默认拦截器FormAuthenticationFilter 只拦截post请求。
不需要配置authc = org.apache.shiro.web.filter.authc.FormAuthenticationFilter
,因为默认的就是FormAuthenticationFilter
。
我们在登录的时候,如果用户名为username,密码为password,那么我们可以不用自己写登录的代码,FormAuthenticationFilter这个过滤器会自动帮我们进行登陆验证。在测试shiro框架的时候,也都没问题。
但是后来在实际项目开发中,突然发现FormAuthenticationFilter不起作用了,后来才发现原因:在测试的时候,filterChainDefinitions中配置了/** = authc
,表示所有访问地址都有经过FormAuthenticationFilter过滤,但是在实际项目的时候,并没有这么配置,因此失效了。
解决方案:filterChainDefinitions下配置加上/login = authc,此处的/login就是你登录的时候表单提交的路径。
提示:authc表示使用FormAuthenticationFilter来过滤
1. 判断当前URL是否为登录地址:
shiroFilter的loginUrl值。
boolean org.apache.shiro.web.filter.AccessControlFilter.isLoginRequest(ServletRequest request, ServletResponse response);
2. 如果当前请求URL为登录地址时,判断是否为form提交。
boolean org.apache.shiro.web.filter.authc.FormAuthenticationFilter.isLoginSubmission(ServletRequestrequest, ServletResponse response);
在此两点可以总结出登录表单及登录界面URL的规则,即:
get loginUrl:进入登录界面
post loginUrl:提交登录表单
username:表单用户名
password:表单密码
当登陆报错了才会进来login方法中来。若身份验证成功的话,会直接跳转到之前的访问地址或是successfulUrl去。因为在FormAuthenticationFilter
内部都已经做完认证了。我们只需要在login方法中写上(判断异常类型)验证失败的逻辑就好,
@RequestMapping(value = "login",method = RequestMethod.POST)
public string loginSubmit(Param param) {
String errorClassName = (String) ServletHelper.getRequestAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
if(UnknownAccountException.class.getName().equals(errorClassName)) {
ServletHelper.setRequestAttribute("error", "用户名/密码错误");
} else if(IncorrectCredentialsException.class.getName().equals(errorClassName)) {
ServletHelper.setRequestAttribute("error", "用户名/密码错误");
} else if(errorClassName != null) {
ServletHelper.setRequestAttribute("error", "未知错误:" + errorClassName);
}
// 登录失败后,跳回到login画面,让用户再次登录
return "admin/login";
}
//DisabledAccountException (禁用的帐号)
//LockedAccountException (锁定的帐号)
//UnknownAccountException(错误的帐号)
//ExcessiveAttemptsException(登录失败次数过多)
//IncorrectCredentialsException (错误的凭证)
//ExpiredCredentialsException (过期的凭证)
……
shiroFilter的successUrl值
<!--successUrl配置只是做为一种附加配置,只有session中没有用户请求地址时才会使用successUrl。--> <!--系统默认的是认证成功后跳转到上一次请求的路径,如果是首次请求,--> <!--那shiro就会跳转到默认虚拟路径“/”,也就是跳转到index.jsp。-->