自定义Spring Security过滤器
来源:互联网 发布:js数组的sort 编辑:程序博客网 时间:2024/05/17 07:02
准备:
1、Spring Security需要自定义一个继承至AbstractSecurityInterceptor的Filter,该抽象类包含了AccessDecisionManager(决策管理器)、AuthenticationManager(身份认证管理器)的setter, 可以通过Spring自动注入,另外,资源角色授权器需要单独自定义注入
2、AccessDecisionManager(决策管理器)的实现需要实现AccessDecisionManager接口,在实现的decide(Authentication arg0, Object arg1,Collection<ConfigAttribute> arg2)方法中,需要将用户具有的角色权限Collection<GrantedAuthority> grantedAuthorities=arg0.getAuthorities();与访问该资源所需要的金额角色权限Collection<ConfigAttribute> arg2进行比较,若有一个角色匹配,则放行允许该用户访问此资源。
3、AuthenticationManager(身份认证管理器)可以通过applicationContext-security.xml中<authentication-manager />标签实现。该标签需要引用一个实现了UserDetailService接口的类。该类的loadUserByUsername(String username)方法,通过传进来的用户名返回一个User对象,构造该User对象时需要传入GrantedAuthority的Collection,此时可以通过不同的用户名赋予不同的GrantedAuthority。
4、资源角色授权器需要实现FilterInvocationSecurityMetadataSource接口。请求的资源所需要的角色权限在服务器启动时候就已经确定的,所以在该实现类的构造方法中需要确定每一种资源需要那些角色权限,通过一个Map<String, List<ConfigAttribute>>即可将所有资源所需要的List<ConfigAttribute>存储起来。该实现类中getAttributes(Object arg0)方法,可以通过请求的url返回对应的Collection<ConfigAttribute>,通过传进来的FilterInvocation可以得到RequestUrl,然后遍历Map<String, List<ConfigAttribute>>。
一、定义继承至AbstractSecurityInterceptor的CustomSecurityFilter。
1 package com.spring.security.demo; 2 3 import java.io.IOException; 4 5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest;10 import javax.servlet.ServletResponse;11 12 import org.springframework.security.access.SecurityMetadataSource;13 import org.springframework.security.access.intercept.AbstractSecurityInterceptor;14 import org.springframework.security.access.intercept.InterceptorStatusToken;15 import org.springframework.security.web.FilterInvocation;16 import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;17 18 public class CustomSecurityFilter extends AbstractSecurityInterceptor implements19 Filter20 {21 private FilterInvocationSecurityMetadataSource securityMetadataSource;22 23 public FilterInvocationSecurityMetadataSource getSecurityMetadataSource()24 {25 return securityMetadataSource;26 }27 28 public void setSecurityMetadataSource(29 FilterInvocationSecurityMetadataSource securityMetadataSource)30 {31 this.securityMetadataSource = securityMetadataSource;32 }33 34 @Override35 public void destroy()36 {37 // TODO Auto-generated method stub38 39 }40 41 @Override42 public void doFilter(ServletRequest arg0, ServletResponse arg1,43 FilterChain arg2) throws IOException, ServletException44 {45 FilterInvocation fileInvocation = new FilterInvocation(arg0, arg1, arg2);46 InterceptorStatusToken interceptorStatusToken = this47 .beforeInvocation(fileInvocation);48 fileInvocation.getChain().doFilter(arg0, arg1);49 this.afterInvocation(interceptorStatusToken, null);50 }51 52 @Override53 public void init(FilterConfig arg0) throws ServletException54 {55 // TODO Auto-generated method stub56 57 }58 59 @Override60 public Class<? extends Object> getSecureObjectClass()61 {62 return FilterInvocation.class;63 }64 65 @Override66 public SecurityMetadataSource obtainSecurityMetadataSource()67 {68 return this.securityMetadataSource;69 }70 71 }
二、定义AccessDecisionManager(决策管理器)、AuthenticationManager(身份认证管理器)、实现了UserDetailService接口的CustomUserDetailService。
CustomAccessDecisionManager.java
1 package com.spring.security.demo.dependent.components; 2 3 import java.util.Collection; 4 import java.util.Iterator; 5 6 import org.springframework.security.access.AccessDecisionManager; 7 import org.springframework.security.access.AccessDeniedException; 8 import org.springframework.security.access.ConfigAttribute; 9 import org.springframework.security.access.SecurityConfig;10 import org.springframework.security.authentication.InsufficientAuthenticationException;11 import org.springframework.security.core.Authentication;12 import org.springframework.security.core.GrantedAuthority;13 14 public class CustomAccessDecisionManager implements AccessDecisionManager15 {16 /**17 * Authentication arg0 --->用户具有的角色权限 18 * Collection<ConfigAttribute> arg2 --->访问该资源所需的角色权限19 */20 @Override21 public void decide(Authentication arg0, Object arg1,22 Collection<ConfigAttribute> arg2) throws AccessDeniedException,23 InsufficientAuthenticationException24 {25 Iterator<ConfigAttribute> iter = arg2.iterator();26 while (iter.hasNext())27 {28 String accessResourceNeedRole = ((SecurityConfig) iter.next())29 .getAttribute();30 for (GrantedAuthority grantedAuthority : arg0.getAuthorities())31 {32 String userOwnRole = grantedAuthority.getAuthority();33 if (accessResourceNeedRole.equals(userOwnRole))34 {35 return;36 }37 }38 }39 throw new AccessDeniedException("访问被拒绝!");40 }41 42 @Override43 public boolean supports(ConfigAttribute arg0)44 {45 return true;46 }47 48 @Override49 public boolean supports(Class<?> arg0)50 {51 return true;52 }53 54 }
CustomFilterInvocationSecurityMetadataSource.java
1 package com.spring.security.demo.dependent.components; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 import java.util.HashMap; 6 import java.util.Iterator; 7 import java.util.List; 8 import java.util.Map; 9 10 import org.springframework.security.access.ConfigAttribute;11 import org.springframework.security.access.SecurityConfig;12 import org.springframework.security.web.FilterInvocation;13 import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;14 import org.springframework.security.web.util.AntUrlPathMatcher;15 import org.springframework.security.web.util.UrlMatcher;16 17 public class CustomFilterInvocationSecurityMetadataSource implements18 FilterInvocationSecurityMetadataSource19 {20 private Map<String, List<ConfigAttribute>> mp;21 private UrlMatcher urlMatcher;22 23 /**24 * 构造每一种资源所需要的角色权限25 */26 public CustomFilterInvocationSecurityMetadataSource()27 {28 super();29 this.mp = new HashMap<String, List<ConfigAttribute>>();30 this.urlMatcher = new AntUrlPathMatcher();31 List<ConfigAttribute> list = new ArrayList<ConfigAttribute>();32 ConfigAttribute cb = new SecurityConfig("Role_ADMIN"); // 构造一个权限(角色)33 ConfigAttribute cbUser = new SecurityConfig("Role_USER"); // 构造一个权限(角色)34 ConfigAttribute cbManager = new SecurityConfig("Role_MANAGER"); // 构造一个权限(角色)35 list.add(cb);36 list.add(cbUser);37 list.add(cbManager);38 39 mp.put("/Main.jsp", list);40 list.remove(2);41 mp.put("/Main2.jsp", list);42 }43 44 @Override45 public Collection<ConfigAttribute> getAllConfigAttributes()46 {47 return null;48 }49 50 /**51 * 获取访问某一个url所需的角色52 */53 @Override54 public Collection<ConfigAttribute> getAttributes(Object arg0)55 throws IllegalArgumentException56 {57 String requestUrl = ((FilterInvocation) arg0).getRequestUrl();58 Iterator<String> iter = this.mp.keySet().iterator();59 while (iter.hasNext())60 {61 String temp = iter.next();62 if (this.urlMatcher.pathMatchesUrl(requestUrl, temp))63 {64 return mp.get(temp);65 }66 }67 68 return null;69 }70 71 @Override72 public boolean supports(Class<?> arg0)73 {74 return true;75 }76 77 }
CustomUserDetailService.java
1 package com.spring.security.demo.dependent.components; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import org.springframework.dao.DataAccessException; 7 import org.springframework.security.core.GrantedAuthority; 8 import org.springframework.security.core.authority.GrantedAuthorityImpl; 9 import org.springframework.security.core.userdetails.User;10 import org.springframework.security.core.userdetails.UserDetails;11 import org.springframework.security.core.userdetails.UserDetailsService;12 import org.springframework.security.core.userdetails.UsernameNotFoundException;13 14 public class CustomUserDetailService implements UserDetailsService15 {16 /**17 * arg0 --->登录的用户名18 */19 @Override20 public UserDetails loadUserByUsername(String arg0)21 throws UsernameNotFoundException, DataAccessException22 {23 List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();24 GrantedAuthority grantedAuthority = null;25 26 if ("admin".equals(arg0))27 {28 grantedAuthority = new GrantedAuthorityImpl("Role_ADMIN");29 }30 else if ("manager".equals(arg0))31 {32 grantedAuthority = new GrantedAuthorityImpl("Role_MANAGER");33 }34 else35 {36 grantedAuthority = new GrantedAuthorityImpl("Role_USER");37 }38 grantedAuthorities.add(grantedAuthority);39 40 User user = new User(arg0, "123456", true, true, true, true,41 grantedAuthorities);42 43 return user;44 }45 46 }
三、完成applicationContext-security.xml以及web.xml的配置
applicationContext-security.xml
1 <beans:beans xmlns="http://www.springframework.org/schema/security" 2 xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 4 http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd"> 5 6 <!-- 用户验证通过才能授权,若不通过会跳到authentication-failure-url(验证失败页面) 7 若用户验证通过,但没有default-target-url的访问权限,则会跳转至access-denied-page(授权失败页面) --> 8 <http access-denied-page="/AccessDenied.jsp"> 9 <intercept-url pattern="/Login.jsp" filters="none" />10 <logout logout-success-url="/Login.jsp" />11 <form-login login-page="/Login.jsp" default-target-url="/Main.jsp"12 authentication-failure-url="/Login.jsp" />13 <http-basic />14 15 <custom-filter ref="CustomSecurityFilter" before="FILTER_SECURITY_INTERCEPTOR" />16 </http>17 18 <beans:bean id="CustomSecurityFilter"19 class="com.spring.security.demo.CustomSecurityFilter">20 21 <!-- 注入决策管理器 -->22 <beans:property name="accessDecisionManager" ref="CC_AccessDecisionManager"></beans:property>23 24 <!-- 注入资源角色授权管理器 -->25 <beans:property name="securityMetadataSource" ref="CC_SecurityMetadataSource"></beans:property>26 27 <!-- 注入身份认证管理器 -->28 <beans:property name="authenticationManager" ref="CC_AuthenticationManager"></beans:property>29 30 </beans:bean>31 32 <beans:bean id="CC_SecurityMetadataSource"33 class="com.spring.security.demo.dependent.components.CustomFilterInvocationSecurityMetadataSource"></beans:bean>34 35 <beans:bean id="CC_AccessDecisionManager"36 class="com.spring.security.demo.dependent.components.CustomAccessDecisionManager"></beans:bean>37 38 <authentication-manager alias="CC_AuthenticationManager">39 <authentication-provider user-service-ref="AidUserDetailService"></authentication-provider>40 </authentication-manager>41 42 <beans:bean id="AidUserDetailService"43 class="com.spring.security.demo.dependent.components.CustomUserDetailService"></beans:bean>44 </beans:beans>
web.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 5 version="3.0"> 6 <listener> 7 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 8 </listener> 9 10 <context-param>11 <param-name>contextConfigLocation</param-name>12 <param-value>/WEB-INF/applicationContext*.xml</param-value>13 </context-param>14 15 <filter>16 <filter-name>springSecurityFilterChain</filter-name>17 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>18 </filter>19 20 <filter-mapping>21 <filter-name>springSecurityFilterChain</filter-name>22 <url-pattern>/*</url-pattern>23 </filter-mapping>24 25 <display-name></display-name>26 <welcome-file-list>27 <welcome-file>index.jsp</welcome-file>28 </welcome-file-list>29 </web-app>
四、完成前台测试页面
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head>10 <base href="<%=basePath%>">11 12 <title>用户登录</title>13 14 <meta http-equiv="pragma" content="no-cache">15 <meta http-equiv="cache-control" content="no-cache">16 <meta http-equiv="expires" content="0">17 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">18 <meta http-equiv="description" content="This is my page">19 <!--20 <link rel="stylesheet" type="text/css" href="styles.css">21 -->22 23 </head>24 25 <body>26 <div>27 用户名:admin (admin拥有Role_ADMIN角色,其他任意用户拥有Role_USER角色)28 密码:12345629 </div>30 <hr />31 <form action="j_spring_security_check" method="POST"> 32 用户名:<input type="text" name="j_username" /><br />33 密码:<input type="password" name="j_password"><br />34 <input type="submit" value="登录">35 </form>36 </body>37 </html>
- 自定义Spring Security过滤器
- spring security自定义过滤器
- 自定义security过滤器顺序
- Spring Security 自定义资源访问权限过滤器Fliter ,参考FilterSecurityInteceptor
- spring security过滤器
- spring security FilterSecurityInterceptor过滤器
- spring security UsernamePasswordAuthenticationFilter过滤器
- spring security 源码分析: 过滤器
- spring security学习- 图解过滤器
- spring-security的过滤器执行
- spring security 自定义验证
- spring security - 自定义登陆
- spring security 自定义 openid
- Spring Security自定义Login
- spring security 2中使用通过自定义过滤器实现多登录页面
- spring security 二中使用通过自定义过滤器实现多登录页面
- 图解Spring Security默认使用的过滤器
- 关于Spring-security的过滤器分析
- 基于SSH框架的JAVA WEB程序员所需掌握技术
- C++的输入输出问题
- 主席树/函数式线段树/可持续化线段树 POJ_2104,BZOJ_1901,ZOJ_2112
- 广州现场赛D题Signal Interference(计算几何)
- cmd.jsp 经典版
- 自定义Spring Security过滤器
- 堆和栈的区别
- Android------SQLite
- 面试中必须会写的函数源码--------strcpy()与strlen()
- 在Windows上调整SGA大小遭遇ORA-27100、ORA-27102错误的处理方法
- Js获取当前日期时间及其它操作
- Android-ViewPagerIndicator简单集成
- POJ1144 Network PASCAL代码
- SSH原理与运用