Java 在Spring Boot中处理OAuth2回调

Java 在Spring Boot中处理OAuth2回调,java,spring,spring-boot,oauth-2.0,Java,Spring,Spring Boot,Oauth 2.0,我正在尝试构建一个Spring引导项目,该项目需要登录到OAuth2 SSO中。 我有以下Maven依赖项: org.springframework.boot:spring-boot-starter-web org.springframework.security:spring-security-oauth2-client org.springframework.security:spring-security-config 我使用HttpSecurity强制应用程序的OAuth2身份验证,使

我正在尝试构建一个Spring引导项目,该项目需要登录到OAuth2 SSO中。 我有以下Maven依赖项:

org.springframework.boot:spring-boot-starter-web
org.springframework.security:spring-security-oauth2-client
org.springframework.security:spring-security-config
我使用
HttpSecurity
强制应用程序的OAuth2身份验证,使用以下方法:

@EnableWebSecurity
@Order(101)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatcher("/api/auth/oauth2/callback").permitAll()
            .anyRequest().authenticated()
            .and()
            .oauth2Login();
    }

}
现在,它所做的是:它看到用户没有登录,将他们重定向到SSO,在他们登录后,它将用户重定向回
/api/auth/oauth2/callback?code=…&state=…
端点。一切正常。然而,我对Spring Boot还相当陌生,我不明白如何坚持用户现在已经通过身份验证的事实(我知道我仍然需要验证回调,这不是问题)

下面是我想要实现的身份验证模型:我想在回调端点内生成一个哈希,并将该哈希存储在应用程序的内存中,并作为cookie存储在用户浏览器上。然后,在任何后续请求中,应用程序将读取该cookie的值,在内存数据库中找到包含哈希的行,并从数据库行中获取相应的用户数据

我已经广泛地寻找了一个很好的例子,但是,所有基于Spring Boot的OAuth2例子都使用Github/Google OAuth,并且它似乎可以处理很多隐藏的东西(或者可能我没有正确地理解它们)

任何帮助/指导都将不胜感激

如果有帮助,下面是我的
应用程序.yml
文件:

spring:
  security:
    oauth2:
      client:
        registration:
          custom_sso_name:
            clientId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
            clientSecret: SUPER_SECRET
            authorizationGrantType: authorization_code
            redirectUri: https://dev.localhost/api/auth/oauth2/callback
        provider:
          custom_sso_name:
            userInfoUri: https://sso.example.com/nidp/oauth/nam/userinfo
            authorizationUri: https://sso.example.com/nidp/oauth/nam/authz
            tokenUri: https://sso.example.com/nidp/oauth/nam/token
            preferTokenInfo: false
你可以查一下电话号码

设置此选项后,可以自动关联自定义项 AuthenticationProvider并在控制器中登录用户,如下所示:

    SecurityContextHolder.getContext().setAuthentication(authManager.authenticate(new UserInfo(yourHash, token, expirationDate)));
在这里,UserInfo是一个示例类(它扩展了
AbstractAuthenticationToken
),可以保存您想要保存的哈希,以及您可能需要的任何其他数据

在上面链接的示例中,他们使用了
UsernamePasswordAuthenticationToken
,如果您只想存储散列,这可能就足够了。如果您想存储额外信息,我建议您使用自定义的
AuthenticationToken
,因为它是UserInfo:

public class UserInfo extends AbstractAuthenticationToken {


    private String hash;
    private String oAuthToken;
    private DateTime expirationTime;

    public UserInfo (String hash, String oAuthToken, DateTime expirationTime){
        super(Collections.emptyList());
        this.hash= hash;
        this.oAuthToken = oAuthToken;
        this.expirationTime = expirationTime;
    }

    @Override
    public String getCredentials() {
       if(expirationTime.isAfter(DateTime.now())){
           return oAuthToken;
       } else {
           return null;
       }
    }

    @Override
    public String getPrincipal() {
        return hash;  //Or anything you stored that may be useful for checking the authentication
    }
然后,在任何后续请求中,应用程序将读取该cookie的 值,在内存数据库中查找包含哈希的行,然后 从数据库行获取相应的用户数据

此身份验证完成后,您可以在任何请求中自定义检查身份验证:

@GetMapping("/")
public String profileSettings(Principal principal) {

    if (principal instanceof UserInfo){
        String hash = ((UserInfo) principal).getPrincipal();
       //Now you can use the hash for your custom logic, such like database reading
       return "profileSettings";
    } else {
       return "login";
    }
}

嗨,你找到什么了吗?我也遇到了同样的问题…@CarlosLópezMarí我确实通过使用SpringSecurityContext找到了解决方案,我会在有时间的时候在这里发布我的解决方案,请看这个帮助我将用户设置为已登录的页面:天哪,我正在查看任何关于如何手动登录用户的文章,但没有找到任何内容。也许“手册”这个词毕竟是关键。。。非常感谢。这并没有给我访问令牌或任何东西,所以我想我要使用REST客户端和Cookie…在我的情况下,我编写了接收oauth2回调并自己获得访问令牌的端点——我唯一想要的是在完成后能够登录用户。