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

时间:2016-01-20 18:56:22

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

基于此示例https://spring.io/guides/tutorials/spring-boot-oauth2/我已经通过社交网络实施了SSO应用程序。为了改进这种方法并在我的数据库中存储访问/刷新令牌,我添加了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类,以便从true方法返回AuthorizationCodeResourceDetails.isClientOnly()

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

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

如果我以正确的方式实施了这件事,请告诉我。

已更新

我现在确定它是不正确的实现,因为我的表oauth_client_token中有2个不同的用户我只有一个记录.. Auth对象为null,authentication_id仅基于OAuth2 client_id计算..这是错的。当身份验证不为null时,我需要持久化令牌..但我不知道如何使用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();
    }

如何正确实施?