一、前言
前面几篇博客都是结合源码简单介绍了下Spring Security的一点基本内容,今篇换换口味,简单看看一个关于登录成功跳转路径设置的问题。
二、defaultSuccessUrl与successForwardUrl
1、successForwardUrl
在SecurityConfig类中我们设置如下:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
....
// 登录成功跳转
.defaultSuccessUrl("/main",true)
....
}
上面是通过defaultSuccessUrl方法设置认证成功后跳转的路径,那其实也可以通过successForwardUrl这个方法设置:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
....
// 登录成功跳转
.successForwardUrl("/main")
....
}
那么他们有什么区别?其中的一个区别有时候也会是一个坑。
如果说我们用了successForwardUrl,并且在controller中如下返回页面,那么就会报错了。
@RequestMapping("/main")
public String toMain(Authentication authentication){
String name = SecurityContextHolder.getContext().getAuthentication().getName(); // 正确方式
System.out.println("登录用户:" + authentication.getName());
return "main.html";
}
其中第一个,此时括号中的authentication无法获取,要用第一行的方式获取用户的认证信息,这个说明下。
第二个可能有的时候一时没记起来就头疼了,登录成功跳转出现异常:There was an unexpected error (type=Method Not Allowed, status=405).:
提示该请求方式不支持,我们知道登录的请求是post方式,但是我们看输出toMain方法是执行了的,这里有个要注意的是springmvc不支持post请求直接返回页面,successForwardUrl是转发过来的,所以还是post请求,这里就报错了。所以如果要是用successForwardUrl,那么controller中最后在重定向一下就可以解决问题了:
@RequestMapping("/main")
public String toMain(Authentication authentication){
String name = SecurityContextHolder.getContext().getAuthentication().getName(); 正确方式
System.out.println("登录用户:" + authentication.getName()); 报错方式
return "redirect:/main.html";
}
2、defaultSuccessUrl
defaultSuccessUrl方法其实有两个重载的,
public final T defaultSuccessUrl(String defaultSuccessUrl) {
return defaultSuccessUrl(defaultSuccessUrl, false);
}
public final T defaultSuccessUrl(String defaultSuccessUrl, boolean alwaysUse) {
SavedRequestAwareAuthenticationSuccessHandler handler = new SavedRequestAwareAuthenticationSuccessHandler();
handler.setDefaultTargetUrl(defaultSuccessUrl);
handler.setAlwaysUseDefaultTargetUrl(alwaysUse);
this.defaultSuccessHandler = handler;
return successHandler(handler);
}
那其实第一个里面还是调用了带两个参数的,那么第二个boolean类型参数到底有何作用。如果说我们配置的时候使用第一个方法:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
....
// 登录成功跳转
.defaultSuccessUrl("/main")
....
}
那么这个时候会出现个问题,假如我们还没有登录认证,在浏览器输入一个不存在的url,例如localhost:8080/test,那通过此前的配置security会帮我们导向登录页面,然后当我们登录成功后你会发现跳转的路径变成了/test,而不是设置的/main。
使用第二个方法,并且第二参数置为true,那么就不会出现上面问题,会直接转到/main。