开始
默认情况下申请令牌访问oauth/token
未携带client_secret
参数时会返回Bad client credentials
如果直接通过AuthenticationEntryPoint
是无法自定义返回的信息,我们需要重写过滤器ClientCredentialsTokenEndpointFilter
。
自定义过滤器
public class CustomClientCredentialsTokenEndpointFilter extends ClientCredentialsTokenEndpointFilter {
private AuthorizationServerSecurityConfigurer configurer;
private AuthenticationEntryPoint authenticationEntryPoint;
public CustomClientCredentialsTokenEndpointFilter(AuthorizationServerSecurityConfigurer configurer) {
this.configurer = configurer;
}
@Override
public void setAuthenticationEntryPoint(AuthenticationEntryPoint authenticationEntryPoint) {
// 把父类的干掉
super.setAuthenticationEntryPoint(null);
this.authenticationEntryPoint = authenticationEntryPoint;
}
@Override
protected AuthenticationManager getAuthenticationManager() {
return configurer.and().getSharedObject(AuthenticationManager.class);
}
@Override
public void afterPropertiesSet() {
setAuthenticationFailureHandler(new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
authenticationEntryPoint.commence(httpServletRequest, httpServletResponse, e);
}
});
setAuthenticationSuccessHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
// 无操作-仅允许过滤器链继续到令牌端点
}
});
}
}
自定义AuthenticationEntryPoint
@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
e.printStackTrace();
response.setStatus(200);
Result result = Result.buildFail(e.getMessage());
response.setHeader("Content-Type", "application/json;charset=utf-8");
response.getWriter().print(objectMapper.writeValueAsString(result));
response.getWriter().flush();
}
}
修改授权服务器配置
public class AuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationEntryPoint authenticationEntryPoint;
@Autowired
private CustomUserDetailsService userDetailsService;
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
CustomClientCredentialsTokenEndpointFilter endpointFilter = new CustomClientCredentialsTokenEndpointFilter(security);
endpointFilter.afterPropertiesSet();
endpointFilter.setAuthenticationEntryPoint(authenticationEntryPoint);
security.addTokenEndpointAuthenticationFilter(endpointFilter);
// 注意:security不需要在调用allowFormAuthenticationForClients方法
security.authenticationEntryPoint(authenticationEntryPoint)
.tokenKeyAccess("isAuthenticated()")
.checkTokenAccess("permitAll()");
}
// 此处省略其他代码...
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。