`

spring security 3.0x 使用

阅读更多

  本文是一个简单的基于用户,角色,权限的spring security应用。

 

   使用步骤:

   1 在web.xml引入如下配置:

     

	<listener>  
	    <listener-class>
	    org.springframework.security.web.session.HttpSessionEventPublisher
	    </listener-class>  
	</listener> 

    

   2 增加spring security配置文件spring_security.xml(名称可以自己取):

    

<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"
 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="false" access-denied-page="/accessDenied.jsp">
	  <!-- 不要过滤图片等静态资源,其中**代表可以跨越目录,*不可以跨越目录。
	  <intercept-url pattern="/**/*.jpg" filters="none" />
	  <intercept-url pattern="/**/*.png" filters="none" />
	  <intercept-url pattern="/**/*.gif" filters="none" />
	  <intercept-url pattern="/**/*.css" filters="none" />
	  <intercept-url pattern="/**/*.js" filters="none" /> -->
	  <!-- 登录页面和忘记密码页面不过滤 -->
	  <intercept-url pattern="/login.jsp" filters="none" />
	  <intercept-url pattern="/jsp/forgotpassword.jsp"   filters="none" />
	  <!-- ROLE_ENTER_ORDINARY_PAGE, -->
	  <intercept-url pattern="/index.jsp"   access="ROLE_ENTER_ORDINARY_PAGE, ROLE_ENTER_HIGH_LEVEL_PAGE" /> 
	
	  
	  <!-- 检测失效的sessionId,超时时定位到另外一个URL, 防止固化session攻击 -->
	  <!-- <session-management invalid-session-url="/timeout.jsp" session-fixation-protection="migrateSession"> -->
	  <session-management session-authentication-strategy-ref="sessionAuthenticationStrategy">
   	  </session-management>
   	  
   	  <custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" /> 
	  
	  <form-login login-page="/login.jsp" authentication-failure-url="/loginError.jsp"   default-target-url="/index.jsp"/>
	  <logout invalidate-session="true" logout-success-url="/login.jsp"/>
	  <http-basic/>
	  <!-- <remember-me user-service-ref="userService"/> -->
	  <remember-me user-service-ref="userService" data-source-ref="myDataSource"/>
	  <anonymous/>
	 </http>

	 <!-- 注意能够为authentication-manager 设置alias别名  -->
	 <authentication-manager alias="authenticationManager">
	      <!-- <authentication-provider user-service-ref="userDetailsManager"> -->
	      <authentication-provider user-service-ref="userService">
      		<password-encoder hash="md5">
      			<salt-source user-property="username"/>
      		</password-encoder>
	           <!-- <password-encoder ref="passwordEncoder"> -->
	                <!-- 用户名做为盐值 -->
	                <!--<salt-source user-property="username" />
	           </password-encoder>-->
	      </authentication-provider>
	 </authentication-manager>
	 

	 
</b:beans>

    

   3 在web.xml中添加spring security配置的引用

    

  	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring/spring.xml, /WEB-INF/spring/spring_security.xml</param-value>
	</context-param>

 

   4 创建用户,角色,权限表

   

--创建表t_user
create table t_user(
id int PRIMARY key auto_increment,
username VARCHAR(50) not null,
password varchar(50) not NULL
);
--插入数据
insert into t_user values(null, 'user', '47a733d60998c719cf3526ae7d106d13');
insert into t_user values(null, 'admin', 'ceb4f32325eda6142bd65215f4c0f371');

--创建表t_Role
create table 	(
id int PRIMARY key auto_increment,
name VARCHAR(50) not null
);
--插入数据
insert into t_role values(null, '普通用户');
insert into t_role values(null, '高级用户');


--创建表t_Perm
create table t_perm(
id int PRIMARY key auto_increment,
name VARCHAR(50) not null
);

--插入数据
insert into t_perm values(null, 'ROLE_ENTER_ORDINARY_PAGE');
insert into t_perm values(null, 'ROLE_ENTER_HIGH_LEVEL_PAGE');



--创建表角色--人员的关联关系(多对多)
create table t_user_role(
id int primary key auto_increment,
userid int not null, 
roleid int not null
);

--创建约束
alter table t_user_role
add CONSTRAINT fk_userid foreign key (userid)
REFERENCES t_user (id);

alter table t_user_role
add CONSTRAINT fk_roleid foreign key (roleid)
REFERENCES t_role (id);

--插入数据
insert into t_user_role
select null,a.id, b.id   from t_user a, t_role b 
where a.username = 'user' and b.name='普通用户';

insert into t_user_role
select null,a.id, b.id   from t_user a, t_role b 
where a.username = 'admin' and b.name='高级用户';




--创建角色--权限关联关系表(多对多)
create table t_role_perm(
id int primary key auto_increment,
permid int not null, 
roleid int not null
);


--创建约束
alter table t_role_perm
add CONSTRAINT fk_perm_permid foreign key (permid)
REFERENCES t_perm (id);

alter table t_role_perm
add CONSTRAINT fk_perm_roleid foreign key (roleid)
REFERENCES t_role (id);

--插入数据
insert into t_role_perm
select null,a.id, b.id   from t_role a, t_perm b 
where a.name = '普通用户' and b.name='ENTER_ORDINARY_PAGE';

insert into t_role_perm
select null,a.id, b.id   from t_role a, t_perm b 
where a.name = '高级用户' and b.name='ROLE_ENTER_HIGH_LEVEL_PAGE';

 

  5 在spring security的配置文件中,有如下配置:

	 <authentication-manager alias="authenticationManager">
	      <!-- <authentication-provider user-service-ref="userDetailsManager"> -->
	      <authentication-provider user-service-ref="userService">
      		<password-encoder hash="md5">
      			<salt-source user-property="username"/>
      		</password-encoder>
	           <!-- <password-encoder ref="passwordEncoder"> -->
	                <!-- 用户名做为盐值 -->
	                <!--<salt-source user-property="username" />
	           </password-encoder>-->
	      </authentication-provider>
	 </authentication-manager>

   对于authentication-provider的配置有很多种,可以使用jdbc的配置,也可以使用service的,在此,我们使用service配置来实现用户的登陆和授权验证

   

  6 在spring的配置文件中注册要使用的service

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
		xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context" 
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/aop 
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/context 
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">

  <!-- 配置占位符 -->
  <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">    
    <property name="location" >   
        <value>WEB-INF/config/jdbc.properties</value>  
    </property>  
  </bean>   
  
  <!-- 数据源 -->
  <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${JDBC.DRIVERNAME}"/>
    <property name="url" value="${JDBC.URL}"/>
    <property name="username" value="${JDBC.USERNAME}"/>
    <property name="password" value="${JDBC.PASSWORD}"/>
  </bean>
    

  <bean id="mySessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="myDataSource"/>
      
    <property name="packagesToScan">
    	<list>
    		<value>main.model</value>
    	</list>
    </property>
    <property name="hibernateProperties">
      <value>
        hibernate.dialect=org.hibernate.dialect.MySQLDialect
        hibernate.show_sql=true
        hibernate.hbm2ddl.auto=update
        hibernate.cache.provider_class=org.hibernate.cache.NoCacheProvider
      </value>
    </property>
  </bean>  
  <bean id="userDaoImpl" class="main.daoImpl.UserDaoImpl">
  	<property name="sessionFactory" ref="mySessionFactory"></property>
  </bean>
  
  
   <bean id="passwordEncoder"
  	class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />
  	
  	 <!-- 用户详细信息管理 : 数据源、用户缓存、启用用户组功能。  -->
	 <bean id="userDetailsManager"
	  class="org.springframework.security.provisioning.JdbcUserDetailsManager">
	  <property name="dataSource" ref="myDataSource" />
	  <!--  <property name="userCache" ref="userCache" /> -->
	 </bean> 
	 
	 <bean id="userService" class="main.service.UserService">
	 	<property name="userDaoImpl" ref="userDaoImpl"/>
	 </bean>

	<!-- spring security session-manager -->
	<bean id="concurrencyFilter"  
	    class="org.springframework.security.web.session.ConcurrentSessionFilter">  
	    <property name="sessionRegistry" ref="sessionRegistry" />  
	    <property name="expiredUrl" value="/timeout.jsp" /> 
	</bean> 

	<bean id="sessionAuthenticationStrategy"  
    	class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">  
	    <constructor-arg type="org.springframework.security.core.session.SessionRegistry" index="0"
	        ref="sessionRegistry" />  
	    <property name="maximumSessions" value="1" />  
	    <property name="exceptionIfMaximumExceeded" value="true"></property>
	</bean>  
	
	<bean id="sessionRegistry"  
	    class="org.springframework.security.core.session.SessionRegistryImpl" />
	 
</beans>

   

  7 使用UserDetailsService做验证和授权,首先要实现UserDetails接口,以把我们从数据库查询到的数据包装后供spring security使用

package main.security;

import java.util.ArrayList;
import java.util.Collection;

import main.model.Perm;
import main.model.User;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.userdetails.UserDetails;

@SuppressWarnings("serial")
public class UserDetail implements UserDetails {
	
	public UserDetail(User user) {
		this.username = user.getUsername();
		this.password = user.getPassword();
		this.authorities = new ArrayList<GrantedAuthority>();
		for (Perm perm : user.getPerms()) {
			this.authorities.add(new GrantedAuthorityImpl(perm.getName()));
		}
	}
	
	private String username;
	
	private String password;
	
	private Collection<GrantedAuthority> authorities;

	public Collection<GrantedAuthority> getAuthorities() {
		return this.authorities;
	}

	public String getPassword() {
		return this.password;
	}

	public String getUsername() {
		return this.username;
	}

	public boolean isAccountNonExpired() {
		return true;
	}

	public boolean isAccountNonLocked() {
		return true;
	}

	public boolean isCredentialsNonExpired() {
		return true;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof UserDetail) {
			UserDetail another = (UserDetail)obj;
			return this.getUsername().equals(another.getUsername());
		}
		return super.equals(obj);
	}

	@Override
	public int hashCode() {
		return this.getUsername().hashCode();
	}

	public boolean isEnabled() {
		return true;
	}
	

}

   在UserDetails中可以获取到当前用户的权限

 

  8 实现UserDetailsService接口,实现验证和授权

   

package main.service;

import java.util.List;

import main.daoImpl.UserDaoImpl;
import main.model.Perm;
import main.model.User;
import main.security.UserDetail;

import org.springframework.dao.DataAccessException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

public class UserService implements UserDetailsService {

	private UserDaoImpl userDaoImpl;

	public void setUserDaoImpl(UserDaoImpl userDaoImpl) {
		this.userDaoImpl = userDaoImpl;
	}

	public UserDetails loadUserByUsername(String username)
    	throws UsernameNotFoundException, DataAccessException {
		User user = this.userDaoImpl.findByName(username);
		if (user == null) {
			throw new UsernameNotFoundException("用户名错误!");
		}
		//从数据库中获取当前用户拥有权限
		List<Perm> permList = this.userDaoImpl.listPermByUser(user);
		user.setPerms(permList);
		return new UserDetail(user);
	}

}

   看到loadUserByUsername方法时,你可能会疑问,只是在验证用户名是否正确,并没验证密码,是的,此方法只验证用户名,返回值类为UserRetails,该接口有个getPassword()方法,实现该接口时只要把用户的密码在此方法中返回就行了,密码的验证由spring security 自己完成的

 

 到此就是一个完整的基于用户,角色,权限管理的spring security项目了,有很多的具体细节没有讲到,我在此附上源码,有兴趣的可以自己跑跑一下!

 

 

分享到:
评论

相关推荐

    SpringSecurity3.0.x官方参考文档(英文+中文双解版)

    **Spring Security 3.0.x 知识点详解** Spring Security 是一个强大的和高度可定制的身份验证和访问控制框架,广泛应用于Java企业级应用的安全管理。Spring Security 3.0.x 版本是该框架的一个重要里程碑,它提供了...

    spring security3.0所需要的最精简的jar包

    在3.0版本中,Spring Security 已经相当成熟,提供了丰富的特性来保障应用的安全性。 在开始使用Spring Security时,了解并正确引入必要的jar包是至关重要的。以下是你提供的压缩包文件中的关键组件: 1. **spring...

    spring security 3.0x remember-me 免登陆

    在Spring Security 3.0x中,配置"remember-me"服务主要包括以下几个步骤: 1. **依赖配置**:首先,确保你的项目依赖于Spring Security 3.0.x版本。在你的pom.xml或build.gradle文件中添加相应的依赖。 2. **配置...

    thymeleaf-extras-springsecurity-3.0-master.zip

    thymeleaf-extras-springsecurity3 for integration with Spring Security 3.x thymeleaf-extras-springsecurity4 for integration with Spring Security 4.x Current versions: Version 3.0.2.RELEASE - for ...

    spring security3.1.3 和 spring security3.0.0

    如果你的项目已经使用了Spring 3.0.x,那么3.0.0版本可能是更兼容的选择;而3.1.3则提供了更多的改进和修复,如果兼容性不是问题,推荐使用这个版本。在提供的压缩包中,`spring-security-3.0.0.RELEASE.zip`包含了...

    Spring Security 3.x 官网文档 chm格式 (中文版)

    通过学习《Spring Security 3.x 官方文档》,开发者可以掌握如何在Spring应用中正确地配置和使用Spring Security,确保应用的安全性和稳定性。这份文档详尽地阐述了各种安全策略和技术,对于提升Java Web开发者的...

    spring security 3

    这部分涉及到了实际的SpringSecurity配置,如元素和元素的使用,用于定义安全规则和URL的访问权限。其中元素的pattern属性用于指定要拦截的URL模式,而access属性则用来指定哪些角色可以访问匹配的URL。此外,文档...

    spring-security文档和jar包

    《spring-security3.0.rar》是一个包含Spring Security 3.0版本库的压缩文件,用户可以将其解压到项目的lib目录下,以便在项目中引用。3.0版本虽然较旧,但仍能提供基本的安全功能,如HTTP安全、基于角色的访问控制...

    Spring_Security3中文指南.pdf

    ### Spring Security 3.0 入门与核心概念详解 #### 一、Spring Security简介 Spring Security 是一款功能强大且高度可定制的应用安全框架,它为基于 Java 的应用程序提供了全面的安全服务。尤其对于那些采用 ...

    Springboot整合Spring security+Oauth2+JWT搭建认证服务器,网关,微服务之间权限认证及授权

    Springboot整合Spring security+Oauth2+JWT搭建认证服务器,网关,微服务之间权限认证及授权。 OAuth2是一个关于授权的开放标准,核心思路是通过各类认证手段(具体什么手段OAuth2不关心)认证用户身份,并颁发...

    thymeleaf-extras-springsecurity:适用于Spring Security 3.x和4.x的Thymeleaf“ extras”集成模块

    该存储库包含3个项目: thymeleaf-extras-springsecurity3与Spring Security 3.x集成thymeleaf-extras-springsecurity4用于与Spring Security 4.x集成thymeleaf-extras-springsecurity5与Spring Security 5.x集成...

    springsecurity.pdf

    Acegi Security在Spring Security 2.0版本之前被广泛使用,它为Web应用程序提供了细粒度的安全控制功能。通过Acegi Security,开发者可以轻松地实现基于角色的安全性,确保只有经过验证的用户才能访问特定资源。 ##...

    Spring 3.x企业应用开发实战

    结合《Spring MVC 3.0实战指南》,本书旨在帮助读者掌握Spring 3.x版本的核心特性和最佳实践,以便在现代Java应用开发中实现高效、可维护的解决方案。 Spring框架是Java领域中最广泛使用的轻量级框架之一,它提供了...

    spring-security-reference-4.0.1

    自 Spring Security 3.0 版本以来,该框架经历了多次重大改进和技术迭代。4.0 版本更是引入了许多新特性,进一步提升了安全性的同时简化了配置过程。 ##### 1.3 发行编号 Spring Security 4.0.1 是在 4.0 版本基础...

Global site tag (gtag.js) - Google Analytics