问题背景
回忆Oauth2获取access_token的流程,第一步是调用 Oauth2认证服务器 获取授权码接口
如: localhost:7777/oauth/authorize?client_id=cms&response_type=code
之后这个地址会跳转到Oauth2认证服务器登陆首页,进行账号密码输入,然后进入授权页
如图:
抛出问题
1 在这个过程中,调用获取授权码接口后,是如何自动跳转到 Oauth2认证服务器登陆页(http://localhost:7777/login 的
2 Oauth2登陆页的地址(默认:http://localhost:7777/login) 是否可以手动可配置,例如配置成(http://localhost:7777/myIndex),配置如何生效的
源码解读(一)
1 启动配置application.yml 便于我们查看调试过程
设置日志打印级别 用于调试源码
logging:
level:
root: debug
2 浏览器访问获取授权码请求地址 localhost:7777/oauth/authorize?client_id=cms&response_type=code 开始流程
关键类 ExceptionTranslationFilter
源码查看 继承了spring mvc 的拦截器 使得请求都进入到此拦截器中
追踪 chain.doFilter(request, response) 底层通过springmvc 框架路由到/oauth/authorize controller上
进入到授权 controller AuthorizationEndpoint中,发现发现未携带验证参数 (也就是未登录到 Oauth2认证中心 )
内部抛出了异常 throw new InsufficientAuthenticationException(
"User must be authenticated with Spring Security before authorization can be completed.")
回到上一个图中,此时这个方法请求处在ExceptionTranslationFilter的chain.doFilter(request, response) 中,此时方法抛出了异常,那么异常会被捕获,我们来看看异常捕获后做了什么处理,也就是
handleSpringSecurityException(request, response, chain, ase)
继续追踪
LoginUrlAuthenticationEntryPoint 类中 请留意这个redirectUrl参数
会发现这个redirectUrl 就是即将跳转的登陆首页地址
buildRedirectUrlToLoginPage(request, response, authException)拿到登陆首页地址之后,开始准备进行页面跳转
最终 response.sendRedirect("http://localhost:7777/login");
跳转至我们的首页
源码解读(二)
刚才我们发现最终跳转的首页地址是 redirectUrl参数决定的
也就是 redirectUrl = buildRedirectUrlToLoginPage(request, response, authException);
那么我们来看这里面 这个参数是哪里来的
最终发现是LoginUrlAuthenticationEntryPoint类中的loginFormUrl参数
那么这个值又是怎么设置进去的的?
为什么默认会是/login 我们不妨程序启动的时候debug看一下 启动流程
这一步我们发现程序启动的时候 这里设置的默认值为/login了
现在问题来了,如何改变这个默认值?将首页地址改成 /myIndex
可以如下解决
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// 配置登录页并允许访问
http.formLogin()
.loginPage("/myIndex")
.permitAll()
..........
}
}
我们来看这一步做了什么setLoginPage(loginPage)
这里就发现了 将默认的loginFormUrl 更新成自己设置的myIndex了
最终效果展示: