1
春ブーツのOAuth2 + JWTとUserDetailsService
これは私のOAuth2ServerConfig
configです:
@Configuration
public class OAuth2ServerConfig {
private static final String RESOURCE_ID = "restservice";
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("123");
return converter;
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Autowired
private TokenStore tokenStore;
@Autowired
private TokenEnhancer tokenEnhancer;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// @formatter:off
endpoints
.tokenStore(tokenStore)
.tokenEnhancer(tokenEnhancer)
.authenticationManager(this.authenticationManager);
// @formatter:on
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// @formatter:off
clients
.inMemory()
.withClient("clientapp")
.authorizedGrantTypes("password","refresh_token")
.authorities("ROLE_CLIENT")
.scopes("read", "write")
.resourceIds(RESOURCE_ID)
.secret("123456");
// @formatter:on
}
}
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Autowired
private ResourceServerTokenServices tokenService;
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
// @formatter:off
resources
.resourceId(RESOURCE_ID)
.tokenServices(tokenService);
// @formatter:on
}
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.antMatchers("/profile/*").authenticated()
.and().csrf()
.disable().sessionManagement().sessionCreationPolicy(STATELESS);
// @formatter:on
}
}
}
この私のUserDetailsService
実装:
@Service
public class DBUserDetailsService implements UserDetailsService {
@Autowired
private UserService userService;
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userService.findUserByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User " + username + " not found.");
}
Set<Permission> permissions = userService.getUserPermissions(user);
return new DBUserDetails(user, permissions);
}
}
今私が正常にJWT accessTokenを発行することができるよしかし、私はそれを使用しようとすると、私の既存のロジックは次のエラーで失敗します。
java.lang.String cannot be cast to com.example.domain.model.security.DBUserDetails
何らかの理由で、DBUserDetailsService.loadUserByUsername
が成功した後に呼び出されていませんJWTトークンに基づく認証で、DBUserDetails
の代わりにSecurityContextHolder.getContext().getAuthentication().getPrincipal()
のようなユーザー名を持つ文字列があります。
私は間違っていますか?
私が見る限り、何も表示されません。プリンシパルが正しく設定されているようです。そして、 'Authentication'オブジェクトに何があると思いますか? –
私はDBUserDetailsオブジェクト(DBUserDetailsService.loadUserByUsernameメソッド呼び出しの後)がJWTトークンなしの純粋なOAuth2構成であった – alexanoid