自定义FormAuthentia

来源:互联网 发布:产品模型数据交换标准 编辑:程序博客网 时间:2024/06/06 01:40

1.shiro使用FormAuthenticationFilter进行验证码进行表单验证,验证码的功能应该加在FormAuthenticationFilter中,在认证之前进行验证码校验。

需要编写FormAuthenticationFilter的子类,继承FormAuthenticationFilter,改写它的认证方法,在认证之前进行验证码校验

2.自定义FormAuthenticationFilter

package cn.itcast.ssm.shiro;


import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;


import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;


public class CustomFormAuthenticationFilter extends FormAuthenticationFilter{


@Override
protected boolean onAccessDenied(ServletRequest request,
ServletResponse response) throws Exception {
// 在这里进行验证码校验
//从session获取正确验证码
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpSession session = httpServletRequest.getSession();
//取出session的验证码(正确的验证码)
String validateCode = (String) session.getAttribute("validateCode");

//取出页面的验证码
//输入的验证码和session中的验证码对比
String randomcode = httpServletRequest.getParameter("randomcode");
if(randomcode != null && validateCode != null && !randomcode.equals(validateCode)){
//如果校验失败,将验证码错误失败信息通过shiroLoginFailuerZ设置到request中
httpServletRequest.setAttribute("shiroLoginFilure", "randomcode");
//拒绝访问,不再 校验账号和密码
return true;
}
return super.onAccessDenied(request, response);
}

//原FormAuthenticationFilter的认证方法

}

3.配置自定义的 CustomFormAuthenticationFilter 

<!-- 自定义form认证过虑器 -->
<!-- 基于Form表单的身份验证过滤器,不配置将也会注册此过虑器,表单中的用户账号、密码及loginurl将采用默认值,建议配置 -->
<bean id="formAuthenticationFilter" 
class="cn.itcast.ssm.shiro.CustomFormAuthenticationFilter ">
<!-- 表单中账号的input名称 -->
<property name="usernameParam" value="username" />
<!-- 表单中密码的input名称 -->
<property name="passwordParam" value="password" />
 </bean>

4.对controller进行编写:

package cn.itcast.ssm.controller;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;


import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;


import cn.itcast.ssm.exception.CustomException;
import cn.itcast.ssm.po.ActiveUser;
import cn.itcast.ssm.service.SysService;


/**
 * 
 * <p>Title: LoginController</p>
 * <p>Description: 登陆和退出</p>
 * <p>Company: www.itcast.com</p> 
 * @author
 * 
 * @version 1.0
 */
@Controller
public class LoginController {

@Autowired
private SysService sysService;


//用户登陆提交方法
/**

* <p>Title: login</p>
* <p>Description: </p>
* @param session
* @param randomcode 输入的验证码
* @param usercode 用户账号
* @param password 用户密码 
* @return
* @throws Exception
*/
/* @RequestMapping("/login")
public String login(HttpSession session, String randomcode,String usercode,String password)throws Exception{

//校验验证码,防止恶性攻击
//从session获取正确验证码
String validateCode = (String) session.getAttribute("validateCode");

//输入的验证和session中的验证进行对比 
if(!randomcode.equals(validateCode)){
//抛出异常
throw new CustomException("验证码输入错误");
}

//调用service校验用户账号和密码的正确性
ActiveUser activeUser = sysService.authenticat(usercode, password);

//如果service校验通过,将用户身份记录到session
session.setAttribute("activeUser", activeUser);
//重定向到商品查询页面
return "redirect:/first.action";
}*/

@RequestMapping("/login")
public String login(HttpServletRequest request)throws Exception{

//如果登录失败从request中获取认证异常信息,shiroLoginFailuer就是shiro异常类的权限命名
String exceptionClassName = (String) request.getAttribute("shiroLoginFailuer");
//根据shiro返回的异常类路径判断,抛出指定异常信息
if(exceptionClassName != null){
if(UnknownAccountException.class.getName().equals(exceptionClassName)){
//最终会抛给异常处理器
throw new CustomException("账号不存在");

}else if(IncorrectCredentialsException.class.getName().equals(exceptionClassName)){
throw new CustomException("用户名/密码错误");
}else if("randomCodeError".equals(exceptionClassName)){
throw new CustomException("验证码错误");
}else{
throw new Exception();//最终在异常处理器生成未知错误
}
}
//此方法不出来登录成功(认证成功),shiro认证成功会自动跳转到上一个请求路径
// 登录失败还到login页面
return "login";
}
/* //用户退出
@RequestMapping("/logout")
public String logout(HttpSession session)throws Exception{

//session失效
session.invalidate();
//重定向到商品查询页面
return "redirect:/first.action";

}
*/


}

6.参考添加验证码的方法

7.在filter配置匿名访问验证码jsp


<!-- 过虑器链定义,从上向下顺序执行,一般将/**放在最下边 -->
<property name="filterChainDefinitions">
<value>
<!-- 对静态资源设置匿名访问 -->
/images/** = anon
/js/** = anon
/styles/** = anon
<!-- 验证码,可匿名访问 -->
/validatecode.jsp = anon



原创粉丝点击