最近拿出几天看了下Spring Security2,Spring Security是从Acige发展而来,网上和基本参考书上找到的例子大多是Acige的,Spring Security的不多。
1.准备
必须先理顺以下几个Spring Security核心类的作用和关系
- Authentication :认证信息
- AuthenticationManager 认证管理器
- AuthenticationProvider 验证数据提供器
- UserDetailsService:用户信息服务接口
- AccessDecisionManager 授权器
常用过滤器
AuthenticationProcessingFilter 处理form登陆的过滤器,与form登陆有关的所有操作都是在此进行的。
LogoutFilter 只处理注销请求,默认为/j_spring_security_logout。
FilterSecurityInterceptor URL拦截过滤器
2.实体类
RBAC 模型 ,一共五张表:用户、用户角色、角色、角色权限、权限,本例使用Hibernate映射。
三个实体类:User、Role、Resource。
User 继承UserDetails接口,并实现到Role的单向多对多映射
public class User implements UserDetails{
private static final long serialVersionUID = -1689430377678136883L;
private Integer id;
private String name;
private String password;
private Integer disabled;
private Set<Role> roles = new HashSet<Role>(0);
//单向多对多映射,用户登陆验证时可以获得权限,非延迟加载
@Override
public GrantedAuthority[] getAuthorities() { //获得用户的角色列表,GrantedAuthorityImpl存储的是Role名称
List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>(roles.size());
for(Role role : this.roles) {
grantedAuthorities.add(new GrantedAuthorityImpl(role.getName()));
}
return grantedAuthorities.toArray(new GrantedAuthority[roles.size()]);
}
Role比较简单,POJO类
public class Role implements java.io.Serializable {
private static final long serialVersionUID = -953612771016471024L;
private Integer id;
private String name;
}
Resouce类需要单向关联Role
public class Resource implements java.io.Serializable {
private static final long serialVersionUID = 5604673911728289859L;
private Integer id;
private String type;//资源类型,例如URL
private String value;
private Set<Role> roles = new HashSet<Role>(0);//Hibernate配置
}
3.DAO层代码
两个DAO类,UserDao和ResourceDao
UserDao类
public interface UserDao {
public User loadUserByUsername(String username);//通过用户名获得User
}
ResourceDao类
public interface ResourceDao {
public List<Resource> loadResourceByType(String type);
//根据类型获得Resource队列,例如获得URL资源 loadResourceByType("URL")
}
4.Security Support支持类
UserDetailsServiceImpl继承org.springframework.security.userdetails.UserDetails接口,只需要实现一个方法
public class UserDetailsServiceImpl implements UserDetailsService {
private UserDao userDao;//spring注入
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
return userDao.loadUserByUsername(username);
}//没有用户时抛出UsernameNotFoundException异常
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
URLDefinitionSourceFactory的目的是构造一个DefaultFilterInvocationDefinitionSource类
public class URLDefinitionSourceFactory implements FactoryBean{
/**
* 这个类的目的就是构建一个DefaultFilterInvocationDefinitionSource类,
* DefaultFilterInvocationDefinitionSource是默认提供的FilterInvocationDefinitionSource实现类,省力
* 本类继承FactoryBean给DefaultFilterInvocationDefinitionSource构造的两个参数赋值
* 关于FactoryBean接口的使用,Spring新手自己查下
*/
private ResourceDao resourceDao;//Spring注入
//返回DefaultFilterInvocationDefinitionSource构造参数之一
private UrlMatcher getUrlMatcher() {
return new AntUrlPathMatcher();//这个比RegexUrlPathMatcher简单,所以用这个,不求甚解
}
//返回DefaultFilterInvocationDefinitionSource构造参数之二
private LinkedHashMap<RequestKey, ConfigAttributeDefinition> getRequestMap() throws Exception {
List<Resource> resources= resourceDao.loadResourceByType("URL");//取所有URL资源
LinkedHashMap<RequestKey, ConfigAttributeDefinition> requestMap = new LinkedHashMap<RequestKey,ConfigAttributeDefinition>();
//这个Map看起来比较唬人,把握两点:key为URL地址,value为允许访问该URL的角色S,URL与ROLE是多对多的关系
for (Resource resource : resources) {
Set<Role> roles = resource.getRoles();
int i = roles.size();
String[] rolenames = new String[i];//将该URL的的角色名称转化为一个String数组
for (Role role : roles) {
i--;
rolenames[i] = role.getName();
}
requestMap.put(new RequestKey(resource.getValue()), new ConfigAttributeDefinition(rolenames));
//key为URL地址,用RequestKey封装
//value为ConfigAttributeDefinition,可以理解为一个数组,该数组中存放ConfigAttribute
//每个ConfigAttribute封装一个角色名称
}
return requestMap;
}
@Override
public Object getObject() throws Exception {//工厂方法
LinkedHashMap<RequestKey, ConfigAttributeDefinition> requestMap = getRequestMap();//取参数一
UrlMatcher matcher = getUrlMatcher(); //取参数二
DefaultFilterInvocationDefinitionSource definitionSource = new DefaultFilterInvocationDefinitionSource(
matcher, requestMap); //构造完成
return definitionSource;
}
@Override
public Class<DefaultFilterInvocationDefinitionSource> getObjectType() {//FactoryBean接口方法
return DefaultFilterInvocationDefinitionSource.class;
}
@Override
public boolean isSingleton() {//FactoryBean接口方法
return true;
}
public void setResourceDao(ResourceDao resourceDao) {
this.resourceDao = resourceDao;
}
}
5.applicationContext-security.xml配置文件
<?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-2.5.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.6.xsd">
<!-- 支持类之一 userDatailsService接口实现-->
<beans:bean id="userDatailsService" class="com.kaqike.security.security.support.UserDetailsServiceImpl">
<beans:property name="userDao" ref="userDao"/>
</beans:bean>
<!-- 支持类之二 DefaultFilterInvocationDefinitionSource工厂类-->
<beans:bean id="URLDefinitionSourceFactory" class="com.kaqike.security.security.URLDefinitionSourceFactory" >
<beans:property name="resourceDao" ref="resourceDao"/>
</beans:bean>
<!--http 是Spring Security的关键配置,各个拦截器在此实现 -->
<http auto-config='true'>
<concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="true"/>
</http>
<!-- userDatailsService配置,使用md5验证 -->
<authentication-provider user-service-ref="userDatailsService">
<password-encoder hash="md5"></password-encoder>
</authentication-provider>
<authentication-manager alias="authenticationManager" />
<!--授权器 -->
<beans:bean id="accessDecisionManager" class="org.springframework.security.vote.AffirmativeBased">
<beans:property name="allowIfAllAbstainDecisions" value="false"/>
<beans:property name="decisionVoters">
<beans:list>
<beans:bean class="org.springframework.security.vote.RoleVoter"/>
<beans:bean class="org.springframework.security.vote.AuthenticatedVoter"/>
</beans:list>
</beans:property>
</beans:bean>
<!--URL资源拦截器 -->
<beans:bean id="URLSecurityInterceptor" class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="accessDecisionManager" ref="accessDecisionManager"/>
<beans:property name="objectDefinitionSource" ref="URLDefinitionSourceFactory" />
<beans:property name="observeOncePerRequest" value="false" />
<custom-filter after="LAST" />
</beans:bean>
<!-- 登录成功监听器 -->
<beans:bean class="com.kaqike.security.listener.LoginSuccessListener"></beans:bean>
<!-- 认证日志监听器 -->
<beans:bean id="loggerListener" class="org.springframework.security.event.authentication.LoggerListener" />
</beans:beans>
6.其他
pom.xml文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>kaqike</groupId>
<artifactId>spring_security</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring_security</name>
<description>first spring security app</description>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>${spring.version}</version>
<type>jar</type>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</e
分享到:
相关推荐
在这个例子中,包含的所有jar包很可能是Spring Security框架所需的基本依赖,包括Spring Security的核心库、Web支持、OAuth2模块等。这些库将帮助开发者集成Spring Security到他们的应用中,提供安全功能。 在实际...
这个“Spring Security 小例子(1)”很可能是针对初学者或者那些希望快速了解该框架基本用法的开发者设计的。在本篇文章中,我们将深入探讨Spring Security的核心概念和关键组件,以及如何在实际项目中应用它们。 ...
通过这个Spring Security实战例子,你可以深入了解Spring Security的配置、认证和授权机制,以及如何与数据库集成。实践是最好的老师,动手完成这四个小项目将有助于巩固理解,并为你在实际项目中应用Spring ...
Spring Security支持基于表单的身份验证,也支持OAuth2和其他现代认证协议。 免登录功能,即Remember-Me服务,允许用户在一段时间内无须反复登录。这通过RememberMeServices接口实现,通常使用Token-Based策略,将...
通过分析`samples`目录下的子文件,我们可以看到不同类型的Spring Security示例,例如基本的认证和授权示例、OAuth2集成、JWT(JSON Web Tokens)身份验证等。每个子项目都包含了完整的源代码和配置文件,便于开发者...
Spring Security 是一个强大的安全框架,主要用于Java应用的安全管理。它为Web应用程序提供了全面的身份验证、授权和访问控制功能。在Spring Security 3版本中,这个框架进一步完善了其特性和性能,使其成为开发者...
SSH + Spring Security3.2例子
6. **无状态认证(Token-based Authentication)**:尽管例子没有明确提到,但SpringSecurity也支持JWT(JSON Web Tokens)或OAuth2等无状态认证方式,这在现代API开发中非常常见。 7. **CSRF防护**:Spring...
在这个例子中,我们将深入探讨如何使用Spring Security进行认证和授权,并结合数据库操作进行动态配置。 首先,Spring Security的核心概念包括认证(Authentication)和授权(Authorization)。认证是确认用户身份...
总的来说,这个"Spring Security例子源代码"是一个实践性的学习资源,涵盖了从用户登录、权限控制到数据库验证的整个安全流程。通过深入研究这个示例,开发者可以更好地理解和应用Spring Security,从而提升其构建...
### Spring Security 4 登录示例详解 #### 一、概览 在现代Web应用开发中,安全性至关重要。Spring Security 是一款广泛使用的安全框架,它为基于Spring的应用提供了全面的安全解决方案,包括认证、授权等核心功能...
在这个小例子中,我们将探讨如何创建并集成自定义过滤器,以及它在Spring Security中的工作原理。 首先,我们需要理解Spring Security的基础架构。它基于过滤器链模型,其中每个过滤器负责处理请求的不同方面。默认...
这个"spring-Security简单例子"旨在展示如何在项目中配置和使用Spring Security进行用户登录和访问权限控制的基本操作。下面将详细阐述Spring Security的核心概念、配置步骤以及实现原理。 1. **核心概念** - **...
Spring Security ACL(Access Control List)是Spring Security框架的一个高级特性,用于实现细粒度的访问控制,特别是针对数据对象的安全管理。在这个实例中,我们将会深入探讨如何在Spring Security框架下,结合...
demos中可能包含如何在Spring MVC应用中配置和使用Spring Security的例子。 8. **自定义配置**:Spring Security 的强大之处在于其高度可定制性。通过自定义`UserDetailsService`,你可以实现自己的用户存储逻辑。...
这个压缩包文件"springsecurity"很可能包含了一个Spring Security的示例项目,让我们来深入探讨一下Spring Security的相关知识点。 1. **Spring Security架构**: Spring Security的核心组件包括过滤器链、安全性...
总的来说,这个例子提供了一个使用Spring Security 3.0.4的ACL特性的实践指南,帮助开发者实现对象级别的细粒度权限控制。通过理解和应用这些概念,你可以为你的应用程序构建出强大且灵活的安全体系。
标题 "s2sh+springSecurity的注解配置例子" 提供了一个关于整合Spring Security与Struts 2(S2)和Hibernate(SH)框架的注解配置实践的线索。这通常涉及到在Java web应用程序中创建一个安全的环境,通过利用Spring ...
简单springsecurity3.0的例子 做了详细注释,另外集成了tiles 和conversion插件,希望对你有帮助,里面有不对的地方请给我留言,我加你QQ一起讨论..注:我是通过maven管理的,如果你不是的话可能无法运行起来,只能看代码