【问题标题】:How to tie OAuth authentication with Spring Security如何将 OAuth 身份验证与 Spring Security 联系起来
【发布时间】:2017-08-02 18:46:22
【问题描述】:

我有一个 Grails 2.5.3 应用程序,目前使用 spring 安全插件进行身份验证。用户使用用户名/密码登录。

我现在更新了应用程序以支持 OAuth 身份验证(使用 ScribeJava)。用户可以单击将他们重定向到 OAuth 提供者页面的链接,并在成功输入凭据后将他们重定向回我的应用程序。但是,我无法将此功能与 spring 安全插件绑定,因此当用户被重定向回我的应用程序时(从 OAuth 成功登录后),我实际上可以看到他们已登录并继续使用我所有的 spring像<sec:ifLoggedIn> 这样的安全好东西。

有谁知道这样做的方法或有一个我可以看看的例子吗?

这是我使用 OAuth 对用户进行身份验证的方式:

//called when user clicks "login using oauth"
def authenticate() {
    OAuthService service = new ServiceBuilder()
                              .apiKey(grailsApplication.config.my.sso.clientid)
                              .apiSecret(grailsApplication.config.my.sso.clientsecret)
                              .build(MyApi.instance());
    String url =  service.getAuthorizationUrl();
    return redirect(url: url)
}

//called when oauth provider redirects to my application
def authorization_code() {
    def code = params.code
    OAuthService service = new ServiceBuilder()
                              .apiKey(grailsApplication.config.my.sso.clientid)
                              .apiSecret(grailsApplication.config.my.sso.clientsecret)
                              .build(MyApi.instance());
    println code                          
    OAuth2AccessToken accessToken = service.getAccessToken(code);
    String userProfileUrl = grailsApplication.config.my.sso.authdomain+"/userinfo"
    final OAuthRequest request = new OAuthRequest(Verb.GET, userProfileUrl);
    service.signRequest(accessToken, request);
    final Response response = service.execute(request);
    println(response.getCode());
    println(response.getBody());        
    render (text: code)
}

【问题讨论】:

  • 以下答案对您有帮助吗?

标签: grails spring-security oauth grails-plugin spring-security-oauth2


【解决方案1】:

每当您通过OAuth 进行身份验证时,远程服务器每次都会返回一个unique id (some numeric value)。 您可以使用该id 来验证您的最终用户,并使用springsecurity.reauthenticate() 方法对用户进行身份验证。

步骤:

  1. 当用户与服务提供商连接(首次验证)时。 服务提供商向您发送unique id。将 unique id 保存在 用户表。
  2. 当用户通过该服务提供商登录时。再次服务提供商 发送unique id。检查您的系统中是否存在unique id, 如果用户存在该唯一ID,则使用 springsecurity.reauthenticate(userInstance) 方法来验证用户。现在您可以使用弹簧安全功能。

查看链接:http://www.jellyfishtechnologies.com/grails-2-2-0-integration-with-facebook-using-grails-oauth-plugin/

【讨论】:

    【解决方案2】:

    假设您从 Oauth 提供商那里获得了用户详细信息,您只需要 设置特定用户的安全上下文

    通过解析JSON之类的方式获取用户详细信息

    def oauthResponse = JSON.parse(response?.getBody())
    Map data = [
                        id          : oauthResponse.id,
                        email       : oauthResponse.email,
                        name        : oauthResponse.name,
                        first_name  : oauthResponse.given_name,
                        last_name   : oauthResponse.family_name,
                        gender      : oauthResponse.gender,
                        link        : oauthResponse.link
                ]
    

    在我们的例子中,我们使用电子邮件 ID 作为用户名。

    因此,当我们获取用户数据时,只需检查用户是否已在系统中注册或如下所示

    //load the user details service bean
    def userDetailsService
    
    //check if user is already registered on our system
    User user = User.findByEmail(data?.email)
    if (user) {
    
        //If user exists load his context
        userDetails = userDetailsService.loadUserByUsername(data?.email)
    } else {
    
        //create the new user
        //Assign the role to it
    
        //load his context as below
       userDetails = userDetailsService.loadUserByUsername(data?.email)
    }
    

    用户注册成功后,我们只需要像下面这样加载他的上下文

    def password
    
    //setting spring security context
    SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(userDetails, password == null ? userDetails.getPassword() : password, userDetails.getAuthorities()))
    

    一旦加载了 spring 安全上下文,您就可以将用户重定向到您的登录页面。

    现在 oauth 用户将像任何其他具有相同角色的用户一样访问资源。

    【讨论】:

      猜你喜欢
      • 2020-05-11
      • 1970-01-01
      • 2016-10-18
      • 2012-04-06
      • 2019-08-03
      • 2015-07-22
      • 2019-10-11
      • 2016-05-31
      • 2022-01-15
      相关资源
      最近更新 更多