`
hanqunfeng
  • 浏览: 1543369 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

SpringSecurity3.X--验证码

阅读更多

目录

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的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>

 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
		
	}

	
}

 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();
%>
 

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>

 效果图如下:

 

 

另外,从网上也看到了类似的解决方案:

springsecurity3和JCaptcha的整合

里面使用到了jcaptcha的jar包,我整合后发现也很好用,附件中给出jar包。

  • 大小: 8.5 KB
分享到:
评论
1 楼 愛吃小雪生 2014-05-21  
谷歌浏览器filter好像通不过啊,一直取不到session里面的验证码

相关推荐

    spring boot3.x结合spring security最新版实现jwt登录验证

    本教程将详细讲解如何在Spring Boot 3.x版本中结合Spring Security的最新版实现JWT(JSON Web Token)登录验证。 首先,让我们了解JWT。JWT是一种轻量级的身份认证和授权机制,它以JSON对象的形式在客户端和服务器...

    基于SpringSecurity 5.7.x的微服务安全设计与源码实现

    结果:本项目采用Spring Security 5.7.x框架,实现了微服务架构下的安全设计方案及其源码实现。项目主要使用Java语言开发,同时涉及HTML、CSS和JavaScript等前端技术。项目文件总计519个,包括Java源文件345个、XML...

    基于Spring Boot 2.x的前后端分离架构X-Boot 后台.zip

    .zip,基于Spring Boot 2.x的前后端分离开发平台X-Boot 前端:Vue iView Admin 后端:Spring Boot 2.x/Spring Security/JWT/Spring Data JPA Mybatis-Plus/Redis/Elasticsearch/Activiti 分布式限流/同步锁/验证码/...

    基于Spring Boot 2.x的Java一站式前后端分离快速开发平台XBoot设计源码

    平台支持微信小程序和Uniapp前端开发,后端采用Vue+iView Admin,并结合了Spring Boot 2.x、Spring Security、JWT、JPA、Mybatis-Plus、Redis、Elasticsearch、Activiti等先进技术。功能丰富,包括分布式限流、同步...

    基于Spring Boot 2.x的一站式前后端分离快速开发平台

    XBoot 微信小程序+Uniapp 前端:Vue+iView Admin 后端:Spring Boot 2.x/Spring Security/JWT/JPA+Mybatis-Plus/Redis/Elasticsearch/Activiti 分布式限流/同步锁/验证码/SnowFlake雪花算法ID生成 动态权限管理 数据...

    全套Spring Security入门到项目实战课程

    ### Spring Security 全套入门到项目实战课程知识点详解 #### 一、Spring Security 概述 **1.1 Spring Security 介绍** - **定义**: Spring Security 是一款基于 Spring 框架的身份认证(Authentication)与用户...

    SpringBoot2.7整合SpringSecurity+Jwt+Redis+MySQL+MyBatis完整项目代码

    在本项目中,我们主要关注的是SpringBoot 2.7版本与多个技术的深度整合,包括Spring Security、JWT(JSON Web Token)、Redis缓存以及MySQL数据库,并利用MyBatis作为持久层框架。以下是对这些技术及其整合应用的...

    x-boot前后端分离开发平台

    基于Spring Boot 2.x的前后端分离开发平台X-Boot 前端:Vue+iView Admin 后端:Spring Boot 2.x/Spring Security/JWT/Spring Data JPA+Mybatis-Plus/Redis/Elasticsearch/Activiti 分布式限流/同步锁/验证码/...

    Spring boot+vue3+element plus实现后台管理系统

    前后端分离项目,Spring boot作为后端,vue框架实现前端,后端整合swagger3测试工具,jwt实现验证码生成,awt生成图形验证码,整合邮箱验证,使用mybatis-generator自动生成实体类以及mapper,设置有拦截器验证登录...

    SpringSecurity框架下实现CSRF跨站攻击防御的方法

    SpringSecurity框架下实现CSRF跨站攻击防御的方法 CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种网络攻击方式,也可以说是一种安全漏洞,这种安全漏洞在web开发中广泛存在。在SpringSecurity框架下,...

    security-demo:Springboot,SpringSecutity常见演示集

    整理了SpringSecurity常见示例 模块划分,帮你快速掌握Spring Security 1.核心依赖 依赖 版本 Sprint Boot 2.1.6发布 春云 格林威治SR2 Spring安全 2.1.6发布 Spring安全OAuth2 2.1.3发布 胡图尔 4.0.5 2.模块整理...

    java版商城源码下载-learning-project:该项目收集一些优秀的开源项目

    Security/JWT/Spring Data JPA+Mybatis-Plus/Redis/Elasticsearch/Activiti 分布式限流/同步锁/验证码/SnowFlake雪花算法ID生成 动态权限管理 数据权限 工作流 代码生成 日志 定时任务 第三方社交账号、短信登录 单...

    xboot-front:基于Vue + iView Admin开发的XBoot前初始化分离开放平台前端权限可控制至按钮显示动态路由权限菜单多语言简洁美观的前瞻分离

    涉及技术:Spring Boot 2.x / Spring Security / JWT / Spring Data JPA + Mybatis-Plus / Redis / Elasticsearch分布式限流/同步锁/验证码/ SnowFlake雪花算法ID生成动态权限管理定时任务第三方账号,短信登录 ...

    acegi资料大全-全集

    `Acegi X_509双向认证 (添加验证码jcaptcha).mht`可能涉及到了基于X.509证书的SSL/TLS客户端认证,这是一种更高级的身份验证方式,常用于企业级应用。同时,结合jCaptcha的使用,可以防止恶意自动化的登录尝试,...

    CAS服务器部署

    1. **客户端配置**:在需要接入CAS的各个应用系统中,配置CAS客户端库,如Spring Security CAS。 2. **服务URL配置**:设置每个应用的CAS服务URL,以及服务验证和登出URL。 3. **测试登录**:通过浏览器访问应用,...

    ssh框架搭建并简单实例实现(注册登录功能)

    3. 如果验证成功,可以使用Spring Security或自定义Session管理实现用户登录状态的维护。 4. 登录成功后,跳转到主页或其他受保护的页面。 在实践中,还需要处理可能出现的异常,优化用户体验,如添加验证码、错误...

    基于SpringBoot+Vue实现的小区物业管理系统介绍

    - **后端**:使用SpringBoot作为主框架,SpringSecurity进行安全控制,Mybatis-Plus简化数据操作,EasyExcel处理Excel导出,Kaptcha用于生成图片验证码。 - **前端**:采用Vue.js作为前端框架,axios处理HTTP请求...

    Web安全培训ppt(适合初学者)

    开发工具:安全框架Spring security、 shiro、Spring boot 3、安全工具和设备(2天) DDos防护、WAF、主机入侵防护等等 4、网站安全工具(1天) 阿里云、云狗、云盾 网站在线检测:http://webscan.360.cn/ ...

    基于JAVA的安全电子商务(文档).zip

    Spring Security是Java生态系统中的一个强大安全框架,广泛应用于后端开发。它提供了访问控制、身份验证、会话管理等功能,可以帮助开发者轻松实现权限控制,防止未授权的访问和攻击。 5. **Apache HttpClient** ...

Global site tag (gtag.js) - Google Analytics