首页 文章

如何将OAuth身份验证与Spring Security联系起来

提问于
浏览
8

我有一个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)
}

2 回答

  • 0

    假设您从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用户将像具有相同角色的任何其他用户一样访问资源 .

  • 1

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

    这样做的步骤:

    • 当用户与服务提供商连接(首次验证)时 . 服务提供商发送给您 unique id . 将 unique id 保存在用户表中 .

    • 当用户通过该服务提供商登录时 . 服务提供商再次发送 unique id . 检查系统中是否存在 unique id ,如果用户存在该唯一ID,则使用 springsecurity.reauthenticate(userInstance) 方法对用户进行身份验证 . 现在您可以使用Spring安全功能 .

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

相关问题