applicationContext-security.xml:

<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">

<!-- 访问被拒绝时跳转到403界面 -->
<http entry-point-ref="authenticationProcessingFilterEntryPoint"
access-denied-page="/403.jsp" >
<!-- 放行页面 -->
<intercept-url pattern="/*.css" filters="none" />
<intercept-url pattern="/error.jsp" filters="none" />
<intercept-url pattern="/index*.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="any" />
<!-- 访问全部要通过身份验证 -->
<intercept-url pattern="/**" access="isAuthenticated()" />
<!-- 访问全部要有ROLE_USER权限 -->
<intercept-url pattern="/**" access="ROLE_USER" />

<!-- 安全退出后的页面 -->
<logout logout-success-url="/logout.jsp" />
<!-- 两周内记住我 -->
<remember-me key="jbcpPetStore" />

<!-- 检测失效的sessionId,超时时定位到另外一个URL, -->
<session-management
session-authentication-error-url="/No_certification.jsp"
invalid-session-url="/index.jsp" session-fixation-protection="migrateSession">
<!-- 防止多端登录 -->
<concurrency-control max-sessions="1"
error-if-maximum-exceeded="true" expired-url="/error.jsp" />
</session-management>

<custom-filter ref="loginFilter" position="FORM_LOGIN_FILTER" />
</http>

<!-- 自定义登录过滤 -->
<beans:bean id="loginFilter"
class="filter.UsernamePasswordAuthenticationExtendFilter">
<!-- 验证页面 -->
<beans:property name="filterProcessesUrl" value="/j_spring_security_check" />
<!-- 验证成功后的处理 -->
<beans:property name="authenticationSuccessHandler"
ref="loginLogAuthenticationSuccessHandler" />
<!-- 验证失败后的处理 -->
<beans:property name="authenticationFailureHandler"
ref="simpleUrlAuthenticationFailureHandler" />
<!-- 认证器 -->
<beans:property name="authenticationManager" ref="authenticationManager" />

</beans:bean>

<!-- 认证器 -->
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref='myUserDetailsService' />
</authentication-manager>

<!-- 注入认证器 -->
<beans:bean id="myUserDetailsService" class="filter.MyUserDetailService" />

<!-- 开始注入登录过滤器 -->
<beans:bean id="loginLogAuthenticationSuccessHandler"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/welcome.jsp"></beans:property>
</beans:bean>
<beans:bean id="simpleUrlAuthenticationFailureHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/index.jsp?error=true"></beans:property>
</beans:bean>
<!-- 注入登录过滤器结束 -->

<beans:bean id="authenticationProcessingFilterEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/index.jsp"></beans:property>
</beans:bean>

</beans:beans>

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 防止请求Spring乱码 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<!--强制转换编码(request和response均适用) -->
<param-name>ForceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Spring Security过滤器 -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Struts2 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
<!-- Spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml,classpath:applicationContext-security.xml</param-value>
</context-param>
<!-- Spring监听 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 监听session 防止多端登录 -->
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
<!-- session有效期为30分 -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
</web-app>

继承UsernamePasswordAuthenticationFilter类的代码:

package filter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;

/**
* 重载SECURITY3的UsernamePasswordAuthenticationFilter的attemptAuthentication,
* obtainUsername,obtainPassword方法(完善逻辑) 增加验证码校验模块 添加验证码属性 添加验证码功能开关属性
*
* @author shadow
* @email 124010356@qq.com
* @create 2012.04.28
*/
public class UsernamePasswordAuthenticationExtendFilter extends UsernamePasswordAuthenticationFilter {

private SessionAuthenticationStrategy sessionAuthenticationStrategy = null;

public SessionAuthenticationStrategy getSessionAuthenticationStrategy() {
return sessionAuthenticationStrategy;
}

public void setSessionAuthenticationStrategy(
SessionAuthenticationStrategy sessionAuthenticationStrategy) {
this.sessionAuthenticationStrategy = sessionAuthenticationStrategy;
}

// 验证码字段
private String validateCodeParameter = "validateCode";
// 是否开启验证码功能
private boolean openValidateCode = false;

@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
request.getSession().removeAttribute("msg");
// 只接受POST方式传递的数据
if (!"POST".equals(request.getMethod())){
throw new AuthenticationServiceException("不支持非POST方式的请求!");
}

// 开启验证码功能的情况
if (isOpenValidateCode()){
checkValidateCode(request);
}

// 获取Username和Password
String username = obtainUsername(request);
String password = obtainPassword(request);

// UsernamePasswordAuthenticationToken实现Authentication校验
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
username, password);

// 允许子类设置详细属性
setDetails(request, authRequest);

// 运行UserDetailsService的loadUserByUsername 再次封装Authentication
return this.getAuthenticationManager().authenticate(authRequest);
}

