spring oauth2 oauthServer 在client_id或client_secret不正确时,返回的信息不是我们需要返回的统一的json格式,spring oauth2返回的信息如下:
{
"error": "invalid_client",
"error_description": "Bad client credentials"
}
因此,我们需要进行自定义返回格式处理。
首先,需要自定义一个CustomClientCredentialsTokenEndpointFilter来继承ClientCredentialsTokenEndpointFilter
public class CustomClientCredentialsTokenEndpointFilter extends ClientCredentialsTokenEndpointFilter {
private final AuthorizationServerSecurityConfigurer configurer;
private AuthenticationEntryPoint authenticationEntryPoint;
public CustomClientCredentialsTokenEndpointFilter(AuthorizationServerSecurityConfigurer configurer) {
this.configurer = configurer;
}
@Override
public void setAuthenticationEntryPoint(AuthenticationEntryPoint authenticationEntryPoint) {
this.authenticationEntryPoint = authenticationEntryPoint;
}
@Override
protected AuthenticationManager getAuthenticationManager() {
return configurer.and().getSharedObject(AuthenticationManager.class);
}
@Override
public void afterPropertiesSet() {
setAuthenticationFailureHandler((request, response, exception) -> authenticationEntryPoint.commence(request, response, exception));
setAuthenticationSuccessHandler((request, response, authentication) -> {
// no-op - just allow filter chain to continue to token endpoint
});
}
}
其次,定义CustomAuthenticationEntryPoint
@Component("customAuthenticationEntryPoint")
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
response.setStatus(HttpStatus.OK.value());
R r = R.error(HttpStatus.UNAUTHORIZED.value(), "client_id或client_secret错误");
response.setHeader("Content-Type", "application/json;charset=utf-8");
response.getWriter().print(JSON.toJSONString(r));
response.getWriter().flush();
}
}
然后,在public void configure(AuthorizationServerSecurityConfigurer oauthServerSecurity) {}里边进行配置
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServerSecurity) {
CustomClientCredentialsTokenEndpointFilter endpointFilter = new CustomClientCredentialsTokenEndpointFilter(oauthServerSecurity);
endpointFilter.afterPropertiesSet();
endpointFilter.setAuthenticationEntryPoint(customAuthenticationEntryPoint);
// 客户端认证之前的过滤器
oauthServerSecurity.addTokenEndpointAuthenticationFilter(endpointFilter);
}
至次,配置完成。
注意:
此处,在configure中,不再需要配置allowFormAuthenticationForClients()。
allowFormAuthenticationForClients的作用是让/oauth/token支持client_id以及client_secret作登录认证,
oauthServerSecurity.allowFormAuthenticationForClients();即设置allowFormAuthenticationForClients = true;作用是在BasicAuthenticationFilter之前添加ClientCredentialsTokenEndpointFilter,使用ClientDetailUserDeailsService来进行client端登录的验证。
同时,使用allowFormAuthenticationForClients()和我们自定义的CustomClientCredentialsTokenEndpointFilter,会导致oauth2仍然使用allowFormAuthenticationForClients中默认的ClientCredentialsTokenEndpointFilter进行过滤,致使我们的自定义CustomClientCredentialsTokenEndpointFilter不生效。
因此,在使用CustomClientCredentialsTokenEndpointFilter时,不再需要开启allowFormAuthenticationForClients()功能。
自定义前:
自定义后: