首页 文章

自己的Spring OAuth2服务器以及第三方OAuth提供商

提问于
浏览
18

在Spring Boot应用程序中,我有OAuth2 Authorization \ Resource服务器 . 基于此和Spring Security,我已经获得了我的Spring MVC REST API endpoints .

除此之外,我还想基于第三方OAuth提供商(如Twitter,Facebook,Google)为我的REST endpoints 添加身份验证 .

在我的应用程序中,我有两个实体 - UserSocialUser . SocialUser 表示社交网络中的用户 Profiles . User 可以有0- *关联 SocialUsers . 现在我可以在Twitter上验证用户,之后我在我的数据库中创建了两条记录 - User和SocialUser . SocialUser包含Twitter发布的访问/刷新令牌以及来自此社交网络的一些其他配置文件信息 .

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

Also, this user doesn't have username, password and email in his User entity. 而且我也不知道如何手动创建自己的访问令牌并将其发送到客户端以供将来的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服务器为这个新用户手动生成这个新令牌?

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

UPDATED:

我已将 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 对象并将其放入安全上下文中 . 我是对的吗?如果是这样,你能否告诉我一个如何实施的例子?

2 回答

  • 0

    因此,您要实现的目标是:当客户端将用户重定向到您的授权服务器(授权代码或隐式授权)以获取令牌时,用户可以使用他最喜欢的社交网络登录 .

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

    我认为你错误地解决了问题:不是构建你的Twitter客户端并以编程方式生成令牌,而是将社交SSO集成到spring-security-oauth2的流程中,实际上是如何将社交SSO集成到 Spring 季安全 .

    最后,它是关于授权服务器如何保护AuthorizationEndpoint: /oauth/authorize . 由于您的授权服务器可以工作,因此您已经有一个扩展 WebSecurityConfigurerAdapter 的配置类,它使用 formLogin 来处理 /oauth/authorize 的安全性 . That's where you need to integrate social stuff.

    您不必使用Spring Security内置表单身份验证机制,而是必须插入自己的安全性,允许用户使用表单登录,或者与其他提供程序一起启动SSO .
    Spring Security由一堆抽象组成,但它实际上只是为每个请求填充 SecurityContextAuthentication 对象 .

    一旦身份验证过程完成,用户将继续 /oauth/authorize ,同意客户端访问某些范围,并且令牌将按照通常的方式进行传递,而无需以编程方式生成令牌 .

    我已经使用SAML(Spring Security SAML扩展)完成了这项工作,但在您的情况下,您应该深入了解Spring Social projects,它似乎支持开箱即用的所有主要社交网络 .
    好消息是你已经拥有了大量的工具,"bad news"是你必须了解它们如何工作到一定程度才能将它们连接在一起 .

  • 8

    tutorial显示了如何实现这一点(如果我理解正确的问题):让auth服务器根据外部oauth2身份验证发出自己的oauth2令牌 . 相应的代码可用here .

    它的要点是除了 @EnableAuthorizationServer 之外还使用 @EnableOAuth2Client 并在spring security default之前插入 OAuth2ClientAuthenticationProcessingFilter 过滤器 .

相关问题