上文地址:SpringSecurityOAuth2(1)(password,authorization_code,refresh_token,client_credentials)获取token
上一篇博客写了一个至简的OAuth2的token认证服务器,只实现了4种获取token的方式 ,对于异常处理,以及无权处理,生成token前的数据完整性校验等等没有涉及,该篇文章对于这些内容做一些补充:
OAUth2的认证适配器AuthorizationServerConfigurerAdapter有三个主要的方法:
-
AuthorizationServerSecurityConfigurer:
配置令牌端点(Token Endpoint)的安全约束
-
ClientDetailsServiceConfigurer:
配置客户端详细服务, 客户端的详情在这里进行初始化
-
AuthorizationServerEndpointsConfigurer:
配置授权(authorization)以及令牌(token)的访问端点和令牌服务(token services)
1、请求前客户端信息完整校验
对于携带数据不完整的请求,可以直接返回给前端,不需要经过后面的验证 client信息一般以Base64编码放在Authorization 中 例如编码前为
client_name:111 (client_id:client_secret Base64编码)
Basic Y2xpZW50X25hbWU6MTEx
新建一个ClientDetailsAuthenticationFilter继承OncePerRequestFilter
/**
* @Description 客户端不带完整client处理
* @Author wwz
* @Date 2019/07/30
* @Param
* @Return
*/
@Component
public class ClientDetailsAuthenticationFilter extends OncePerRequestFilter {
private ClientDetailsService clientDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// 只有获取token的时候需要携带携带客户端信息,放过其他
if (!request.getRequestURI().equals("/oauth/token")) {
filterChain.doFilter(request, response);
return;
}
String[] clientDetails = this.isHasClientDetails(request);
if (clientDetails == null) {
ResponseVo resultVo = new ResponseVo(HttpStatus.UNAUTHORIZED.value(), "请求中未包含客户端信息");
HttpUtilsResultVO.writerError(resultVo, response);
return;
}
this.handle(request, response, clientDetails, filterChain);
}
private void handle(HttpServletRequest request, HttpServletResponse response, String[] clientDetails, FilterChain filterChain) throws IOException, ServletException {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {
filterChain.doFilter(request, response);
return;
}
MyClientDetails details = (MyClientDetails) this.getClientDetailsService().loadClientByClientId(clientDetails[0]);
UsernamePasswordAuthenticationToken token =
new UsernamePasswordAuthenticationToken(details.getClientId(), details.getClientSecret(), details.getAuthorities());
SecurityContextHolder.getContext()