// 匹对验证码的正确性
public void checkValidateCode(HttpServletRequest request) {
String jcaptchaCode = obtainValidateCodeParameter(request);
if (null == jcaptchaCode || "".equals(jcaptchaCode)){
throw new AuthenticationServiceException("请输入验证码");
}
if(null == request.getSession().getAttribute("rand")){
throw new AuthenticationServiceException("验证码失效");
}
//对比普通验证码
if(!request.getSession().getAttribute("rand").equals(jcaptchaCode)){
throw new AuthenticationServiceException("验证码错误!");
}
return;
}

public String obtainValidateCodeParameter(HttpServletRequest request) {
Object obj = request.getParameter(getValidateCodeParameter());
return null == obj ? "" : obj.toString().trim();
}

@Override
protected String obtainUsername(HttpServletRequest request) {
Object obj = request.getParameter(getUsernameParameter());
return null == obj ? "" : obj.toString().trim();
}

@Override
protected String obtainPassword(HttpServletRequest request) {
Object obj = request.getParameter(getPasswordParameter());
return null == obj ? "" : obj.toString().trim();
}

public String getValidateCodeParameter() {
return validateCodeParameter;
}

public void setValidateCodeParameter(String validateCodeParameter) {
this.validateCodeParameter = validateCodeParameter;
}

public boolean isOpenValidateCode() {
return openValidateCode;
}

public void setOpenValidateCode(boolean openValidateCode) {
this.openValidateCode = openValidateCode;
}
}

UserDetailsService页面代码:

package filter;

import java.util.ArrayList;
import java.util.Collection;

import model.UserDetail;

import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

/**
* 登录类
*
* @author Administrator
* @comment 在这个类中,你就可以从数据库中读入用户的密码、角色信息、是否锁定、 账号是否过期等. new User()方法参数说明, String
* username(用户名), String password(密码), boolean enabled(账户是否可用), boolean
* accountNonExpired(账户是否未过期), boolean accountNonLocked(账户是否未锁定),
* Collection<GrantedAuthority> authorities(账户所受权限).
*/
public class MyUserDetailService implements UserDetailsService {

@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
Collection<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
GrantedAuthorityImpl auth2 = new GrantedAuthorityImpl("ROLE_USER");// 进行授权
auths.add(auth2);// 添加所授的权限
UserDetail user = new UserDetail("123", "123", true, true, true, true, auths);
return user;
}
}

UserDetail类方法:

package model;

import java.util.Collection;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

@SuppressWarnings("serial")
public class UserDetail implements UserDetails {
private Collection<GrantedAuthority> authorities;
private String password;
private String username;
private boolean isAccountNonExpired;
private boolean isAccountNonLocked;
private boolean isCredentialsNonExpired;
private boolean isEnabled;

/** default constructor */
public UserDetail() {
}

public UserDetail(String username, String password,
boolean isAccountNonExpired, boolean isAccountNonLocked,
boolean isCredentialsNonExpired, boolean isEnabled, Collection<GrantedAuthority> authorities) {
this.username = username;
this.password = password;
this.isAccountNonExpired = isAccountNonExpired;
this.isAccountNonLocked = isAccountNonLocked;
this.isCredentialsNonExpired = isCredentialsNonExpired;
this.isEnabled = isEnabled;
this.authorities = authorities;
}

// Constructors

public Collection<GrantedAuthority> getAuthorities() {
return authorities;
}

public void setAuthorities(Collection<GrantedAuthority> authorities) {
this.authorities = authorities;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public boolean isAccountNonExpired() {
return isAccountNonExpired;
}

public void setAccountNonExpired(boolean isAccountNonExpired) {
this.isAccountNonExpired = isAccountNonExpired;
}

public boolean isAccountNonLocked() {
return isAccountNonLocked;
}

public void setAccountNonLocked(boolean isAccountNonLocked) {
this.isAccountNonLocked = isAccountNonLocked;
}

public boolean isCredentialsNonExpired() {
return isCredentialsNonExpired;
}

public void setCredentialsNonExpired(boolean isCredentialsNonExpired) {
this.isCredentialsNonExpired = isCredentialsNonExpired;
}

public boolean isEnabled() {
return isEnabled;
}

public void setEnabled(boolean isEnabled) {
this.isEnabled = isEnabled;
}

@Override
public boolean equals(Object obj) {
System.out.println("进入equals方法");
if (obj instanceof UserDetail) {
UserDetail another = (UserDetail)obj;
return this.getUsername().equals(another.getUsername());
}
return super.equals(obj);
}

@Override
public int hashCode() {
System.out.println("进入hashCode方法");
return this.getUsername().hashCode();
}

}

SpringSecurity自定义过滤器的更多相关文章

  1. Spring-security自定义过滤器

