- 浏览: 174119 次
- 性别:
- 来自: 成都
最新评论
-
lizhenlzlz:
@XStreamAsAttribute()属性
XStream 用法详解 java 类与 XML 互换 -
rouguo:
挺好的,找了一周的资料,找到的基本都是关于,直接定义用户,或者 ...
spring security 3 自定义认证,授权示例 -
Seanman:
caoyangx 写道不知道你试过没有,saveOrDelet ...
spring security 3 扩展 HttpSessionEventPublisher 统计在线用户数 -
Seanman:
cn_hack 写道caoyangx 写道不知道你试过没有,s ...
spring security 3 扩展 HttpSessionEventPublisher 统计在线用户数 -
sxcalan:
<div class="quote_title ...
spring security 3 自定义认证,授权示例
Spring Security 3.x 出来一段时间了,跟Acegi是大不同了,与2.x的版本也有一些小小的区别,网上有一些文档,也有人翻译Spring Security 3.x的guide,但通过阅读guide,无法马上就能很容易的实现一个完整的实例。
我花了点儿时间,根据以前的实战经验,整理了一份完整的入门教程,供需要的朋友们参考。
1,建一个web project,并导入所有需要的lib,这步就不多讲了。
2,配置web.xml,使用Spring的机制装载:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext*.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <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> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> </web-app>
这个文件中的内容我相信大家都很熟悉了,不再多说了。
2,来看看applicationContext-security.xml这个配置文件,关于Spring Security的配置均在其中:
<?xml version="1.0" encoding="UTF-8"?> <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"> <http access-denied-page="/403.jsp"><!-- 当访问被拒绝时,会转到403.jsp --> <intercept-url pattern="/login.jsp" filters="none" /> <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=true" default-target-url="/index.jsp" /> <logout logout-success-url="/login.jsp" /> <http-basic /> <!-- 增加一个filter,这点与Acegi是不一样的,不能修改默认的filter了,这个filter位于FILTER_SECURITY_INTERCEPTOR之前 --> <custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="myFilter" /> </http> <!-- 一个自定义的filter,必须包含authenticationManager,accessDecisionManager,securityMetadataSource三个属性, 我们的所有控制将在这三个类中实现,解释详见具体配置 --> <beans:bean id="myFilter" class="com.robin.erp.fwk.security.MyFilterSecurityInterceptor"> <beans:property name="authenticationManager" ref="authenticationManager" /> <beans:property name="accessDecisionManager" ref="myAccessDecisionManagerBean" /> <beans:property name="securityMetadataSource" ref="securityMetadataSource" /> </beans:bean> <!-- 认证管理器,实现用户认证的入口,主要实现UserDetailsService接口即可 --> <authentication-manager alias="authenticationManager"> <authentication-provider user-service-ref="myUserDetailService"> <!-- 如果用户的密码采用加密的话,可以加点“盐” <password-encoder hash="md5" /> --> </authentication-provider> </authentication-manager> <beans:bean id="myUserDetailService" class="com.robin.erp.fwk.security.MyUserDetailService" /> <!-- 访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源 --> <beans:bean id="myAccessDecisionManagerBean" class="com.robin.erp.fwk.security.MyAccessDecisionManager"> </beans:bean> <!-- 资源源数据定义,即定义某一资源可以被哪些角色访问 --> <beans:bean id="securityMetadataSource" class="com.robin.erp.fwk.security.MyInvocationSecurityMetadataSource" /> </beans:beans>
3,来看看自定义filter的实现:
package com.example.spring.security; 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 org.springframework.security.access.SecurityMetadataSource; import org.springframework.security.access.intercept.AbstractSecurityInterceptor; import org.springframework.security.access.intercept.InterceptorStatusToken; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter { private FilterInvocationSecurityMetadataSource securityMetadataSource; // ~ Methods // ======================================================================================================== /** * Method that is actually called by the filter chain. Simply delegates to * the {@link #invoke(FilterInvocation)} method. * * @param request * the servlet request * @param response * the servlet response * @param chain * the filter chain * * @throws IOException * if the filter chain fails * @throws ServletException * if the filter chain fails */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { FilterInvocation fi = new FilterInvocation(request, response, chain); invoke(fi); } public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() { return this.securityMetadataSource; } public Class<? extends Object> getSecureObjectClass() { return FilterInvocation.class; } public void invoke(FilterInvocation fi) throws IOException, ServletException { InterceptorStatusToken token = super.beforeInvocation(fi); try { fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); } finally { super.afterInvocation(token, null); } } public SecurityMetadataSource obtainSecurityMetadataSource() { return this.securityMetadataSource; } public void setSecurityMetadataSource( FilterInvocationSecurityMetadataSource newSource) { this.securityMetadataSource = newSource; } @Override public void destroy() { } @Override public void init(FilterConfig arg0) throws ServletException { } }
最核心的代码就是invoke方法中的InterceptorStatusToken token = super.beforeInvocation(fi);这一句,即在执行doFilter之前,进行权限的检查,而具体的实现已经交给accessDecisionManager了。
4,来看看authentication-provider的实现:
package com.example.spring.security; import java.util.ArrayList; import java.util.Collection; import org.springframework.dao.DataAccessException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.GrantedAuthorityImpl; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; 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_ADMIN"); auths.add(auth2); if(username.equals("robin1")){ auths=new ArrayList<GrantedAuthority>(); GrantedAuthorityImpl auth1=new GrantedAuthorityImpl("ROLE_ROBIN"); auths.add(auth1); } // User(String username, String password, boolean enabled, boolean accountNonExpired, // boolean credentialsNonExpired, boolean accountNonLocked, Collection<GrantedAuthority> authorities) { User user = new User(username, "robin", true, true, true, true, auths); return user; } }
在这个类中,你就可以从数据库中读入用户的密码,角色信息,是否锁定,账号是否过期等,我想这么简单的代码就不再多解释了。
5,对于资源的访问权限的定义,我们通过实现FilterInvocationSecurityMetadataSource这个接口来初始化数据。
package com.example.spring.security; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; import org.springframework.security.web.util.AntUrlPathMatcher; import org.springframework.security.web.util.UrlMatcher; /** * * 此类在初始化时,应该取到所有资源及其对应角色的定义 * * @author Robin * */ public class MyInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource { private UrlMatcher urlMatcher = new AntUrlPathMatcher();; private static Map<String, Collection<ConfigAttribute>> resourceMap = null; public MyInvocationSecurityMetadataSource() { loadResourceDefine(); } private void loadResourceDefine() { resourceMap = new HashMap<String, Collection<ConfigAttribute>>(); Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>(); ConfigAttribute ca = new SecurityConfig("ROLE_ADMIN"); atts.add(ca); resourceMap.put("/index.jsp", atts); resourceMap.put("/i.jsp", atts); } // According to a URL, Find out permission configuration of this URL. public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { // guess object is a URL. String url = ((FilterInvocation)object).getRequestUrl(); Iterator<String> ite = resourceMap.keySet().iterator(); while (ite.hasNext()) { String resURL = ite.next(); if (urlMatcher.pathMatchesUrl(url, resURL)) { return resourceMap.get(resURL); } } return null; } public boolean supports(Class<?> clazz) { return true; } public Collection<ConfigAttribute> getAllConfigAttributes() { return null; } }
看看loadResourceDefine方法,我在这里,假定index.jsp和i.jsp这两个资源,需要ROLE_ADMIN角色的用户才能访问。
这个类中,还有一个最核心的地方,就是提供某个资源对应的权限定义,即getAttributes方法返回的结果。注意,我例子中使用的是AntUrlPathMatcher这个path matcher来检查URL是否与资源定义匹配,事实上你还要用正则的方式来匹配,或者自己实现一个matcher。
6,剩下的就是最终的决策了,make a decision,其实也很容易,呵呵。
package com.example.spring.security; import java.util.Collection; import java.util.Iterator; import org.springframework.security.access.AccessDecisionManager; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; public class MyAccessDecisionManager implements AccessDecisionManager { //In this method, need to compare authentication with configAttributes. // 1, A object is a URL, a filter was find permission configuration by this URL, and pass to here. // 2, Check authentication has attribute in permission configuration (configAttributes) // 3, If not match corresponding authentication, throw a AccessDeniedException. public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { if(configAttributes == null){ return ; } System.out.println(object.toString()); //object is a URL. Iterator<ConfigAttribute> ite=configAttributes.iterator(); while(ite.hasNext()){ ConfigAttribute ca=ite.next(); String needRole=((SecurityConfig)ca).getAttribute(); for(GrantedAuthority ga:authentication.getAuthorities()){ if(needRole.equals(ga.getAuthority())){ //ga is user's role. return; } } } throw new AccessDeniedException("no right"); } @Override public boolean supports(ConfigAttribute attribute) { // TODO Auto-generated method stub return true; } @Override public boolean supports(Class<?> clazz) { return true; } }在这个类中,最重要的是decide方法,如果不存在对该资源的定义,直接放行;否则,如果找到正确的角色,即认为拥有权限,并放行,否则throw new AccessDeniedException("no right");这样,就会进入上面提到的403.jsp页面
评论
就算找到的自定义过滤器的,基本配置都很复杂,运行不了,
感谢博主提供的这个资料,简洁明了,能够正常运行,再个可运行的例子前学习,事半功倍
[list] [*][url][/url] [/list]
术语又后多,看了一遍思路还是有点不清晰。
网上搜到博主的文章,豁然开朗。
Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/applicationContext-security.xml]; nested exception is java.lang.NoClassDefFoundError: org/springframework/security/web/util/AntPathRequestMatcher
谁可以帮忙解释下
jar 包冲突。楼主配置没有问题。谢谢~
Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/applicationContext-security.xml]; nested exception is java.lang.NoClassDefFoundError: org/springframework/security/web/util/AntPathRequestMatcher
谁可以帮忙解释下
相关推荐
通过学习和运行这个示例,你可以深入理解Spring Security的自定义登录认证流程,以及如何与JWT相结合,为你的Spring Boot应用提供安全的认证和授权机制。记得在实际项目中,根据具体需求调整配置和代码,确保安全...
本示例将介绍如何在Spring Security中自定义密码加密方式,以及如何处理认证成功和失败的情况。 首先,我们需要了解Spring Security的基本架构。它主要包括以下组件: 1. **Filter Security Chain**:这是Spring ...
3. **定制Filter**:在Spring Cloud Gateway中,我们可以自定义WebFlux Filter,利用Spring Security提供的API进行认证和鉴权。这通常涉及到`@PreAuthorize`和`@Secured`等注解的使用,以控制对特定路由的访问权限。...
这个压缩包文件"视频配套笔记_Spring Security OAuth2.0认证授权_v1.1.rar"包含了对这一主题的详细解释和实例代码,旨在帮助开发者深入理解和应用OAuth2.0与Spring Security的集成。 首先,Spring Security是Spring...
springsecuritytest自定义权限成功实例.rar 每个类都有相应的详细的介绍,看懂不难,当前前提还是需要对Springsecurity有些了解,自定义权限拦截器;认证管理器;用户详细信息;资源访问管理;用户信息查询等类;
6. **配置SecurityConfig**:在Spring Security的配置类中,你需要配置`http`,设置认证和授权规则,包括使用自定义的`UserDetailsService`和`AccessDecisionManager`。 7. **动态权限更新**:创建一个服务接口,...
SpringBoot+SpringSecurity整合示例代码,实现了从数据库中获取信息进行登录认证和权限认证。 本项目为idea工程,请用idea2019导入(老版应该也可以)。 本项目用户信息所需sql文件,在工程的resources文件夹下,...
在`SpringSecurity.md`和`SpringSecurity.pdf`文档中,可能包含SpringSecurity配置、自定义用户服务、授权策略等方面的代码示例。`codes`目录可能包含实际运行的项目代码,方便读者实践和理解。 8. **图笔记.draw...
在本示例中,我们将探讨如何使用Spring Security为简单的Web应用程序添加安全功能。首先,让我们了解一下Spring Security的核心概念和主要组件。 1. **核心概念**: - **Authentication(身份验证)**:确认用户的...
在Spring Security 3中,你可以看到如何配置不同的认证提供者,以及如何自定义认证流程。 2. **授权(Authorization)**:Spring Security 提供细粒度的访问控制,如基于角色的访问控制(RBAC)。在demos中,你可以...
本资源提供的"spring security3.07"教程和"contacts"示例源码,对于学习和理解Spring Security的内部工作原理及其在实际应用中的使用具有很高的价值。 首先,我们来看`tutorial`目录,这是Spring Security的教程...
Spring Security 是一个强大的安全框架,用于为Java应用提供身份验证和授权服务。在这个完整的项目实例中,我们将深入探讨Spring Security的核心概念以及如何将其应用于实际的Web应用程序开发。 首先,我们从用户、...
总结起来,Spring Security Oauth2.0专题涵盖了如何使用Spring Security构建安全的OAuth2.0认证和授权系统,包括授权服务器、资源服务器的配置,以及客户端的交互。通过学习这个专题,开发者可以有效地保护Web应用的...
Spring Security是一个强大的安全管理框架,用于处理Java应用程序的安全需求,包括认证和授权。在从Acegi安全框架转换到Spring Security 2.0时,一个重要的变化就是如何将授权信息存储从XML配置文件迁移到数据库。这...
在这个示例代码中,我们将深入探讨如何在Spring框架中集成Spring Security来实现用户登录认证与授权功能,以及如何利用RBAC(Role-Based Access Control)权限模型进行动态菜单管理。 1. **Spring Security 基础** ...
首先,Spring Security 3的核心组件包括Security Context(安全上下文)、Authentication(认证)、Authorization(授权)和Filter Chain(过滤器链)。安全上下文存储了当前用户的认证信息,如用户名、权限等。...
Spring Security 是一个强大的安全框架,用于Java和Spring应用程序。它为Web应用提供了全面的安全解决...在实际开发中,结合文件"springsecurity"中的示例代码,可以更好地理解和实践Spring Security的Cookie认证功能。
在"SpringSecurity2Demo"这个项目中,我们可以预期看到以下组成部分: 1. **配置文件**: `spring-security.xml`,这是Spring Security的核心配置文件,包含了过滤器链的配置、用户认证源、授权规则等。 2. **控制...
综上所述,"spring security用数据库的示例"是一个实际展示了如何将Spring Security与MySQL数据库整合,实现用户认证和授权的过程。通过理解并实践这个示例,开发者可以更好地掌握Spring Security的使用,提升Web...