SpringSecurity3.X--验证码
来源:互联网 发布:淘宝网鼠标垫 编辑:程序博客网 时间:2024/05/23 19:18
SpringSecurity3.X--验证码
- 博客分类:
- Spring
- SpringSecurity
springspringsecurity
目录
SpringSecurity3.X--一个简单实现
SpringSecurity3.X--前台与后台登录认证
SpringSecurity3.X--remember-me
SpringSecurity3.X--验证码
一般来说,登录时都会要求用户输入验证码,以防止恶意登录。
可是,SpringSecurity并没有为我们提供这样的功能,所以就需要我们自己来解决了。
那么该如何解决呢,其实也挺简单的,
核对验证码信息,当然是在登录时处理的,所以,使用filter是最佳选择。
既然确定了方向,那么久该考虑如何增加这个filter了,其实可以有两种方案:
1.继承UsernamePasswordAuthenticationFilter ,在里面增加验证码验证规则即可;
2.自己定义一个filter,专门处理验证码验证;
笔者这里推荐使用第二种方案,因为第一种我们需要显示声明login-filter,所以需要修改SpringSecurity的配置文件,而方案2根本不需要修改,只需要向一般的filter一样,在web.xml中增加配置即可,唯一需要注意的是,mapping一定要与触发login-filter的url一致,如下所示:
- <filter>
- <filter-name>imageFilter</filter-name>
- <filter-class>com.piaoyi.common.filter.ImageFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>imageFilter</filter-name>
- <url-pattern>/j_spring_security_check</url-pattern>
- </filter-mapping>
<filter><filter-name>imageFilter</filter-name><filter-class>com.piaoyi.common.filter.ImageFilter</filter-class></filter><filter-mapping><filter-name>imageFilter</filter-name><url-pattern>/j_spring_security_check</url-pattern></filter-mapping>
另外需要注意的是,该filter的mapping一定要声明在springSecurityFilterChain的mapping之前,这样可以保证请求先被imageFilter处理。
设计思路就是这样的,这里给出一个简单的实现。
login.jsp
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- pageEncoding="UTF-8"%>
- <%@ include file="/WEB-INF/views/jsp/common/includes.jsp"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>登陆</title>
- </head>
- <body>
- <center>
- <div class="error">
- ${sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message }</div>
- <form name='f' id='f'
- action='<%=request.getContextPath()%>/j_spring_security_check'
- method='POST'>
- <table style="width: 50%">
- <tr>
- <td style="text-align: right; width: 35%">用户名称 :</td>
- <td style="text-align: left"><input type='text'
- name='j_username' value=''></td>
- </tr>
- <tr>
- <td style="text-align: right">密码 :</td>
- <td style="text-align: left"><input type='password'
- name='j_password' /></td>
- </tr>
- <tr>
- <td style="text-align: right"><label for="j_captcha"> 验证码: </label></td>
- <td>
- <input type='text' name='j_captcha' class="required"
- size='5' />
- <img id="imageF" src="<c:url value="/resource/image.jsp"/>" />
- <a href="#" id="flashImage">看不清楚换一张</a>
- </td>
- </tr>
- <tr>
- <td align="right"><input id="_spring_security_remember_me"
- name="_spring_security_remember_me" type="checkbox" value="true" />
- </td>
- <td><label for="_spring_security_remember_me">Remember Me?</label>
- </td>
- </tr>
- <tr>
- <td colspan="2" style="text-align: center"><input
- type="submit" name="submit" value="登录" /></td>
- </tr>
- </table>
- </form>
- </center>
- <script type="text/javascript">
- document.f.j_username.focus();
- if ('${message}' == 1) {
- alert("用户名或密码错误");
- }
- jQuery(function($){
- $("#flashImage").click(function(){
- $('#imageF').hide().attr('src','<c:url value="/resource/image.jsp"/>'+ '?'+ Math.floor(Math.random() * 100)).fadeIn();
- });
- });
- </script>
- </body>
- </html>
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><%@ include file="/WEB-INF/views/jsp/common/includes.jsp"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>登陆</title></head><body><center><div class="error">${sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message }</div><form name='f' id='f'action='<%=request.getContextPath()%>/j_spring_security_check'method='POST'><table style="width: 50%"><tr><td style="text-align: right; width: 35%">用户名称 :</td><td style="text-align: left"><input type='text'name='j_username' value=''></td></tr><tr><td style="text-align: right">密码 :</td><td style="text-align: left"><input type='password'name='j_password' /></td></tr><tr><td style="text-align: right"><label for="j_captcha"> 验证码: </label></td><td><input type='text' name='j_captcha' class="required"size='5' /><img id="imageF" src="<c:url value="/resource/image.jsp"/>" /><a href="#" id="flashImage">看不清楚换一张</a></td></tr><tr><td align="right"><input id="_spring_security_remember_me"name="_spring_security_remember_me" type="checkbox" value="true" /></td><td><label for="_spring_security_remember_me">Remember Me?</label></td></tr><tr><td colspan="2" style="text-align: center"><inputtype="submit" name="submit" value="登录" /></td></tr></table></form></center><script type="text/javascript">document.f.j_username.focus();if ('${message}' == 1) {alert("用户名或密码错误");}jQuery(function($){$("#flashImage").click(function(){$('#imageF').hide().attr('src','<c:url value="/resource/image.jsp"/>'+ '?'+ Math.floor(Math.random() * 100)).fadeIn();});});</script></body></html>
ImageFilter.java
- package com.piaoyi.common.filter;
- import java.io.IOException;
- import javax.servlet.Filter;
- import javax.servlet.FilterChain;
- import javax.servlet.FilterConfig;
- import javax.servlet.ServletException;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- public class ImageFilter implements Filter{
- @Override
- public void destroy() {
- // TODO Auto-generated method stub
- }
- @Override
- public void doFilter(ServletRequest arg0, ServletResponse arg1,
- FilterChain arg2) throws IOException, ServletException {
- // TODO Auto-generated method stub
- HttpServletRequest request = (HttpServletRequest) arg0;
- HttpServletResponse response = (HttpServletResponse) arg1;
- String yanzhengm = request.getParameter("j_captcha");
- String sessionyanz = (String)request.getSession(true).getAttribute("yzkeyword");
- if(yanzhengm.equals(sessionyanz)){
- arg2.doFilter(request, response);
- }else{
- response.sendRedirect("/login.do");
- }
- }
- @Override
- public void init(FilterConfig arg0) throws ServletException {
- // TODO Auto-generated method stub
- }
- }
package com.piaoyi.common.filter;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class ImageFilter implements Filter{@Overridepublic void destroy() {// TODO Auto-generated method stub}@Overridepublic void doFilter(ServletRequest arg0, ServletResponse arg1,FilterChain arg2) throws IOException, ServletException {// TODO Auto-generated method stubHttpServletRequest request = (HttpServletRequest) arg0; HttpServletResponse response = (HttpServletResponse) arg1; String yanzhengm = request.getParameter("j_captcha"); String sessionyanz = (String)request.getSession(true).getAttribute("yzkeyword"); if(yanzhengm.equals(sessionyanz)){ arg2.doFilter(request, response); }else{ response.sendRedirect("/login.do"); }}@Overridepublic void init(FilterConfig arg0) throws ServletException {// TODO Auto-generated method stub}}
image.jsp
- <%@ page contentType="image/jpeg" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" pageEncoding="UTF-8"%>
- <%!
- Color getRandColor(int fc,int bc){//随机获得颜色,RGB格式
- Random random = new Random();
- if(fc>255) fc=255;
- if(bc>255) bc=255;
- int r=fc+random.nextInt(bc-fc);
- int g=fc+random.nextInt(bc-fc);
- int b=fc+random.nextInt(bc-fc);
- return new Color(r,g,b);
- }
- %>
- <%
- //清除缓存,每次访问该页面时都从服务器端读取
- response.setHeader("Pragma","No-cache");
- response.setHeader("Cache-Control","no-cache");
- response.setDateHeader("Expires", 0);
- // 定义显示图片的宽度和高度
- int width=60, height=20;
- BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
- // 画图画板
- Graphics g = image.getGraphics();
- //定义一个随机数
- Random random = new Random();
- // 设置画板背景颜色
- g.setColor(getRandColor(200,250));
- //设置画板的填充范围
- g.fillRect(0, 0, width, height);
- //设置字体
- g.setFont(new Font("Times New Roman",Font.PLAIN,18));
- // 设置线条颜色并画线,155条
- g.setColor(getRandColor(160,200));
- for (int i=0;i<155;i++)
- {
- int x = random.nextInt(width);
- int y = random.nextInt(height);
- int xl = random.nextInt(12);
- int yl = random.nextInt(12);
- g.drawLine(x,y,x+xl,y+yl);
- }
- // 显示数字,4位长度
- String sRand="";
- for (int i=0;i<4;i++){
- String rand=String.valueOf(random.nextInt(10));
- sRand+=rand;
- // 设置每个数字的颜色
- g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
- //在画板上写数字,起始位置
- g.drawString(rand,13*i+6,16);
- }
- // 保存进session
- session.setAttribute("yzkeyword",sRand);
- //System.out.println("yzm:"+sRand);
- // 显示图片
- g.dispose();
- %>
- <%
- //转换成一张图片,格式为JPEG
- ImageIO.write(image, "JPEG", response.getOutputStream());
- out.clear();//清空缓存的内容。
- pageContext.pushBody();
- %>
<%@ page contentType="image/jpeg" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" pageEncoding="UTF-8"%><%!Color getRandColor(int fc,int bc){//随机获得颜色,RGB格式 Random random = new Random(); if(fc>255) fc=255; if(bc>255) bc=255; int r=fc+random.nextInt(bc-fc); int g=fc+random.nextInt(bc-fc); int b=fc+random.nextInt(bc-fc); return new Color(r,g,b); }%><%//清除缓存,每次访问该页面时都从服务器端读取response.setHeader("Pragma","No-cache");response.setHeader("Cache-Control","no-cache");response.setDateHeader("Expires", 0);// 定义显示图片的宽度和高度int width=60, height=20;BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);// 画图画板Graphics g = image.getGraphics();//定义一个随机数Random random = new Random();// 设置画板背景颜色g.setColor(getRandColor(200,250));//设置画板的填充范围g.fillRect(0, 0, width, height);//设置字体g.setFont(new Font("Times New Roman",Font.PLAIN,18));// 设置线条颜色并画线,155条g.setColor(getRandColor(160,200));for (int i=0;i<155;i++){ int x = random.nextInt(width); int y = random.nextInt(height); int xl = random.nextInt(12); int yl = random.nextInt(12); g.drawLine(x,y,x+xl,y+yl);}// 显示数字,4位长度String sRand="";for (int i=0;i<4;i++){ String rand=String.valueOf(random.nextInt(10)); sRand+=rand; // 设置每个数字的颜色 g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));//在画板上写数字,起始位置 g.drawString(rand,13*i+6,16);}// 保存进sessionsession.setAttribute("yzkeyword",sRand);//System.out.println("yzm:"+sRand);// 显示图片g.dispose();%><%//转换成一张图片,格式为JPEGImageIO.write(image, "JPEG", response.getOutputStream());out.clear();//清空缓存的内容。pageContext.pushBody();%>
applicationContext-security.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <beans:beans xmlns="http://www.springframework.org/schema/security"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
- xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
- xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc"
- xmlns:tool="http://www.springframework.org/schema/tool" xmlns:beans="http://www.springframework.org/schema/beans"
- xsi:schemaLocation="
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
- http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
- http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
- http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
- http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool-3.1.xsd
- http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"
- default-lazy-init="true">
- <http security="none" pattern="/index.do" />
- <http auto-config='true' access-decision-manager-ref="accessDecisionManager"
- access-denied-page="/index.do">
- <intercept-url pattern="/demo.do*" access="IS_AUTHENTICATED_REMEMBERED" />
- <intercept-url pattern="/**/*.do*" access="HODLE" />
- <logout logout-url="/logout.do" invalidate-session="true"
- logout-success-url="/logout.jsp" />
- <form-login login-page="/index.do" default-target-url="/frame.do"
- always-use-default-target="true" authentication-failure-url="/index.do?login_error=1" />
- <session-management>
- <concurrency-control max-sessions="1" expired-url="/timeout.jsp"/>
- </session-management>
- <remember-me key="jbcpPetStore" />
- </http>
- <!-- Automatically receives AuthenticationEvent messages -->
- <beans:bean id="loggerListener"
- class="org.springframework.security.authentication.event.LoggerListener" />
- <authentication-manager erase-credentials="false">
- <authentication-provider user-service-ref="userService">
- <password-encoder hash="md5" />
- </authentication-provider>
- </authentication-manager>
- <beans:bean id="userService" class="com.piaoyi.common.security.UserService" />
- <beans:bean id="accessDecisionManager"
- class="org.springframework.security.access.vote.AffirmativeBased">
- <beans:property name="decisionVoters">
- <beans:list>
- <beans:bean class="org.springframework.security.access.vote.RoleVoter" />
- <beans:bean
- class="org.springframework.security.access.vote.AuthenticatedVoter" />
- <beans:bean class="com.piaoyi.common.security.DynamicRoleVoter" />
- </beans:list>
- </beans:property>
- </beans:bean>
- </beans:beans>
转自http://hanqunfeng.iteye.com/blog/1158165
0 0
- SpringSecurity3.X--验证码
- SpringSecurity3用户验证(异常信息,验证码)
- springsecurity3的验证过程
- SpringSecurity3.X--remember-me
- SpringSecurity3.X--一个简单实现
- SpringSecurity3.X--一个简单实现
- 基于springMVC+springSecurity3.x+Mybaits3.x的权限系统
- 基于springMVC+springSecurity3.x+Mybaits3.x的权限系统,,开放源码,支持开源
- 基于springMVC+springSecurity3.x+Mybaits3.x的权限系统,,开放源码,支持开源
- 基于springMVC+springSecurity3.x+Mybaits3.x的权限系统,,开放源码,支持开源
- 基于SpringSecurity3.x, JasperReport5.x等技术实现仿金蝶权限管理的企业信息管理系统
- 基于springMVC+springSecurity3.x+Mybaits3.x的权限系统,,开放源码,支持开源 .
- 基于springMVC+springSecurity3.x+Mybaits3.x的权限系统,,开放源码,支持开源
- 蓝缘管理系统第二个版本开源了。springMVC+springSecurity3.x+Mybaits3.x 系统
- 基于springMVC+springSecurity3.x+Mybaits3.x的权限系统,,开放源码,支持开源
- 蓝缘管理系统第二个版本开源了。springMVC+springSecurity3.x+Mybaits3.x 系统
- 基于springMVC+springSecurity3.x+Mybaits3.x的权限系统,,开放源码,支持开源
- 基于springMVC+springSecurity3.x+Mybaits3.x的权限系统,,开放源码,支持开源
- UML图——用例图
- UDID替代方案
- rm: argument list too long 的处理方法
- Jenkins插件编写入门
- pycharm字体设置
- SpringSecurity3.X--验证码
- 数据库事务四个特性
- iLBC 技术点
- 华为U8220 fastboot刷机
- xCode5.0使用iOS6.1SDK及模拟器
- gridControl添加CheckEdit列问题的解决方法
- SQL2008数据表空间大小查询脚本
- 突然好想你
- jenkins中通过execute shell启动的进程会被杀死的问题