Reputation: 585
I try to create spring rest service, whis is autenticated by my own oauth2 resources server. I created resource server:
@Configuration
@EnableResourceServer
protected static class ResourceServer extends ResourceServerConfigurerAdapter {
@Autowired
private TokenStore tokenStore;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenStore(tokenStore).resourceId("mobileapp");
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/api/shop /**").authenticated().and()
.authorizeRequests().antMatchers("/auth/**").anonymous();
}
}
and authorization server:
@Configuration
@EnableAuthorizationServer
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager auth;
@Autowired
private DataSource dataSource;
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@Bean
public JdbcTokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
@Bean
protected AuthorizationCodeServices authorizationCodeServices() {
return new JdbcAuthorizationCodeServices(dataSource);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.passwordEncoder(passwordEncoder);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authorizationCodeServices(authorizationCodeServices())
.authenticationManager(auth)
.tokenStore(tokenStore())
.approvalStoreDisabled();
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource)
.passwordEncoder(passwordEncoder);
.withClient("mobile")
.authorizedGrantTypes("password", "refresh_token")
.authorities("ROLE_CLIENT")
.scopes("read", "write", "trust")
.autoApprove(true)
.resourceIds("mobileapp")
.secret("123456");
}
When I try to receive an access token from server, using curl:
curl -X POST -vu mobile:123456 http://localhost:8080/oauth/token -H "Accept: application/json" -d "password=test123&[email protected]&grant_type=password&scope=read&client_secret=123456&client_id=mobile"
I get this error as a response message:
{"error":"server_error","error_description":"java.io.NotSerializableException: org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"}
In tomcat logs there is also
o.s.s.o.p.token.store.JdbcTokenStore - Failed to find access token for token
EDIT: Bean definition of password encoder:
@Bean
public BCryptPasswordEncoder passwordEncoder() {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
return bCryptPasswordEncoder;
}
This bean is created in class, in which OAuth2Config and ResourceServer are declared.
I checked code and found out which table spring uses and the table is empty. My question is: should it be auto generated or there is a problem with my code?
Thanks in advance for help.
Upvotes: 3
Views: 11823
Reputation: 1858
The solution, as far as Postgres is concerned, use BYTEA
for ALL token
and authentication
columns.
The columns are defined as LONGVARBINARY
in this schema reference: https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/test/resources/schema.sql
In other words, replace LONGVARBINARY
with BYTEA
if you are using Postgres.
Cheers
Upvotes: 0
Reputation: 74
Your model must have BCryptPasswordEncoder which is not serialized. Make it transient in your user bmodel.
private transient BCryptPasswordEncoder passwordEncoder;
Upvotes: 1
Reputation: 101
Override JdbcTokenStore class and replace this function with.
public OAuth2AccessToken readAccessToken(String tokenValue) {
OAuth2AccessToken accessToken = null;
try {
accessToken = new DefaultOAuth2AccessToken(tokenValue);
}
catch (EmptyResultDataAccessException e) {
if (LOG.isInfoEnabled()) {
LOG.info("Failed to find access token for token "+tokenValue);
}
}
catch (IllegalArgumentException e) {
LOG.warn("Failed to deserialize access token for " +tokenValue,e);
removeAccessToken(tokenValue);
}
return accessToken;
}
Your problem of failed to find access token is resolved.Use this class in OAuth2Config.
Upvotes: 10