在我的系统中,我使用JWT令牌,以便可以仅基于JWT执行请求授权,无需调用数据库来获取角色等。我使用OAuth,我的服务是资源服务器,工作正常,我'我很满意。我遇到的问题是我的uaa-service,它既是授权服务器又是资源服务器。
我注意到当我向uaa-service发送请求时,我可以将@AuthenticatedPrincipal注入到我的控制器方法中,并且我可以访问所有用户字段,而不仅仅是那些存在于JWT中的字段。这意味着Spring以某种方式维护会话或者可能在后台从数据库中获取用户数据。以下是我的设置:
@Configuration
@EnableResourceServer
@Slf4j
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
log.info("Configuring resource server");
http
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers("/register").permitAll().anyRequest().authenticated();
}
@Autowired
public void setJwtAccessTokenConverter(JwtAccessTokenConverter jwtAccessTokenConverter) {
jwtAccessTokenConverter.setAccessTokenConverter(bitcoinTokenConverter());
}
@Bean
DefaultAccessTokenConverter bitcoinTokenConverter() {
return new CustomTokenConverter();
}
并且
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
KeyPair keyPair = new KeyStoreKeyFactory(new ClassPathResource(keystoreName), keystorePassword.toCharArray())
.getKeyPair(keystoreAlias);
converter.setKeyPair(keyPair);
return converter;
}
@Bean
public TokenEnhancer tokenEnhancer() {
return new CustomTokenEnhancer();
}
@Bean
public DefaultAccessTokenConverter accessTokenConverter() {
return new DefaultAccessTokenConverter();
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), jwtAccessTokenConverter()));
endpoints
.authenticationManager(authenticationManager)
.userDetailsService(customUserDetailsService)
.tokenEnhancer(tokenEnhancerChain);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}
和
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
@Bean
FilterRegistrationBean forwardedHeaderFilter() {
FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
filterRegBean.setFilter(new ForwardedHeaderFilter());
filterRegBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return filterRegBean;
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests().antMatchers("/register").permitAll().anyRequest().authenticated();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService).passwordEncoder(new BCryptPasswordEncoder());
auth.authenticationEventPublisher(new DefaultAuthenticationEventPublisher(applicationEventPublisher));
}
我在哪里弄错了?在我的SecurityConfig.java中我有
auth.userDetailsService(customUserDetailsService).passwordEncoder(new BCryptPasswordEncoder());
这样可以通过从数据库中获取用户并验证密码来执行登录,但看起来它也可能导致传入请求不仅仅基于JWT处理。