最近学习了下spring security,现在的最新版本是spring security3.2.0。搞了好长时间看了好多博文,以及官方文档终于整出了一个小例子了。在这里帖出来,希望能给大家一个参考,并且我也可以时常回顾。
一.数据库表结构
表结构采用 用户-角色-资源的权限管理设计
运用的是MySql数据库。
1.用户表users
create table if not exists user(
id bigint not null auto_increment,
username varchar(50),
password varchar(50),
status integer,
descn varchar(200),
primary key(id)
);
2.角色表role
create table if not exists role(
id bigint not null auto_increment,
name varchar(50),
descn varchar(200),
primary key(id)
);
3.资源表resc
create table if not exists resc(
id bigint not null auto_increment,
name varchar(50),
res_type varchar(50),
res_string varchar(200),
descn varchar(200),
primary key(id)
);
4.用户角色关联表user_role
create table if not exists user_role(
user_id bigint,
role_id bigint,
foreign key(user_id) references user(id) on delete cascade on update cascade,
foreign key(role_id) references role(id) on delete cascade on update cascade
);
5.角色资源关联表resc_role
create table if not exists resc_role(
resc_id bigint,
role_id bigint,
foreign key(resc_id) references resc(id) on delete cascade on update cascade,
foreign key(role_id) references role(id) on delete cascade on update cascade
);
插入数据
insert into user(username,password,status,descn) values('admin','admin',1,'管理员');
insert into user(username,password,status,descn) values('user','user',1,'用户');
insert into role(name,descn) values('ROLE_ADMIN','管理员角色');
insert into role(name,descn) values('ROLE_USER','用户角色');
insert into resc(id,name,res_type,res_string,descn) values(1,'','URL','/admin.jsp','');
insert into resc(id,name,res_type,res_string,descn) values(2,'','URL','/**','');
insert into resc_role(resc_id,role_id) values(1,1);
insert into resc_role(resc_id,role_id) values(2,1);
insert into resc_role(resc_id,role_id) values(2,2);
insert into user_role(user_id,role_id) values(1,1);
insert into user_role(user_id,role_id) values(1,2);
insert into user_role(user_id,role_id) values(2,2);
二.系统配置文件
1)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_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>spring_security</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:/applicationContext*.xml</param-value> </context-param> <!-- 指定Log4J配置文件位置 --> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>/WEB-INF/log4j.properties</param-value> </context-param> <listener> <!-- 负责加载 log4j监听器 --> <listener-class> org.springframework.web.util.Log4jConfigListener </listener-class> </listener> <listener> <!-- 负责加载 classpath:applicationContext --> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <listener> <!-- 负责加载会话监听器事件 --> <listener-class> org.springframework.security.web.session.HttpSessionEventPublisher </listener-class> </listener> <!-- 负责加载spring security过滤器 --> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class> org.springframework.web.filter.DelegatingFilterProxy </filter-class> <init-param> <param-name>target-class</param-name> <param-value>org.springframework.security.web.FilterChainProxy</param-value> </init-param> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>setCharacterEncoding</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> </filter><!-- filtered type --> <filter-mapping> <filter-name>setCharacterEncoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 系统欢迎界面 --> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> </web-app>
该文件用于在容器启动时自动加载spring security的过滤器,用来过滤所有的用户请求
2)applicationContext-security.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- - Application context containing authentication, channel - security and web URI beans. - - Only used by "filter" artifact. - --> <b:beans xmlns="http://www.springframework.org/schema/security" xmlns:b="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 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.1.xsd"> <!-- 不要过滤图片等静态资源 --> <http pattern="/**/*.jpg" security="none"/> <http pattern="/**/*.png" security="none"/> <http pattern="/**/*.gif" security="none"/> <http pattern="/**/*.css" security="none"/> <http pattern="/**/*.js" security="none"/> <!-- 这个元素用来在你的应用程序中启用基于安全的注解 <global-method-security pre-post-annotations="enabled" access-decision-manager-ref="myAccessDecisionManager"/> --> <!-- 配置页面访问权限 --> <http auto-config='true' access-denied-page="/accessDenied.jsp"> <!-- 登陆页面和忘记密码页面不过滤 --> <intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <intercept-url pattern="/forgotpassword.jsp"/> <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=true" default-target-url="/index.jsp" always-use-default-target='true' /> <!-- "记住我"功能,采用持久化策略(将用户的登录信息存放在数据库表中) --> <remember-me data-source-ref="dataSource" /> <!-- 实现免登陆验证 --> <!-- 只能登陆一次 --> <session-management session-authentication-error-url="/402.jsp" invalid-session-url="/sessionTimeout.jsp"> <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" /> </session-management> <logout/> <!-- 增加一个自定义的filter,放在FILTER_SECURITY_INTERCEPTOR之前, 实现用户、角色、权限、资源的数据库管理。 11/3/23 --> <custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR"/> </http> <!-- 将用户信息硬编码在xml文件中 --> <!-- <authentication-manager> <authentication-provider> <user-service> <user name="admin" password="admin" authorities="ROLE_ADMIN,ROLE_USER" /> <user name="user" password="user" authorities="ROLE_USER" /> </user-service> </authentication-provider> </authentication-manager> --> <!-- 数据中查找用户 <authentication-manager alias="myAuthenticationManager"> <authentication-provider> <jdbc-user-service data-source-ref="dataSource" users-by-username-query="select username,password,status as enabled from user where username=?" authorities-by-username-query="select u.username,r.name as authority from user u join user_role ur on u.id=ur.user_id join role r on r.id=ur.role_id where u.username=?" /> </authentication-provider> </authentication-manager> --> <!-- 实现了UserDetailsService的Bean --> <!-- 注意能够为authentication-manager 设置alias别名 --> <authentication-manager alias="myAuthenticationManager"> <authentication-provider user-service-ref="myUserDetailService"> <password-encoder ref="passwordEncoder"> <salt-source user-property="username" /> </password-encoder> </authentication-provider> </authentication-manager> <!-- 一个自定义的filter,必须包含authenticationManager, accessDecisionManager,securityMetadataSource三个属性。 --> <b:bean id="myFilter" class="com.spring.security.filter.MyFilterSecurityInterceptor"> <!-- 用户拥有的权限 --> <b:property name="authenticationManager" ref="myAuthenticationManager"></b:property> <!-- 用户是否拥有所请求资源的权限 --> <b:property name="accessDecisionManager" ref="myAccessDecisionManager"></b:property> <!-- 资源与权限对应关系 --> <b:property name="securityMetadataSource" ref="mySecurityMetadataSource"></b:property> </b:bean> </b:beans>
该文件就是spring security最主要的配置文件,该文件中配置了资源的访问权限,以及用户的来源。我们看到是从UserDetailsService来获取用户信息,然后再经过自定义过滤器myFilter来实现用户权限资源的管理。myFilter依赖于这三个类,authenticationManager,accessDecisionManager,securityMetadataSource,具体这三个类的Bean在下面这个配置中有配置,这三个Bean的作用在配置文件中有说明,这里就不在赘述。我用了两个配置文件目的就是把,Bean的配置放在applicationContext-common-business.xml文件中,spring security的配置文件只有引用,这样看起来结构更加清晰。也就是说下面的配置文件类似魏生产Bean的工厂。
3)applicationContext-common-business.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- - Application context containing business beans. - - Used by all artifacts. - --> <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" 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"> <!-- 加载数据库资源文件 --> <context:property-placeholder location="classpath:dbconn.properties" /> <!-- 扫描包,应用Spring的注解 --> <context:component-scan base-package="com.spring.security.dao" /> <!-- 配置视图解析器,将ModelAndView及字符串解析为具体的页面 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:viewClass="org.springframework.web.servlet.view.JstlView" p:prefix="/WEB-INF/security/" p:suffix=".jsp" p:contentType="text/html;charset=UTF-8" /> <!-- 定义使用springframework数据源实现 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <!-- 指定连接数据库的驱动 --> <property name="driverClassName" value="${jdbc.driverClassName}" /> <!-- 指定连接数据库的URl --> <property name="url" value="${jdbc.url}" /> <!-- 指定连接数据库的用户名 --> <property name="username" value="${jdbc.username}" /> <!-- 指定连接数据库的密码 --> <property name="password" value="${jdbc.password}" /> </bean> <!-- 操作数据库的模板类 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <constructor-arg ref="dataSource"></constructor-arg> </bean> <!-- 配置userservice类 --> <bean id="myUserDetailService" class="com.spring.security.service.MyUserDetailService"> <property name="userCache" ref="userCache"/> </bean> <!-- 用户的密码加密或解密 --> <bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" /> <!-- 启用用户的缓存功能 --> <bean id="userCache" class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache"> <property name="cache" ref="userEhCache" /> </bean> <bean id="userEhCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <property name="cacheName" value="userCache" /> <property name="cacheManager" ref="cacheManager" /> </bean> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" /> <!-- 设置权限的前缀为AUTH_,而不是ROLE_。 <bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter"> <property name="rolePrefix" value="ROLE_"/> </bean> --> <!-- 访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源。 --> <bean id="myAccessDecisionManager" class="com.spring.security.MyAccessDecisionManager"> </bean> <!-- 资源源数据定义,将所有的资源和权限对应关系建立起来,即定义某一资源可以被哪些角色去访问。--> <bean id="mySecurityMetadataSource" class="com.spring.security.MyInvocationSecurityMetadataSourceService"> <constructor-arg name="resourcesDao" ref="resourcesDao"></constructor-arg> </bean> </beans>
所有Bean类的配置
4)数据库资源文件dbconn.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost/javaee
jdbc.username=root
jdbc.password=123
5)缓存配置文件ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"> <diskStore path="java.io.tmpdir"/> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /> <!-- set Category's Data expiration policies --> <cache name="org.qiujy.domain.cachedemo.Category" maxElementsInMemory="100" eternal="true" timeToIdleSeconds="0" timeToLiveSeconds="0" overflowToDisk="false" /> <!-- set Category's productes Data expiration policies --> <cache name="org.qiujy.domain.cachedemo.Category.products" maxElementsInMemory="500" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true" /> <!-- set Product's Data expiration policies --> <cache name="org.qiujy.domain.cachedemo.Product" maxElementsInMemory="500" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true" /> <!-- set Default Data expiration policies --> <cache name="org.hibernate.cache.StandardQueryCache" maxElementsInMemory="50" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="7200" overflowToDisk="true" /> <!-- set customerQueries Data expiration policies--> <cache name="myCacheRegion" maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true" /> <!-- spring security's cache config. sparta 10/6/20 10:56 --> <cache name="userCache" maxElementsInMemory="100" eternal="false" timeToIdleSeconds="600" timeToLiveSeconds="3600" overflowToDisk="true" /> <!-- spring security's acls cache config. sparta 10/6/22 15:41 --> <cache name="aclCache" maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="600" timeToLiveSeconds="3600" overflowToDisk="true" /> </ehcache>
6)myFilter过滤用户请求
(1)MyFilterSecurityInterceptor.java
public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter { //与applicationContext-security.xml里的myFilter的属性securityMetadataSource对应, //其他的两个组件,已经在AbstractSecurityInterceptor定义 @Autowired private FilterInvocationSecurityMetadataSource securityMetadataSource; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { FilterInvocation fi = new FilterInvocation(request, response, chain); invoke(fi); } public Class<? extends Object> getSecureObjectClass() { return FilterInvocation.class; } public void invoke(FilterInvocation fi) throws IOException, ServletException { // object为FilterInvocation对象 //super.beforeInvocation(fi);源码 //1.获取请求资源的权限 //执行Collection<ConfigAttribute> attributes = SecurityMetadataSource.getAttributes(object); //2.是否拥有权限 //this.accessDecisionManager.decide(authenticated, object, attributes); InterceptorStatusToken token = super.beforeInvocation(fi); try { fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); } finally { super.afterInvocation(token, null); } } @Override public SecurityMetadataSource obtainSecurityMetadataSource() { return this.securityMetadataSource; } public void setSecurityMetadataSource( FilterInvocationSecurityMetadataSource securityMetadataSource) { this.securityMetadataSource = securityMetadataSource; } public void destroy() { } public void init(FilterConfig filterconfig) throws ServletException { } }
核心的InterceptorStatusToken token = super.beforeInvocation(fi);会调用我们定义的accessDecisionManager:decide(Object object)和securityMetadataSource
:getAttributes(Object object)方法。
(2)MyInvocationSecurityMetadataSourceService.java
public class MyInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource { private ResourcesDao resourcesDao; // resourceMap及为key-url,value-Collection<ConfigAttribute>,资源权限对应Map private static Map<String, Collection<ConfigAttribute>> resourceMap = null; public MyInvocationSecurityMetadataSourceService(ResourcesDao resourcesDao) { this.resourcesDao = resourcesDao; System.out.println("加载MyInvocationSecurityMetadataSourceService..." + resourcesDao); loadResourceDefine(); } // 加载所有资源与权限的关系 private void loadResourceDefine() { if (resourceMap == null) { resourceMap = new HashMap<String, Collection<ConfigAttribute>>(); List<Resource> resources = resourcesDao.findAll(); //加载资源对应的权限 for (Resource resource : resources) { Collection<ConfigAttribute> auths = resourcesDao .loadRoleByResource(resource.getRes_string()); System.out.println("权限=" + auths); resourceMap.put(resource.getRes_string(), auths); } } } //加载所有资源与权限的关系 @Override public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { // object是一个URL,被用户请求的url String requestUrl = ((FilterInvocation) object).getRequestUrl(); System.out.println("requestUrl is " + requestUrl); int firstQuestionMarkIndex = requestUrl.indexOf("?"); if (firstQuestionMarkIndex != -1) { requestUrl = requestUrl.substring(0, firstQuestionMarkIndex); } if (resourceMap == null) { loadResourceDefine(); } // Iterator<String> ite = resourceMap.keySet().iterator(); while (ite.hasNext()) { String resURL = ite.next(); if (resURL.equals(requestUrl)) { return resourceMap.get(resURL); } } return null; } @Override public boolean supports(Class<?> arg0) { // TODO Auto-generated method stub return true; } @Override public Collection<ConfigAttribute> getAllConfigAttributes() { // TODO Auto-generated method stub return null; } }
(3)MyAccessDecisionManager.java
public class MyAccessDecisionManager implements AccessDecisionManager { @Override public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { if (configAttributes == null) { return; } //所请求的资源拥有的权限(一个资源对多个权限) Iterator<ConfigAttribute> ite = configAttributes.iterator(); while (ite.hasNext()) { ConfigAttribute ca = ite.next(); //访问所请求资源所需要的权限 String needRole = ((SecurityConfig) ca).getAttribute(); System.out.println("needRole is " + needRole); // ga 为用户所被赋予的权限。 needRole 为访问相应的资源应该具有的权限。 for (GrantedAuthority ga : authentication.getAuthorities()) { if (needRole.trim().equals(ga.getAuthority().trim())) { return; } } } //没有权限 throw new AccessDeniedException("没有权限访问!"); } @Override public boolean supports(ConfigAttribute arg0) { // TODO Auto-generated method stub return true; } @Override public boolean supports(Class<?> arg0) { // TODO Auto-generated method stub return true; } }
(4)MyUserDetailService.java
/* * 该类的主要作用是为Spring Security提供一个经过用户认证后的UserDetails。 *该UserDetails包括用户名、密码、是否可用、是否过期等信息。 */ public class MyUserDetailService implements UserDetailsService { @Autowired private UserInfoDao userInfoDao; @Autowired private UserCache userCache; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { System.out.println("username is :" + username); Users user = null; try { user = this.userInfoDao.findByName(username); System.out.println(user); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 获得用户权限 Collection<GrantedAuthority> auths = userInfoDao .loadUserAuthorityByName(username); boolean enables = true; // 账户过期否 boolean accountNonExpired = true; // 证书过期否 boolean credentialsNonExpired = true; // 账户锁定否 boolean accountNonLocked = true; // 封装成spring security的user User userdetail = new User(username, user.getPassword(), enables, accountNonExpired, credentialsNonExpired, accountNonLocked, auths); for (GrantedAuthority s : auths) { s.getAuthority(); } System.out.println(auths); return userdetail; } public UserInfoDao getUserInfoDao() { return userInfoDao; } public void setUserInfoDao(UserInfoDao userInfoDao) { this.userInfoDao = userInfoDao; } //设置用户缓存功能。 public UserCache getUserCache() { return userCache; } public void setUserCache(UserCache userCache) { this.userCache = userCache; } }
7)Dao组件
1)ResourcesDao.java
@Repository public class ResourcesDao { @Autowired private JdbcTemplate jdbcTemplate; private static final Log log = LogFactory.getLog(UserInfoDao.class); public ResourcesDao() { System.out.println("加载ResourcesDao..." + jdbcTemplate); } public List<Resource> findAll() { try { List<Resource> resourceList = new ArrayList<Resource>(); List<Map<String, Object>> resources = jdbcTemplate .queryForList("select * from resc"); for (Map<String, Object> map : resources) { Resource r = new Resource(); r.setId(Integer.valueOf(map.get("id").toString())); r.setName(map.get("name").toString()); r.setRes_type(map.get("res_type").toString()); r.setRes_string(map.get("res_string").toString()); r.setDescn(map.get("descn").toString()); resourceList.add(r); } return resourceList; } catch (RuntimeException re) { log.error("find all resource failed " + re); throw re; } } // 加载资源与对应的权限 public Collection<ConfigAttribute> loadRoleByResource(String url) { try { String sql = "select ro.name as role,re.res_string as url " + "from role ro join resc_role rr on ro.id=rr.role_id " + "join resc re on re.id=rr.resc_id " + "where re.res_string='" + url + "'"; List<Map<String, Object>> authList = jdbcTemplate.queryForList(sql); Collection<ConfigAttribute> auths = new ArrayList<ConfigAttribute>(); for(Map<String, Object> map:authList){ ConfigAttribute auth = new SecurityConfig(map.get("role").toString()); auths.add(auth); } return auths; } catch (RuntimeException re) { log.error("find roles by url failed " + re); throw re; } } }
2)UserInfoDao.java
@SuppressWarnings("deprecation") @Repository public class UserInfoDao { @Autowired private JdbcTemplate jdbcTemplate; private static final Log log = LogFactory.getLog(UserInfoDao.class); public UserInfoDao(){ loadSource(); System.out.println("加载UserInfoDao..." + jdbcTemplate); } public Users findByName(String username) throws SQLException { String sql = "select * from user where username='" + username + "'"; RowMapper<Users> mapper = new RowMapper<Users>() { @Override public Users mapRow(ResultSet rs, int rowNum) throws SQLException { Users user = new Users(); user.setId((int) rs.getLong("id")); user.setUsername(rs.getString("username")); user.setPassword(rs.getString("password")); user.setStatus(rs.getInt("status")); user.setDescribtion(rs.getString("descn")); return user; } }; System.out.println("怎么没有呢?"); Users user = jdbcTemplate.queryForObject(sql, mapper); return user; } // 通过用户名获得权限集合 public Collection<GrantedAuthority> loadUserAuthorityByName(String username) { try{ List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>(); List<String> authsList = loadUserAuthorities(username); for(String roleName:authsList){ GrantedAuthorityImpl authority = new GrantedAuthorityImpl(roleName); auths.add(authority); } return auths; }catch(RuntimeException re){ log.error("" + re); throw re; } } // 获取权限列表 public List<String> loadUserAuthorities(String username) { try { String sql = "select r.name as authority " + "from user u join user_role ur on u.id=ur.user_id " + "join role r on r.id=ur.role_id " + "where u.username='" + username + "'"; List<Map<String, Object>> list = jdbcTemplate.queryForList(sql); List<String> roles = new ArrayList<>(); for (Map<String, Object> map : list) { roles.add((String) map.get("authority")); } return roles; } catch (RuntimeException re) { log.error("find by authorities by username failed." + re); throw re; } } private void loadSource(){ System.out.println("加载资源"); } }
还有一些Domain类在此就省略不提了。以上就是笔者经过一个星期搞出来的,总算是能用了。
三.说明
1)容器启动(MySecurityMetadataSource:loadResourceDefine加载系统资源与权限列表)
2)用户发出请求
3)过滤器拦截(MySecurityFilter:doFilter)
4)取得请求资源所需权限(MySecurityMetadataSource:getAttributes)
5)匹配用户拥有权限和请求权限(MyAccessDecisionManager:decide),如果用户没有相应的权限,
执行第6步,否则执行第7步。
6)登录
7)验证并授权(MyUserDetailService:loadUserByUsername)
8)重复4,5
注:该流程为复制其他博客主的
四.结束
最后衷心的希望大家在程序员这条路上走得更远,更久,为我国软件行业做出一些贡献。
相关推荐
spring-security-core-3.2.0.RELEASE.jar,spring-security-web-3.2.0.RELEASE.jar,spring-security-taglibs-3.2.0.RELEASE.jar,spring-security-config-3.2.0.RELEASE.jar,spring-security-acl-3.2.0.RELEASE....
Spring Security 的前身是 Acegi Security ,是 Spring 项目组中用来提供安全认证服务的框架。 Spring Security 为基于J2EE企业应用软件提供了全面安全服务。特别是使用领先的J2EE解决方案-Spring框架开发的企业...
security3.2最新版本配置,资源里面有4个小项目,都是利用maven搭建的,先在mysql中新建一个security空数据库,不要建表,然后只要在myeclipse导入,运行maven install,在连网状态下就会自动下载jar包了,无需再去...
Spring Security的配置通常是基于XML或Java配置,3.2.0.M1可能进一步提升了Java配置的易用性,简化了复杂的安全设置。此外,对于多环境部署的应用,Spring Security还支持动态加载配置,使得开发和生产环境的配置...
10. **安全性**: Spring Security(前身为Acegi)是Spring框架的安全组件,提供认证、授权等功能,为Web应用提供全面的安全解决方案。 总结,Spring-3.2.0.jar作为SSH中的关键部分,为开发者提供了强大的框架支持,...
在安全方面,Spring Security 3.2.0与Spring 3.2.0框架兼容,提供了一套完整的安全解决方案,包括认证、授权和访问控制。开发者可以利用这些组件轻松地实现用户身份验证和权限管理。 总的来说,Spring 3.2.0在很多...
- **版本编号**: 明确了 Spring Security 版本的命名规则,例如 `3.2.0.M2` 中的 `.M2` 表示这是一个里程碑版本(Milestone)。 - **获取 Spring Security**: 提供了多种方式来获取 Spring Security,如通过 Maven ...
8. **Security**:Spring Security(以前称为Acegi Security)提供了全面的安全管理框架,包括认证、授权、CSRF保护、访问控制等,适用于Web和非Web应用。 9. **WebSocket Support**:Spring 3.2开始支持WebSocket...
- 利用Spring Security提供安全控制,保护应用程序免受攻击。 四、总结 Spring 3.2.0是Spring框架发展历程中的一个重要节点,它在提升开发效率、优化性能和增强功能方面做出了显著贡献。开发者可以借助这一版本,更...
Spring Security与Spring MVC的集成更加紧密,提供了更多安全相关的注解和配置选项。 11. **性能优化**: Spring MVC 3.2.0在性能方面也有所提升,例如请求映射速度的加快和内存使用的优化。 这些是Spring MVC ...
- **其他工具**:还包括了一些其他工具和库,如Spring Security、Spring Batch等。 #### 四、如何使用Spring 3.2.0.RELEASE整合包 1. **下载整合包**:可以通过官方提供的链接下载spring-framework-3.2.0.RELEASE-...
Spring Security Reference Ben Alex Luke Taylor Rob Winch version 3.2.0.RELEASE
在"spring-security-learning1"这个示例项目中,你可以期待找到一个运行的Spring Boot应用,其中包含了一个简单的REST API,该API使用Spring Security进行身份验证和授权,并利用JsonView控制JSON响应的可见性。...
下面是 Spring Security 3.2.0.RELEASE 的依赖项配置: ```xml <groupId>org.springframework.security <artifactId>spring-security-web <version>3.2.0.RELEASE <groupId>org.springframework....
"Spring Security 国际化及 UserCache 配置和使用" Spring Security 是一个功能强大且灵活的安全框架,它提供了许多实用的特性来帮助开发者保护 Web 应用程序。今天,我们将探讨 Spring Security 中的国际化和 ...
13. **安全性**:Spring Security是Spring的一个模块,3.2版本提供了更丰富的安全控制,包括认证、授权和CSRF保护等。 在下载的"spring3.2"压缩包中,通常包含所有必需的Spring 3.2核心库以及相关模块的jar文件,...
以上就是基于Spring MVC 4.0、Spring Security 3.2和MyBatis的简单搭建过程。你可以通过security01这个文件来查看具体的代码实现,包括相关的XML配置文件和Java类。在实际项目中,你需要根据需求调整安全策略,例如...
spring-beans-3.2.0.RELEASE-sources.jar spring-context-3.1.3.RELEASE-sources.jar spring-context-support-3.1.3.RELEASE-sources.jar spring-core-2.5.6-sources.jar spring-core-3.2.0.RELEASE-sources.jar ...
7. **Spring Security**:原名为Acegi Security,提供认证、授权和安全控制,保护Web应用免受各种攻击。 8. **Spring Integration**:提供企业服务集成(ESB)功能,包括消息传递、文件处理和网络协议支持,帮助...
虽然不在Spring.jar内,但Spring Boot是基于Spring框架的快速开发工具,它默认配置了许多常见设置,使得创建独立的、生产级别的Spring应用变得简单。 10. **Spring Security**: Spring Security是一个强大的安全...