问题
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