【问题标题】:Own Spring OAuth2 server together with 3rdparty OAuth providers拥有 Spring OAuth2 服务器以及 3rdparty OAuth 提供者
【发布时间】:2015-06-26 09:02:43
【问题描述】:

在 Spring Boot 应用程序中,我有一个 OAuth2 授权/资源服务器。基于此和 Spring Security,我已经保护了我的 Spring MVC REST API 端点。

除此之外,我还想为我的 REST 端点添加基于 Twitter、Facebook、Google 等第三方 OAuth 提供程序的身份验证。

在我的应用程序中,我有两个实体 - UserSocialUserSocialUser 代表社交网络中的用户资料。 User 可以有 0-* 关联 SocialUsers。现在我可以在 Twitter 中对用户进行身份验证,然后在我的数据库中创建两条记录——用户和社交用户。 SocialUser 包含 Twitter 发布的访问/刷新令牌以及来自该社交网络的一些其他个人资料信息。

现在我不知道如何将这个从社交网络创建的用户与我现有的身份验证\授权流程联系起来。对于这个用户,我想创建自己的(通过我自己的 OAuth2 授权服务器)accessToken 并将其提供给客户端。

另外,该用户的User 实体中没有用户名、密码和电子邮件。 而且我不知道如何手动创建自己的访问令牌并将其发送到用于未来 API 调用的客户端。

我找到了一些例子:

@Inject
private TokenEndpoint tokenEndpoint;

public String createAccessToken(User user) {
    HashMap<String, String> parameters = new HashMap<String, String>();
    parameters.put("client_id", "appid");
    parameters.put("client_secret", "myOAuthSecret");
    parameters.put("grant_type", "password");
    parameters.put("password", user.getPassword());
    parameters.put("scope", "read write");
    parameters.put("username", user.getUsername());

    // principal ??
    return tokenEndpoint.getAccessToken(principal, parameters);
}

但我不知道如何根据我的 User 实体创建 Principal,而且我不确定这是正确的方法。

所以,主要问题是 - 如何通过我自己的 OAuth 服务器为这个新用户手动生成这个新令牌?

请告诉我如何正确实施。谢谢。

更新:

我已将ProviderSignInController 添加到我的应用程序中,并且现在能够使用 Twitter 执行完整的 OAuth 舞蹈。另外,我实现了自己的Neo4jConnectionRepositoryNeo4jUsersConnectionRepository,因为我使用 Neo4j 作为主数据库。

@Bean
public ProviderSignInController providerSignInController() {
    return new ProviderSignInController(socialAuthenticationServiceLocator, usersConnectionRepository, new SignInAdapter() {

        @Override
        public String signIn(String userId, Connection<?> connection, NativeWebRequest request) {
            System.out.println("User ID: " + userId + " social display name: " + connection.getDisplayName());
            return null;
        }
    });
}

到目前为止,一切正常。

一个问题是 - 如何在SignInAdapter.signIn 方法中通过我自己的OAuth2 授权服务器对User 进行身份验证/授权?

我想我需要为此用户创建OAuth2Authentication 对象并将其放入安全上下文中。我说的对吗?如果是这样,你能告诉我一个如何实现的例子吗?

【问题讨论】:

  • 如果我理解正确:您有一个提供您自己的令牌的授权服务器,一些资源服务器受这些令牌的保护。您的授权服务器根据自己的用户数据库对您的用户进行身份验证,并且您想添加单点登录 (SSO) 以通过第三方对您的用户进行身份验证?
  • 是的,你是对的。第三方是例如 Google、Facebook、Yahoo OAuth 提供商
  • 我也有同样的要求。你得到这个工作了吗?你能提供更多细节吗?我想知道你在SignInAdapter 中究竟做了什么?
  • 我从自己的 OAuth2 服务器转移到了 JWT

标签: spring-mvc spring-security oauth-2.0 spring-social spring-security-oauth2


【解决方案1】:

所以你想要实现的是:当客户端将用户重定向到你的授权服务器(授权码或隐式授权)以获得令牌时,用户可以使用他最喜欢的社交网络登录。

如果我理解正确,您已经使用 Twitter (ProviderSignInController) 推出了自己的单点登录 (SSO) 实现,现在您想知道如何在 Twitter 响应“OK”时生成令牌。

我认为你把问题搞错了:不是构建你的 Twitter 客户端并以编程方式生成令牌,而是将社交 SSO 集成到 spring-security-oauth2 的流程中,这实际上是如何集成Spring Security 中的社交 SSO。

最后,它是关于您的授权服务器如何保护 AuthorizationEndpoint:/oauth/authorize。 由于您的授权服务器工作正常,您已经有一个扩展 WebSecurityConfigurerAdapter 的配置类,它处理 /oauth/authorizeformLogin 的安全性。 这就是您需要整合社交内容的地方。

您必须插入自己的安全机制,而不是使用 Spring Security 内置的表单身份验证机制,以允许用户使用表单登录,或者使用其他提供商启动 SSO。
Spring Security 由一堆抽象组成,但实际上归结为为每个请求使用 Authentication 对象填充 SecurityContext

身份验证过程完成后,用户将继续/oauth/authorize,同意客户端访问某些范围,并且令牌将按照通常的方式交付,而无需您以编程方式生成令牌。

我已经使用 SAML(Spring Security SAML 扩展)完成了这项工作,但在您的情况下,您应该挖掘 Spring Social projects,它似乎支持所有开箱即用的主要社交网络。
好消息是您已经拥有大量可用的工具,“坏消息”是您必须在一定程度上了解它们的工作原理才能将它们组合在一起。

【讨论】:

  • 嗨,在 github 或其他任何地方是否有任何示例项目?
【解决方案2】:

这个tutorial 展示了如何实现这一点(如果我正确理解了这个问题):拥有一个基于外部 oauth2 身份验证的身份验证服务器发布您自己的 oauth2 令牌。 对应代码在here.

它的要点是除了@EnableAuthorizationServer 之外,您还使用@EnableOAuth2Client 并在spring security 默认值之前插入一个OAuth2ClientAuthenticationProcessingFilter 过滤器。

【讨论】:

    猜你喜欢
    • 2015-06-15
    • 2012-02-06
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    • 2011-02-24
    • 2011-04-11
    • 2017-08-12
    • 2013-12-22
    相关资源
    最近更新 更多