和shiro整合后,使用shiro的session管理,shiro提供sessionDao操作 會話數據。
配置sessionManager
注入到securityManager
----------------------------------------驗證碼(自定義驗證器)---------------------------------
思路
shiro使用FormAuthenticationFilter進行表單認證,驗證校驗的功能應該加在FormAuthenticationFilter中,在認證之前進行驗證碼校驗。
需要寫FormAuthenticationFilter的子類,繼承FormAuthenticationFilter,改寫它的認證方法,在認證之前進行驗證碼校驗。
自定義FormAuthenticationFilter
package cn.qlq.springmvc.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 { //原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)){ //如果校驗失敗,將驗證碼錯誤失敗信息,通過shiroLoginFailure設置到request中 httpServletRequest.setAttribute("shiroLoginFailure", "randomCodeError"); //拒絕訪問,不再校驗賬號和密碼 return true; } return super.onAccessDenied(request, response); } }
配置自定義FormAuthenticationFilter
注入到Shiro 的Web過濾器
在login.action對驗證錯誤 進行解析
在登陸頁面添加驗證碼
驗證碼JSP:validatecode.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.util.Random"%> <%@ page import="java.io.OutputStream"%> <%@ page import="java.awt.Color"%> <%@ page import="java.awt.Font"%> <%@ page import="java.awt.Graphics"%> <%@ page import="java.awt.image.BufferedImage"%> <%@ page import="javax.imageio.ImageIO"%> <% int width = 60; int height = 32; //create the image BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = image.getGraphics(); // set the background color g.setColor(new Color(0xDCDCDC)); g.fillRect(0, 0, width, height); // draw the border g.setColor(Color.black); g.drawRect(0, 0, width - 1, height - 1); // create a random instance to generate the codes Random rdm = new Random(); String hash1 = Integer.toHexString(rdm.nextInt()); System.out.print(hash1); // make some confusion for (int i = 0; i < 50; i++) { int x = rdm.nextInt(width); int y = rdm.nextInt(height); g.drawOval(x, y, 0, 0); } // generate a random code String capstr = hash1.substring(0, 4); //將生成的驗證碼存入session session.setAttribute("validateCode", capstr); g.setColor(new Color(0, 100, 0)); g.setFont(new Font("Candara", Font.BOLD, 24)); g.drawString(capstr, 8, 24); g.dispose(); //輸出圖片 response.setContentType("image/jpeg"); out.clear(); out = pageContext.pushBody(); OutputStream strm = response.getOutputStream(); ImageIO.write(image, "jpeg", strm); strm.close(); %>
在filter配置匿名訪問驗證碼jsp(放行驗證碼JSP)