我有一个使用spring boot的项目,带有oauth2的spring security。当我使用SecurityContextHolder.getContext()。getAuthentication()。getPrincipal()时
在示例中,此方法仅返回用户名结尾,我看到此方法返回了UserDetails命令。
按照设置
OAuthSecurityConfig.java:
package br.com.altha.api.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import br.com.altha.api.security.CustomUserDetailsService; @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled=true) @EnableAuthorizationServer @EnableResourceServer @Order(SecurityProperties.BASIC_AUTH_ORDER-2) @Import(Encoders.class) public class OAuthSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private PasswordEncoder userPasswordEncoder; @Autowired private CustomUserDetailsService userDetailsService; @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(userPasswordEncoder); } }
AuthorizationServerConfig.java:
package br.com.altha.api.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; import br.com.altha.api.security.CustomUserDetailsService; @Configuration public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { private static final String SECRET = "PASSWORD"; @Autowired private AuthenticationManager authenticationManager; @Autowired private PasswordEncoder oauthClientPasswordEncoder; @Autowired private CustomUserDetailsService userDetailsService; @Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) { oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()").passwordEncoder(oauthClientPasswordEncoder); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("altha-adms") .secret(oauthClientPasswordEncoder.encode(SECRET)) .scopes("write", "read") .authorizedGrantTypes("password", "refresh_token") .accessTokenValiditySeconds(60/*1800*/) .refreshTokenValiditySeconds(1800); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints .tokenStore(tokenStore()) .accessTokenConverter(accessTokenConverter()) .authenticationManager(authenticationManager) .reuseRefreshTokens(false) .userDetailsService(userDetailsService); } @Bean public JwtAccessTokenConverter accessTokenConverter() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); converter.setSigningKey(SECRET); return converter; } @Bean public TokenStore tokenStore() { return new JwtTokenStore(accessTokenConverter()); } }
ResourceServerConfig.java:
package br.com.altha.api.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler; import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler; import br.com.altha.api.handler.RestExceptionHandler; @Configuration @Import(Encoders.class) public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Bean public RestExceptionHandler handlerError() { return new RestExceptionHandler(); } @Bean public MethodSecurityExpressionHandler createExpressionHandler() { return new OAuth2MethodSecurityExpressionHandler(); } @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/public/**").permitAll() .antMatchers("/private/**").authenticated() .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler()); } @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.stateless(true); } }
我可以使用以下代码解决此问题:
我向UserAuthenticationConverter添加了一个bean
@Bean public UserAuthenticationConverter userAuthenticationConverter() { DefaultUserAuthenticationConverter defaultUserAuthenticationConverter = new DefaultUserAuthenticationConverter(); defaultUserAuthenticationConverter.setUserDetailsService(userDetailsService); return defaultUserAuthenticationConverter; }
之后,我在JwtAccessTokenConverter中设置了这个bean
@Bean public JwtAccessTokenConverter accessTokenConverter() { final JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter(); jwtAccessTokenConverter.setSigningKey(SECRET); ((DefaultAccessTokenConverter) jwtAccessTokenConverter.getAccessTokenConverter()) .setUserTokenConverter(userAuthenticationConverter()); return jwtAccessTokenConverter; }