2016-09-22 4 views
1

:봄 부팅 OAuth2를 + JWT 나는이 내 <code>OAuth2ServerConfig</code> 설정입니다 봄 OAuth2를 + JWT</p> <p>를 구성하기 위해 노력하고있어 내 봄 부팅 응용 프로그램에서 UserDetailsService의

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

} 
23,944,

는 지금은 성공적으로 JWT accessToken을 발행 할 수있어하지만 난 그것을 사용하려고하면, 기존 로직은 다음 오류와 함께 실패 : DBUserDetailsService.loadUserByUsername이 성공 후 호출되지 않습니다하는 몇 가지 이유를 들어

java.lang.String cannot be cast to com.example.domain.model.security.DBUserDetails 

인증은 JWT 토큰을 기반으로하며 대신 DBUserDetails을 사용합니다. SecurityContextHolder.getContext().getAuthentication().getPrincipal() 예를 들어 "admin"과 같은 사용자 이름의 문자열 만 있습니다.

내가 뭘 잘못하고 있니?

+0

내가 아는 한 아무 것도 없습니다. 교장이 올바르게 설정되어있는 것 같습니다. 그리고'Authentication' 객체에 더 많은 것을 기대합니까? –

+0

DBUserDetails 객체 (DBUserDetailsService.loadUserByUsername 메소드 호출 후)가 JWT 토큰없이 순수한 OAuth2 구성과 같았 으면합니다. – alexanoid

답변

1

스프링 소스 코드를 디버깅 한 후 흐름에 내 UserDetailsService을 삽입하는 방법을 발견했습니다. 이렇게하기 위해서는 accessTokenConverter() 방법을 수정해야합니다 :