带有访问/刷新 token 的 Spring Boot OAuth2 SSO 未正确存储在数据库中

标签 spring spring-security spring-boot spring-security-oauth2 spring-social

基于此示例 https://spring.io/guides/tutorials/spring-boot-oauth2/我已经通过社交网络实现了 SSO 应用程序。为了改进这种方法并将访问/刷新 token 存储在我的数据库中,我添加了 oauth_client_token 表:

    CREATE TABLE IF NOT EXISTS oauth_client_token (
      token_id VARCHAR(255),
      token BLOB,
      authentication_id VARCHAR(255),
      user_name VARCHAR(255),
      client_id VARCHAR(255),
      PRIMARY KEY(authentication_id)
    );

和扩展ClientResources类,以便从AuthorizationCodeResourceDetails.isClientOnly()方法返回true:

class ClientResources {

        private OAuth2ProtectedResourceDetails client = new AuthorizationCodeResourceDetails() {

            @Override
            public boolean isClientOnly() {
                return true;
            }

        };
        private ResourceServerProperties resource = new ResourceServerProperties();

        public OAuth2ProtectedResourceDetails getClient() {
            return client;
        }

        public ResourceServerProperties getResource() {
            return resource;
        }

    }

这是我的 SSO 过滤器:

    private Filter ssoFilter(ClientResources client, String path) {
        OAuth2ClientAuthenticationProcessingFilter clientFilter = new OAuth2ClientAuthenticationProcessingFilter(path);
        OAuth2RestTemplate oAuth2RestTemplate = new OAuth2RestTemplate(client.getClient(), oauth2ClientContext);

        AccessTokenProviderChain tokenProviderChain = new AccessTokenProviderChain(new ArrayList<>(Arrays.asList(new AuthorizationCodeAccessTokenProvider())));
        tokenProviderChain.setClientTokenServices(new JdbcClientTokenServices(dataSource));
        oAuth2RestTemplate.setAccessTokenProvider(tokenProviderChain);

        clientFilter.setRestTemplate(oAuth2RestTemplate);
        clientFilter.setTokenServices(new OkUserInfoTokenServices(okService, client.getClient().getClientId(), apiUrl, eventService));
        clientFilter.setAuthenticationSuccessHandler(new UrlParameterAuthenticationHandler());
        return clientFilter;
    }

现在我不确定我是否以正确的方式实现了这个逻辑,而不是肮脏的黑客。

如果我以正确的方式实现了这个东西,请告诉我。

已更新

我现在确信这不是正确的实现,因为对于我的表中的 2 个不同用户 oauth_client_token 我只有一条记录。Auth 对象为 null,authentication_id 仅基于 OAuth2 计算client_id..这是错误的。当身份验证不为空时,我需要保留 token ..但我不知道如何使用 OAuth2ClientAuthenticationProcessingFilter

的当前实现来做到这一点

现在,在 spring-security-oauth2 2.0.8.RELEASE 的当前版本中,我们在 OAuth2ClientAuthenticationProcessingFilter.successfulAuthentication 方法中只有一个奇怪的注释:

@Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
            FilterChain chain, Authentication authResult) throws IOException, ServletException {
        super.successfulAuthentication(request, response, chain, authResult);
        // Nearly a no-op, but if there is a ClientTokenServices then the token will now be stored
        restTemplate.getAccessToken();
    }

如何正确实现?

最佳答案

关于带有访问/刷新 token 的 Spring Boot OAuth2 SSO 未正确存储在数据库中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34908203/

相关文章:

spring - 如何在 .antmatchers.access() 中使用常量

spring - Spring Security,自定义登录表单: display custom message matching SPRING_SECURITY_LAST_EXCEPTION

tomcat - 如何防止 spring-security 将 ;jsessionid=XXX 附加到登录重定向?

java - Spring Boot Logback 记录 DEBUG 消息

java - 在 Spring Boot 中处理嵌入式 Tomcat 异常

java - 如何使用 MYSQL 通过 spring security 在安全休息端点下插入数据

java - Spring MVC default-servlet-handler 配置阻塞 JSTL View

spring - Kotlin - SpringApplicationBuilder 中的扩展运算符

java - 如何以编程方式从 spring security 中的 <HTTP> 元素访问 <INTERCEPT-URL>

java - Spring Security 定义自定义匿名过滤器