I have configured an OAuth2 authorisation server with spring security oauth, using jwt tokens:
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
...
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
}
@Bean
public ApprovalStore approvalStore() {
return new JdbcApprovalStore(dataSource);
}
@Bean
public TokenStore tokenStore() {
var jwtTokenStore = new JwtTokenStore(tokenConverter());
jwtTokenStore.setApprovalStore(approvalStore());
return jwtTokenStore;
}
@Bean
public JwtAccessTokenConverter tokenConverter() {
var converter = new JwtAccessTokenConverter();
var keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource(jwtKeyStore), jwtKeyPass.toCharArray());
converter.setKeyPair(keyStoreKeyFactory.getKeyPair("jwtkey"));
return converter;
}
}
There is a client that has password
and refresh_token
grants. I can get access and refresh tokens with the following request:
curl --request POST \
--url 'http://localhost:8080/oauth/token?grant_type=password&scope=read' \
--header 'authorization: Basic <xxxxxxx>' \
--header 'content-type: application/x-www-form-urlencoded' \
--data 'username=xxxxxxx&password=xxxxxxx'
Response:
{
"access_token": "<long access token>",
"token_type": "bearer",
"refresh_token": "<long refresh token>",
"expires_in": 599,
"scope": "read",
"subject": "xxx",
"jti": "xxx"
}
However, when I try to refresh the token, I get an error Invalid refresh token
. Further debugging into Spring codes I see that on the first request, it doesn't insert a row into oauth_approvals
table. And on the second request (refreshing the token) it thinks that the user has not approved the scope (although I have autoapprove=true
).
This is not the case with implicit
or authorization_code
grant flow: in those cases it does insert a row into oauth_approvals
table, and the token is refreshed successfully.
Is this a bug in Spring OAuth or is there any workaround?
After digging more into Spring's codes, I came to conclusion that this is indeed a bug there. So I extended JdbcApprovalStore
and used that one instead. Here is pseudo-code
public class JdbcApprovalStoreAutoApprove extends JdbcApprovalStore {
...
@Override
public List<Approval> getApprovals(String userName, String clientId) {
if (client has auto approved scopes) {
return those scopes;
}
return super.getApprovals(userName, clientId);
}