    定义过滤器 public class TokenAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter { publ ...

  2. SpringSecurity学习之自定义过滤器

    我们系统中的认证场景通常比较复杂,比如说用户被锁定无法登录,限制登录IP等.而SpringSecuriy最基本的是基于用户与密码的形式进行认证,由此可知它的一套验证规范根本无法满足业务需要,因此扩展势 ...

  3. Spring Security教程(六):自定义过滤器进行认证处理

    这里接着上篇的自定义过滤器,这里主要的是配置自定义认证处理的过滤器,并加入到FilterChain的过程. 在我们自己不在xml做特殊的配置情况下,security默认的做认证处理的过滤器为Usern ...

  4. SpringSecurity 自定义表单登录

    SpringSecurity 自定义表单登录 本篇主要讲解 在SpringSecurity中 如何 自定义表单登录 , SpringSecurity默认提供了一个表单登录,但是实际项目里肯定无法使用的 ...

  5. 实现MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器

    MVC开发中几种以AOP方式实现的Filters是非常好用的,默认情况下,我们通过App_Start中的FilterConfig来实现的过滤器注册是全局的,也就是整个应用程序都会使用的,针对单独的Fi ...

  6. lucene自定义过滤器

    先介绍下查询与过滤的区别和联系,其实查询(各种Query)和过滤(各种Filter)之间非常相似,可以这样说只要用Query能完成的事,用过滤也都可以完成,它们之间可以相互转换,最大的区别就是使用过滤 ...

  7. asp.net MVC之 自定义过滤器(Filter) - shuaixf

    一.系统过滤器使用说明 1.OutputCache过滤器 OutputCache过滤器用于缓存你查询结果,这样可以提高用户体验,也可以减少查询次数.它有以下属性: Duration :缓存的时间, 以 ...

  8. angular之自定义过滤器的使用

    自定义过滤器需要使用filter函数,格式如下: filter("filterName',function(){ return function(target,args){ .... } } ...

  9. 第六节:Vue过滤器的用法和自定义过滤器

    1.过滤器的用法,用  '|' 分割表达式和过滤器. 例如:{{ msg |  filter}}     {{msg | filter(a)}}  a就标识filter的一个参数. 用两个过滤器:{{ ...

随机推荐

  1. BCTF Web Code–考脑洞,你能过么?

    BCTF Web Code–考脑洞,你能过么? 1)打开链接,是一张图片 根据URL特点推断可能是有文件包含漏洞 2) 将jpg参数修改成index.php,查看源代码,发现base64编码后的代码 ...

  2. 一个简单的jQuery插件开发实例

    两年前写的一个简单的jQuery插件开发实例,还是可以看看的: <script type="text/javascript" src="jquery-1.7.2.m ...

  3. Shell出现cd命令无法识别

    出现cd 等命令无法识别的原因可能是: 当前文件实在windows环境下编辑的其换行结尾是 \r\n 和linux环境的 \n 不一致导致错误, 最好在linux系统上通过 VI 命令新建文件,然后通 ...

  4. MVC3+EF4.1学习系列(二)-------基础的增删改查和持久对象的生命周期变化

    上篇文章中 我们已经创建了EF4.1基于code first的例子  有了数据库 并初始化了一些数据  今天这里写基础的增删改查和持久对象的生命周期变化 学习下原文先把运行好的原图贴来上~~ 一.创建 ...

  5. [转]简述负载均衡和CDN技术

    http://blog.jobbole.com/86066/ 曾经见到知乎上有人问“为什么像facebook这类的网站需要上千个工程师维护?”,下面的回答多种多样,但总结起来就是:一个高性能的web系 ...

  6. [ An Ac a Day ^_^ ] CodeForces 468A 24 Game 构造

    题意是让你用1到n的数构造24 看完题解感觉被样例骗了…… 很明显 n<4肯定不行 然后构造出来4 5的组成24的式子 把大于4(偶数)或者5(奇数)的数构造成i-(i-1)=1 之后就是无尽的 ...

  7. JQ N级导航

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. chapter8_4 错误处理

    在Lua中,对于大多数程序都不用作任何错误处理,应用程序本身会负责这类问题. 所有的Lua活动都是由应用程序的一次调用开始的,这类调用要求Lua执行一个程序块. 执行过程中发生了错误,此调用会返回一个 ...

  9. 网页 JavaScript的DOM操作

    今天,我首先对之前学习的内容进行了复习,然后学习了当鼠标指向某一个按钮时,切换对应的背景图片. <div id="d1"> </div> <input ...

  10. 斯坦福大学公开课:iOS 7应用开发 笔记

    2015-07-06 第一讲   课务.iOS概述 -------------------------------------------------- 开始学习斯坦福大学公开课:iOS 7应用开发留 ...