这个只是自己写的授权码的一个记录,不是那种直接粘贴复制就可以用的代码,主要记录自己在写授权码认证时候的一些遇到的坑,希望可以帮助到别人
一. 第一步:一个统一认证的页面
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors()
.and()
.formLogin()
.loginPage("/login")//自定义登录界面的路径
.loginProcessingUrl("/login") //登录成功的请求
.usernameParameter("username")//
.passwordParameter("password");
}
loginPage()方法可以指定一个我们自定义的路径去覆盖默认的登录界面。
这种定义可以有2种:
- 在boot服务里面放入一个页面当登录主页
- 引入一个外部的可以访问的页面当首页
这里外部访问会出现跨域问题,需要后台在跨域配置 或者在nignx转发
二. 第二步:一个统一认证的逻辑
当配置后台配置完成之后,我们需要实现自定义的认证
AuthenticationManager 认证管理器主要用来管理AuthenticationProvider
AuthenticationProvider 认证具体实现类可以实现多个,当多个AuthenticationProvider共同认证的时候 只要有一个认证成功就被认为登录成功
@Slf4j
@Component
public class UserAuthenticationTokenFilter implements AuthenticationProvider {
@Autowired
private UserDetailsService userDetailsService;
@Override
public Authentication authenticate(Authentication authentication) {
// 认证逻辑
//这个就自行百度 网上很多
}
这里说一个多认证的异常选择
坑点一:
当我们需要定义自定义异常的时候,如果是直接跳出多认证的流程,直接返回异常需要继承AccountStatusException和InternalAuthenticationServiceException就可以了,这边源码也有明确显示,当我们需要让认证继续走流程的时候,则需要继承的异常则必须是AuthenticationException的子类,但是得避开上面2种异常。符合的类好像就2种也没仔细找BadCredentialsException和UsernameNotFoundException
三:统一认证扩展
自定义过滤器,我实现自定义过滤器的作用是因为 我们项目需要把认证的参数放入请求头中在去认证。
public class HttpAuthenticationEntryPoint extends AbstractAuthenticationProcessingFilter {
// AuthenticationManager 参数必须重写用于执行下面的认证流程
@Override
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
super.setAuthenticationManager(authenticationManager);
}
// 认证成功回调方法
@Override
public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler authenticationSuccessHandler){
super.setAuthenticationSuccessHandler(authenticationSuccessHandler);
}
// 认证失败的回调
@Override
public void setAuthenticationFailureHandler(AuthenticationFailureHandler failureHandler) {
super.setAuthenticationFailureHandler(failureHandler);
}
// 重写 attemptAuthentication
@Override
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
throws AuthenticationException{
// http 处理业务过滤...
// 这里最重要的2个方法
//1. CustomAuthenticationToken 是我自定义的类 主要存一些自定义信息 下面会展示
CustomAuthenticationToken authRequest = new CustomAuthenticationToken(appId,redirect_URI,authType,principal,credentials);
setDetails(httpServletRequest,authRequest);
// 2.交给验证客户端,此方法则是将执行自定义AuthenticationProvider
return this.getAuthenticationManager().authenticate(authRequest);
}
坑点一:当我们需要实现自定义的 AbstractAuthenticationToken 实现类的时候 在AuthenticationProvider的
`
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(
CustomAuthenticationToken.class);
}`
方法时需要指定自定义的CustomAuthenticationToken类 不然方法不会进自定义AuthenticationProvider方法
当认证流程执行结构 成功回返回回调 失败会进入失败回调