拥有 Spring OAuth2 服务器和 3rdparty OAuth 提供商 [英] Own Spring OAuth2 server together with 3rdparty OAuth providers

查看:55
本文介绍了拥有 Spring OAuth2 服务器和 3rdparty OAuth 提供商的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

除此之外,我还想基于 Twitter、Facebook、Google 等 3rd 方 OAuth 提供商向我的 REST 端点添加身份验证.

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

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

此外,该用户在他的 User 实体中没有用户名、密码和电子邮件. 而且我也不知道如何手动创建自己的访问令牌并将其发送给客户端以供将来调用 API.

我找到了一些例子:

@Inject私人 TokenEndpoint 令牌端点;公共字符串 createAccessToken(用户用户){HashMap<字符串,字符串>参数 = new HashMap();parameters.put("client_id", "appid");parameters.put("client_secret", "myOAuthSecret");parameters.put("grant_type", "密码");parameters.put("密码", user.getPassword());parameters.put("作用域", "读写");parameters.put("username", user.getUsername());//主要的 ??return tokenEndpoint.getAccessToken(principal, parameters);}

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

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

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

更新:

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

@Bean公共 ProviderSignInController providerSignInController() {返回新的 ProviderSignInController(socialAuthenticationServiceLocator, usersConnectionRepository, new SignInAdapter() {@覆盖public String signIn(String userId, Connection connection, NativeWebRequest request) {System.out.println("用户ID:" + userId + " 社交显示名称:" + connection.getDisplayName());返回空;}});}

到目前为止,一切正常.

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

我想我需要为此用户创建 OAuth2Authentication 对象并将其放入安全上下文中..我说得对吗?如果是这样,能否请您举例说明如何实现?

解决方案

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

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

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

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

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

一旦认证过程完成,用户将继续/oauth/authorize,同意客户端访问某些范围,令牌将像往常一样交付,而无需您以编程方式生成令牌.

我已经使用 SAML(Spring Security SAML 扩展)做到了这一点,但在您的情况下,您应该深入研究 Spring Social 项目,似乎支持所有主要社交网络.
好消息是你已经有一堆可用的工具,坏消息"是你必须在一定程度上了解它们的工作原理才能将它们连接在一起.

In a Spring Boot application, I have an OAuth2 Authorization/Resource servers. Based on this and Spring Security, I have secured my Spring MVC REST API endpoints.

In addition to this, I'd like to add authentication to my REST endpoints based on 3rd party OAuth providers like Twitter, Facebook, Google.

In my application I have two entities - User and SocialUser. SocialUser represents user profile in social networks. User can have 0-* associated SocialUsers. Right now I can authenticate a user in Twitter and after that I'm creating two records in my database - User and SocialUser. SocialUser contains access/refresh tokens issued by Twitter and some other profile information from this social network.

Right now I don't know how to link this User created from social network with my existing authentication\authorization flow. For this user I'd like to create my own(by my own OAuth2 authorization server) accessToken and provide it to the client.

Also, this user doesn't have username, password and email in his User entity. And also I don't know how to manually create my own access Token and send it to the client for future API calls.

I found some example:

@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);
}

but I don't know how to create Principal based on my User entity and also I'm not sure that this is a correct way to go.

So, the main question is - how to manually generate this new token through my own OAuth server for this new user?

Please advise me how can it be correctly implemented. Thanks.

UPDATED:

I have added ProviderSignInController to my application and able right now to perform full OAuth dance with Twitter. Also, I have implemented my own Neo4jConnectionRepository and Neo4jUsersConnectionRepository because I use Neo4j as a primary database.

@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;
        }
    });
}

So far, everything works good.

The one question is - how to authenticate/authorize User through my own OAuth2 Authorization server in the SignInAdapter.signIn method ?

I think I need to create OAuth2Authentication object for this user and put it into Security context.. Am I right ? If so, could you please show me an example how can this be implemented ?

解决方案

So what you want to achieve is : when clients redirect users to your authorization server (authorization code or implicit grant) in order to obtain a token, the user can log-in using his favorite social network.

If I understand correctly, you have rolled your own implementation of single sign on (SSO) with Twitter (ProviderSignInController), and now you're left wondering how to generate a token when Twitter responds "OK".

I think you took the problem by the wrong end : Instead of building your Twitter client and generating a token programmatically, the idea is to integrate social SSO inside the flow of spring-security-oauth2, which in reality is how to integrate social SSO in Spring Security.

In the end, it's about how your authorization server secures the AuthorizationEndpoint : /oauth/authorize. Since your authorization server works, you already have a configuration class extending WebSecurityConfigurerAdapter that handles the security for /oauth/authorize with formLogin. That's where you need to integrate social stuff.

Instead of using the Spring Security built-in form authentication mechanism, you will have to plug-in your own security that either allows the user to login with a form, or starts SSO with other providers.
Spring Security is made of a bunch of abstractions, but it really just comes down to populating the SecurityContext with an Authentication object for each request.

Once the authentication process is complete, the user will continue to /oauth/authorize, consent to the client accessing some scopes, and the token will be delivered as it's usually done, without you having to generate tokens programmatically.

I have done that using SAML (Spring Security SAML extension), but in your case you should dig in the Spring Social projects, which seem to support all the major social networks out of the box.
The good news is that you already have a bunch of tools available, the "bad news" is that you will have to understand how they work to a certain degree in order to plug them together.

这篇关于拥有 Spring OAuth2 服务器和 3rdparty OAuth 提供商的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