Spring Boot OAuth2 SSO with access/refresh tokens is not stored in a database correctly

天大地大妈咪最大 提交于 2020-01-04 06:46:26

问题


Based on this example https://spring.io/guides/tutorials/spring-boot-oauth2/ I have implemented application with SSO throught Social Networks. In order to improve this approach and store access/refresh tokens in my database I have added oauth_client_token table:

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

and extended ClientResources class in order to return true from AuthorizationCodeResourceDetails.isClientOnly() method:

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

    }

This is my SSO filter:

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

Right now I'm not sure I have implemented this logic in the right way and not the dirty hack.

Please advise me if I have implemented this thing in a correct way.

UPDATED

I'm sure right now it is not correct implementation because of for 2 different users in my table oauth_client_token I have only one record.. Auth object is null and authentication_id is calculated only based on OAuth2 client_id.. this is wrong. I need to persist token when authentication is not null.. but I don't know how to do it with a current implementation of OAuth2ClientAuthenticationProcessingFilter

Right now in the current version of spring-security-oauth2 2.0.8.RELEASE we have only one strange comment inside of OAuth2ClientAuthenticationProcessingFilter.successfulAuthentication method:

@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();
    }

How to implement it correctly ?


回答1:


Found the same issue at GitHub:

https://github.com/spring-projects/spring-security-oauth/issues/498 https://github.com/spring-projects/spring-security-oauth/pull/499



来源:https://stackoverflow.com/questions/34908203/spring-boot-oauth2-sso-with-access-refresh-tokens-is-not-stored-in-a-database-co

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!