我正在使用auth2 sso和spring boot。尝试获取访问令牌时,会显示一条错误消息。请说明为什么发生这种错误以及如何解决此问题:使用sso自动重定向到授权调用并获取此错误,然后添加安全配置,它可以正常工作并获取访问令牌。为此,我使用了自定义身份验证提供程序。
2018-12-13 11:02:49.583 DEBUG 19440 --- [nio-8081-exec-7] p.a.OAuth2AuthenticationProcessingFilter : Authentication request failed: error="invalid_token", error_description="Invalid access token: undefined"
2018-12-13 11:02:49.587 DEBUG 19440 --- [nio-8081-exec-7] s.s.o.p.e.DefaultOAuth2ExceptionRenderer : Written [error="invalid_token", error_description="Invalid access token: undefined"] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@65ffb33b]
我的代码如下。
授权服务器:
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager)
.tokenEnhancer(CustomTokenEnhancer())
.tokenStore(tokenStore());
}
@Bean
public TokenEnhancer CustomTokenEnhancer() {
return new TokenEnhancer() {
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication authentication) {
DefaultOAuth2AccessToken newToken = new DefaultOAuth2AccessToken(oAuth2AccessToken);
final Map<String, Object> additionalInfo = new HashMap<>();
final String sessionId=(String) authentication.getUserAuthentication().getDetails();
additionalInfo.put("id", authentication.getPrincipal());
additionalInfo.put("authorities", authentication.getAuthorities());
additionalInfo.put("sessionId", sessionId);
SecurityContextHolder.getContext().setAuthentication(authentication);
newToken.setAdditionalInformation(additionalInfo);
return newToken;
}
};
}
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Value("${accessTokenValidity}")
private Integer accessTokenValidity;
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
System.out.println("accessTokenValidity: "+accessTokenValidity);
clients
.inMemory()
.withClient("client")
.secret("secret")
.authorizedGrantTypes("authorization_code","password")
.scopes("user_info")
.autoApprove(true)
.accessTokenValiditySeconds(accessTokenValidity)
.resourceIds("oauth2-server");
;
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager)
.tokenEnhancer(CustomTokenEnhancer())
.tokenStore(tokenStore());
}
@Bean
public TokenEnhancer CustomTokenEnhancer() {
return new TokenEnhancer() {
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication authentication) {
DefaultOAuth2AccessToken newToken = new DefaultOAuth2AccessToken(oAuth2AccessToken);
final Map<String, Object> additionalInfo = new HashMap<>();
final String sessionId=(String) authentication.getUserAuthentication().getDetails();
additionalInfo.put("id", authentication.getPrincipal());
additionalInfo.put("authorities", authentication.getAuthorities());
additionalInfo.put("sessionId", sessionId);
SecurityContextHolder.getContext().setAuthentication(authentication);
newToken.setAdditionalInformation(additionalInfo);
return newToken;
}
};
}
@Bean
public InMemoryTokenStore tokenStore() throws Exception {
return new InMemoryTokenStore();
}
}
资源服务器:
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers( "**/oauth/**").permitAll()
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/oauth/rest/mcash/logout"))
.permitAll().invalidateHttpSession(true).logoutSuccessUrl("/")
.and()
.exceptionHandling().accessDeniedHandler(accessDeniedHandler);
(accessDeniedHandler);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(daoAuthenticationProvider());
}
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(daoAuthenticationProvider());
}
@Bean
public AuthenticationProvider daoAuthenticationProvider() {
return new CustomAuthonticationProvider();
}
API服务的安全性配置:
@EnableOAuth2Sso
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("**/authentication/**")
.permitAll()
.anyRequest().authenticated();
}
自定义身份验证提供者:
public class CustomAuthonticationProvider implements AuthenticationProvider {
/* (non-Javadoc)
* @see org.springframework.security.authentication.AuthenticationProvider#authenticate(org.springframework.security.core.Authentication)
*/
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
//custom validations
UsernamePasswordAuthenticationToken authenticationToken=new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), password, translate(user.getRoles()));
if(null!=details) {
authenticationToken.setDetails(details);
}
SecurityContextHolder.getContext().setAuthentication(authentication);
return authenticationToken;
}
}