- 浏览: 60963 次
- 性别:
- 来自: 北京
最新评论
-
com0606:
jerrynbcl 写道我也是碰到这问题,在控制层加事务的注解 ...
springmvc的controller中使用@Transactional无效 -
jerrynbcl:
我也是碰到这问题,在控制层加事务的注解没有生效,如果不加ser ...
springmvc的controller中使用@Transactional无效 -
laowoof:
为啥我看不懂
关于spring security的一个小例子 -
mojunbin:
感觉还可以
关于spring security的一个小例子 -
guxinghanshe:
很不错的例子,一步一步来,基本功能已经实现
关于spring security的一个小例子
最近学习了一下spring mvc,顺便就把spring security给看了看。看的官方文档,并借鉴了网上别人的学习经验,看了些源码,大致上对其工作原理有了个了解。把自己弄的做个记录,以后用得着了再翻翻
用的是spring3.0.5,lib里面需要导入的包都移去了
先贴个项目的结构
与spring相关的一些jar包
这个例子中只对url的权限进行控制,没有用spring的method权限控制。
感觉spring mvc确实比较轻巧,不像struts2包装了太多的东西。不过在这里并没有对spring mvc过多研究,更多的是关于spring security的。
web.xml里面的配置如下
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:/applicationContext.xml /WEB-INF/applicationContext-security.xml </param-value> </context-param> <!-- 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> <!-- 配置UTF-8编码过滤 --> <filter> <filter-name>Set Character Encoding</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> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <!-- Spring MVC的配置 --> <!-- 默认所对应的配置文件是WEB-INF下的{servlet-name}-servlet.xml --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <listener> <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class> </listener> <!-- 默认的spring配置文件是在WEB-INF下的applicationContext.xml--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- spring security监听session --> <listener> <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class> </listener> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
springmvc-servlet.xml
此文件名根据web.xml中的配置命名
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd" default-autowire="byName"> <!-- 扫描所有的controller --> <context:component-scan base-package="cn.henu.springmvc.control" /> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"></property> <property name="suffix" value=".jsp"></property> </bean> </beans>
applicationContext-security.xml
这是专门用来配置spring security的,这里没有用默认的拦截器链,并使用了一个自定义的Filter。使用自定义的Filter需要继承AbstractSecurityInterceptor,并实现两个接口FilterInvocationSecurityMetadataSource,
AccessDecisionManager。如果想使用自定义的用户数据源还需要实现UserDetailsService接口
<?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 auto-config="true" access-denied-page="/error.jsp"> <!-- 不过滤图片等静态资源,其中**代表可以跨越目录,*不可以跨越目录--> <intercept-url pattern="/image/**" filters="none" /> <form-login login-page="/login.jsp" login-processing-url="/login" authentication-success-handler-ref="authenticationDispatcher" authentication-failure-url="/login.jsp?error=-1" /> <!-- login-processing-url默认是/j_spring_security_check --> <logout logout-url="/logout" logout-success-url="/" /> <!-- 此配置debug时会报logout-success-url项路径未找到的错,可无视之 --> <session-management session-fixation-protection="none"> <concurrency-control max-sessions="1" expired-url="/login.jsp"/> </session-management> <custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR" /> </http> <!-- 一个自定义的Filter,必须包含以下三项配置 --> <beans:bean id="myFilter" class="cn.henu.spring.security.FilterSecurityInterceptor"> <beans:property name="authenticationManager" ref="authenticationManager" /> <beans:property name="accessDecisionManager" ref="accessDecisionManager" /> <beans:property name="securityMetadataSource" ref="securityMetadataSource" /> </beans:bean> <!-- 资源源数据定义,将所有的资源和权限对应关系建立起来,即定义某一资源可以被哪些角色访问 --> <beans:bean id="securityMetadataSource" init-method="loadResourceDefine" class="cn.henu.spring.security.InvocationSecurityMetadataSourceService"> <beans:property name="interceptUrl"> <beans:props> <beans:prop key="/admin/**">admin</beans:prop> <beans:prop key="/user/**">user,admin</beans:prop> </beans:props> </beans:property> </beans:bean> <!-- 访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源 --> <beans:bean id="accessDecisionManager" class="cn.henu.spring.security.AccessDecisionSecurityManager"> </beans:bean> <authentication-manager alias="authenticationManager"> <authentication-provider user-service-ref="userDetailService"> </authentication-provider> </authentication-manager> <!-- 查询用户信息 --> <beans:bean id="userDetailService" class="cn.henu.spring.security.UserDetailService"> </beans:bean> <!-- 自定义一个角色控制器,根据不同角色登录到不同页面 --> <beans:bean id="authenticationDispatcher" class="cn.henu.spring.security.SuccessHandler"> <beans:property name="authDispatcherMap"> <beans:props> <beans:prop key="admin">/admin/index.jsp</beans:prop> <beans:prop key="user">/user/index.jsp</beans:prop> </beans:props> </beans:property> </beans:bean> </beans:beans>
以下是三个实现类:
FilterSecurityInterceptor.java
package cn.henu.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.apache.log4j.Logger; 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 FilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter { private static final Logger logger = Logger.getLogger(FilterSecurityInterceptor.class); private FilterInvocationSecurityMetadataSource securityMetadataSource; public void init(FilterConfig arg0) throws ServletException { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if(logger.isInfoEnabled()) { logger.info("doFilter~start"); } FilterInvocation invocation = new FilterInvocation(request, response, chain); invoke(invocation); if(logger.isInfoEnabled()) { logger.info("doFilter~end"); } } public void invoke(FilterInvocation invocation)throws IOException, ServletException { InterceptorStatusToken token = super.beforeInvocation(invocation); try { invocation.getChain().doFilter(invocation.getRequest(), invocation.getResponse()); } catch (Exception e) { e.printStackTrace(); } finally { super.afterInvocation(token, null); } } public void destroy() { } @Override public SecurityMetadataSource obtainSecurityMetadataSource() { return this.securityMetadataSource; } @Override public Class<? extends Object> getSecureObjectClass() { return FilterInvocation.class; } public void setSecurityMetadataSource( FilterInvocationSecurityMetadataSource securityMetadataSource) { this.securityMetadataSource = securityMetadataSource; } }
InvocationSecurityMetadataSourceService.java
package cn.henu.spring.security; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.apache.log4j.Logger; 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; public class InvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource { private static final Logger logger = Logger.getLogger(InvocationSecurityMetadataSourceService.class); private UrlMatcher urlMatcher = new AntUrlPathMatcher(); private static Map<String, Collection<ConfigAttribute>> resourceMap; //用以接收配置文件中的对应关系,类似于http配置项中的<intercept-url /> private Map<String, String> interceptUrl; @SuppressWarnings("unused") private void loadResourceDefine() { resourceMap = new HashMap<String, Collection<ConfigAttribute>>(); if(interceptUrl==null) { if(logger.isInfoEnabled()) { logger.info("未建立任何对应关系"); } return; } //从配置文件中读取对应关系 for(Map.Entry<String, String> entry : interceptUrl.entrySet()) { Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>(); ConfigAttribute ca = null; if(entry.getValue()==null) { continue; } for(String configAttribute : entry.getValue().split(",")) { ca = new SecurityConfig(configAttribute); atts.add(ca); } resourceMap.put(entry.getKey(), atts); } /* //通过硬编码设置,resouce和role Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>(); ConfigAttribute ca = new SecurityConfig("admin"); atts.add(ca); resourceMap.put("/admin/**", atts); ca = new SecurityConfig("user"); atts = new ArrayList<ConfigAttribute>(); atts.add(ca); resourceMap.put("/user/**", atts); */ if(logger.isInfoEnabled()) { logger.info("资源和权限对应关系读取完成!"); } } public Collection<ConfigAttribute> getAllConfigAttributes() { return null; } public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { String resUrl = ((FilterInvocation) object).getRequestUrl(); Iterator<String> iterator = resourceMap.keySet().iterator(); while (iterator.hasNext()) { String url = iterator.next(); if(urlMatcher.pathMatchesUrl(url, resUrl)) { Collection<ConfigAttribute> col = resourceMap.get(url); if(logger.isInfoEnabled()) { logger.info("请求的url与资源中的url相匹配."); } return col; } } return null; } public boolean supports(Class<?> clazz) { return true; } public void setInterceptUrl(Map<String, String> interceptUrl) { this.interceptUrl = interceptUrl; } }
AccessDecisionSecurityManager.java
package cn.henu.spring.security; import java.util.Collection; import java.util.Iterator; import org.apache.log4j.Logger; 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 AccessDecisionSecurityManager implements AccessDecisionManager { private static final Logger logger = Logger.getLogger(AccessDecisionManager.class); public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> collection) throws AccessDeniedException, InsufficientAuthenticationException { if(logger.isInfoEnabled()) { logger.debug("decide(Authentication, Object," + "Collection<ConfigAttribute>)~start"); } if(collection==null) { if(logger.isInfoEnabled()) { logger.info("decide(Authentication, Object," + "Collection<ConfigAttribute>)~end"); } return; } if(logger.isInfoEnabled()) { logger.info("正在访问的url是: "+object.toString()); } Iterator<ConfigAttribute> iterator = collection.iterator(); while (iterator.hasNext()) { ConfigAttribute ca = iterator.next(); String needRole = ((SecurityConfig) ca).getAttribute(); for (GrantedAuthority ga : authentication.getAuthorities()) { if(needRole.equals(ga.getAuthority())) { if(logger.isInfoEnabled()) { logger.info("用户角色" + needRole+" 与 "+ "权限" + ga.getAuthority()+" 相匹配."); logger.info("decide(Authentication, Object," + "Collection<ConfigAttribute>)~end"); } return; } } } throw new AccessDeniedException("没有权限"); } public boolean supports(ConfigAttribute arg0) { return true; } public boolean supports(Class<?> arg0) { return true; } }
使用自定义数据源
UserDetailService.java
package cn.henu.spring.security; import java.util.ArrayList; import java.util.Collection; import javax.annotation.Resource; 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; import cn.henu.service.UserService; public class UserDetailService implements UserDetailsService { @Resource private UserService userService; public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { Collection<GrantedAuthority> auths = new ArrayList<GrantedAuthority>(); String password = null; cn.henu.model.User newUser = userService.getObject(username); if(newUser==null) { throw new UsernameNotFoundException("用户 "+username+" 不存在"); } password = newUser.getPassword(); GrantedAuthorityImpl grantedAuthorityImpl = new GrantedAuthorityImpl(newUser.getRole()); auths.add(grantedAuthorityImpl); /* * 此处若用继承自UserDetails的User需要覆写其中的equals和hashCode方法, * 否则无法通过session-management控制max-sessions="1" */ return new User(username, password, true, true, true, true, auths); } }
如果希望不同用户登录成功之后进入不同页面,可以实现AuthenticationSuccessHandler接口,并在<form-login />中配置authentication-success-handler-ref项
SuccessHandler.java
package cn.henu.spring.security; import java.io.IOException; import java.util.Collection; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.GrantedAuthorityImpl; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.util.Assert; public class SuccessHandler implements AuthenticationSuccessHandler { private Map<String, String> map; private static final Logger logger = Logger.getLogger(SuccessHandler.class); public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { Assert.notNull(map, "AuthInterceptMap is null!"); String url = ""; Collection<GrantedAuthority> autCollection = authentication.getAuthorities(); if(autCollection.isEmpty()) { return; } GrantedAuthority[] ga = new GrantedAuthorityImpl[]{}; url = map.get(autCollection.toArray(ga)[0].toString()); //取第一角色权限 if(logger.isInfoEnabled()) { logger.info("登陆成功,跳转至"+url); } response.sendRedirect(request.getContextPath() + url); } public void setAuthDispatcherMap(Map<String, String> map) { this.map = map; } }
关于hibernate的一些配置和spring mvc相关的文件就不贴出来了。
其实spring security中一些对于权限的管理自己写一个过滤器完全可以实现,但是毕竟不如spring security的工作做的全面
- SpringMVC.zip (45.4 KB)
- 下载次数: 230
评论
发表评论
-
侃侃tomcat的bio,nio
2016-10-19 17:25 782对于这2种io以及在socket的应用不作描述,主要探究一 ... -
关于synchronized和lock
2016-01-20 17:26 494目前在Java中存在两种锁机制:synchronized和 ... -
springmvc的controller中使用@Transactional无效
2012-04-23 21:00 13118最近看mybatis的时候做了一个练习,但是进行事务处理的时候 ... -
how tomcat works——(5)容器
2011-05-16 14:26 1414初次翻译东西,英语不好,想着顺便训练下。翻译东西真的不是一件好 ... -
多用户并发访问Servlet与线程同步
2011-04-09 17:53 9833Servlet容器为了响应多个用户同时访问一个Servlet的 ... -
Java反射机制和类的封装性
2011-04-08 21:07 2305以下是一个关于反射是否破坏了类的封装性的测试 实体类 p ...
相关推荐
Spring Security 是一个强大的且高度可定制的身份验证和访问控制框架,它是Java开发人员在构建安全Web应用程序时的首选工具。这个“Spring Security 小例子(1)”很可能是针对初学者或者那些希望快速了解该框架基本...
Spring Security 是一个强大的且高度可定制的身份验证和访问控制框架,用于保护Java应用程序。这个框架提供了全面的安全解决方案,包括Web安全、方法级访问控制、密码管理以及会话管理。在这个"Spring Security的...
Spring Security 是一个强大的安全框架,用于为Java应用提供身份验证和授权服务。在这个"spring security2 例子"中,我们可能会探索如何利用Spring Security 2版本来保护我们的应用程序。Spring Security 2虽然已经...
Spring Security 是一个强大的且高度可定制的身份验证和访问控制框架,专为 Java 应用程序设计。它提供了全面的安全解决方案,包括登录、授权、权限管理等,广泛应用于Web应用程序和企业级系统。在本实战例子中,...
Spring Security 是一个强大的安全框架,用于为Java应用提供身份验证和授权服务。在这个完整的项目实例中,我们将深入探讨Spring Security的核心概念以及如何将其应用于实际的Web应用程序开发。 首先,我们从用户、...
Spring Security 是一个强大的安全框架,用于为Java应用提供安全控制,包括身份验证、授权和访问控制。在Spring Security 4中,我们可以通过自定义过滤器来扩展其功能,以满足特定的安全需求。在这个小例子中,我们...
Spring Security 是一个强大的安全框架,主要用于Java应用的安全管理,它为Web和企业级应用程序提供了全面的身份验证、授权和访问控制功能。在这个“Spring Security Maven 示例”中,我们可以通过官方提供的Maven...
这个“SpringSecurity官网修改例子 tutorial”提供了一个可以直接运行的示例项目,无需连接到数据库,这使得开发者能够快速理解和学习SpringSecurity的核心概念。 在SpringSecurity中,主要涉及以下几个关键知识点...
Spring Security 是一个强大的安全框架,主要用于Java应用的安全管理。它为Web应用程序提供了全面的身份验证、授权和访问控制功能。在Spring Security 3版本中,这个框架进一步完善了其特性和性能,使其成为开发者...
Spring Security 是一个强大的安全框架,主要用于Java应用的安全管理,它为Spring Boot提供了全面的安全服务。在本示例中,我们将探讨如何将Spring Security与Spring Boot整合,以实现一个基础的用户登录验证和权限...
标题 "s2sh+springSecurity的注解配置例子" 提供了一个关于整合Spring Security与Struts 2(S2)和Hibernate(SH)框架的注解配置实践的线索。这通常涉及到在Java web应用程序中创建一个安全的环境,通过利用Spring ...
总的来说,这个例子提供了一个使用Spring Security 3.0.4的ACL特性的实践指南,帮助开发者实现对象级别的细粒度权限控制。通过理解和应用这些概念,你可以为你的应用程序构建出强大且灵活的安全体系。
本文将通过一个具体的示例——Spring MVC + Spring Security 4 的整合登录实例来深入探讨Spring Security的使用方法。 #### 二、核心配置类:`SecurityConfig` 在本例中,我们使用的是Java Config的方式进行Spring...
Spring Security 是一个强大的和高度可定制的身份验证和访问控制框架,用于Java应用程序。它提供了全面的安全解决方案,包括用户认证、权限授权、会话管理、CSRF防护以及基于HTTP的访问控制。在这个例子中,我们将...
总的来说,这个"Spring Security例子源代码"是一个实践性的学习资源,涵盖了从用户登录、权限控制到数据库验证的整个安全流程。通过深入研究这个示例,开发者可以更好地理解和应用Spring Security,从而提升其构建...
本文将深入探讨Spring Cloud Security在用户身份认证和权限管理方面的应用,以"spring-cloud-security例子"为基础,结合spring-boot-security-master项目,详细阐述其核心概念和技术实现。 一、用户身份认证 1.1 ...
SSH + Spring Security3.2例子
在IT行业中,Spring Security是一个广泛使用的安全框架,它为Java应用程序提供了全面的安全管理解决方案。本文将深入探讨如何在Spring Security中实现IP过滤器,以便控制访问应用的客户端IP地址。 首先,我们需要...
在这个"spring-Security简单例子"中,我们可能会看到一个基础的配置文件,一个登录表单,以及一些简单的URL访问控制规则。通过理解这些核心概念和步骤,开发者可以进一步扩展Spring Security以满足更复杂的安全需求...
Spring Security 是一个强大的、高度可定制的身份验证和访问控制框架,广泛用于Java应用程序的安全管理,尤其是在Spring生态体系中。"Spring Security 3 Demos" 是一套针对Spring Security 3 版本的示例项目,旨在...