`

SpringSecurity初体验

阅读更多
        刚刚接触SpringSecurity,根据网上的教程自己试了一下,记录下来以供日后查看。

参考文档

这里主要的参考文档是Spring Security的自带的Reference。网络上有一个它的中文翻译,地址如下:
[url]http://www.family168.com/tutorial/springsecurity/html/springsecurity.html
[/url]

Spring Security基本配置
1. 在web.xml文件中加入Filter声明
<!-- Spring security Filter -->
<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>


注意,springSecurityFilterChain这个名称是由命名空间默认创建的用于处理web安全的一个内部的bean的id。所以你在你的Spring配置文件中,不应该再使用这个id作为你的bean。

2. 使用最小的<http>配置
<http auto-config='true'>  
    <intercept-url pattern="/**" access="ROLE_USER" />  
</http>


3. 配置UserDetailsService来指定用户和权限
<authentication-provider>  
    <user-service>  
      <user name="downpour" password="downpour" authorities="ROLE_USER, ROLE_ADMIN" />  
      <user name="robbin" password="robbin" authorities="ROLE_USER" />  
      <user name="QuakeWang" password="QuakeWang" authorities="ROLE_ADMIN" />  
    </user-service>  
</authentication-provider>


security的XML头为
<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.4.xsd">



如此一番折腾之后,启动服务器,输入地址,系统会自动转向到SS自已的登陆界面,需要当前用户输入用户名、密码进行登陆验证。

接下来通过一个实例来加深理解
创建用户表:
CREATE TABLE [dbo].[USERS](
	[ID] [numeric](18, 0) PRIMARY KEY IDENTITY(1,1) NOT NULL,
	[NAME] [varchar](255) NULL,
	[PASSWORD] [varchar](255) NULL,
	[DISABLED] [varchar](255) NULL)


创建权限表:
CREATE TABLE [dbo].[ROLE](
	[ID] [numeric](18, 0) PRIMARY KEY IDENTITY(1,1) NOT NULL,
	[NAME] [varchar](255) NULL,
	[DESCRIPTION] [varchar](255) NULL)


创建用户权限关系表:
CREATE TABLE [dbo].[USER_ROLE](
	[USER_ID] [numeric](18, 0) NOT NULL,
	[ROLE_ID] [numeric](18, 0) NOT NULL);
ALTER TABLE [dbo].[USER_ROLE]  WITH CHECK ADD FOREIGN KEY([ROLE_ID])
REFERENCES [dbo].[ROLE] ([ID]);
ALTER TABLE [dbo].[USER_ROLE]  WITH CHECK ADD FOREIGN KEY([USER_ID])
REFERENCES [dbo].[USERS] ([ID]);


建立表相对应的bean
其中Users表需要进行修改一下
/**
 * 
 */
package admin.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Transient;

import org.apache.commons.lang.StringUtils;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Proxy;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.userdetails.UserDetails;

/**
 * @author Downpour
 *
 */
@Entity
@Proxy(lazy = false)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Users implements UserDetails {
	
	private static final long serialVersionUID = 8026813053768023527L;

    @Id
	@GeneratedValue
	private Integer id;
	
	private String name;
	
	private String password;
	
	private boolean disabled;
	
	@ManyToMany(targetEntity = Role.class, fetch = FetchType.EAGER)
    @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
	private Set<Role> roles;
	
	@Transient
	private Map<String, List<Resource>> roleResources;
	
	/**
	 * The default constructor
	 */
	public Users() {
		
	}

	/* (non-Javadoc)
	 * @see org.springframework.security.userdetails.UserDetails#getAuthorities()
	 */
	public GrantedAuthority[] getAuthorities() {
		List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>(roles.size());
    	for(Role role : roles) {
    		grantedAuthorities.add(new GrantedAuthorityImpl(role.getName()));
    	}
        return grantedAuthorities.toArray(new GrantedAuthority[roles.size()]);
	}
	
	/**
	 * Returns the authorites string
	 * 
	 * eg. 
	 *    downpour --- ROLE_ADMIN,ROLE_USER
	 *    robbin --- ROLE_ADMIN
	 * 
	 * @return
	 */
	public String getAuthoritiesString() {
	    List<String> authorities = new ArrayList<String>();
	    for(GrantedAuthority authority : this.getAuthorities()) {
	        authorities.add(authority.getAuthority());
	    }
	    return StringUtils.join(authorities, ",");
	}

	/* (non-Javadoc)
	 * @see org.springframework.security.userdetails.UserDetails#getPassword()
	 */
	public String getPassword() {
		return password;
	}

	/* (non-Javadoc)
	 * @see org.springframework.security.userdetails.UserDetails#getUsername()
	 */
	public String getUsername() {
		return name;
	}

	/* (non-Javadoc)
	 * @see org.springframework.security.userdetails.UserDetails#isAccountNonExpired()
	 */
	public boolean isAccountNonExpired() {
		return true;
	}

	/* (non-Javadoc)
	 * @see org.springframework.security.userdetails.UserDetails#isAccountNonLocked()
	 */
	public boolean isAccountNonLocked() {
		return true;
	}

	/* (non-Javadoc)
	 * @see org.springframework.security.userdetails.UserDetails#isCredentialsNonExpired()
	 */
	public boolean isCredentialsNonExpired() {
		return true;
	}

	/* (non-Javadoc)
	 * @see org.springframework.security.userdetails.UserDetails#isEnabled()
	 */
	public boolean isEnabled() {
		return !disabled;
	}

	/**
	 * @return the id
	 */
	public Integer getId() {
		return id;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @return the disabled
	 */
	public boolean isDisabled() {
		return disabled;
	}

	/**
	 * @return the roles
	 */
	public Set<Role> getRoles() {
		return roles;
	}

	/**
	 * @return the roleResources
	 */
	public Map<String, List<Resource>> getRoleResources() {
		// init roleResources for the first time
		if(this.roleResources == null) {
			
			this.roleResources = new HashMap<String, List<Resource>>();
			
			for(Role role : this.roles) {
				String roleName = role.getName();
				Set<Resource> resources = role.getResources();
				for(Resource resource : resources) {
					String key = roleName + "_" + resource.getType();
					if(!this.roleResources.containsKey(key)) {
						this.roleResources.put(key, new ArrayList<Resource>());
					}
					this.roleResources.get(key).add(resource);					
				}
			}
			
		}
		return this.roleResources;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(Integer id) {
		this.id = id;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @param password the password to set
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * @param disabled the disabled to set
	 */
	public void setDisabled(boolean disabled) {
		this.disabled = disabled;
	}

	/**
	 * @param roles the roles to set
	 */
	public void setRoles(Set<Role> roles) {
		this.roles = roles;
	}
	
}


就是继承了UserDetails接口,UserDetails接口就是SS用来进行用户验证用的接口,这个接口的方法都很好实现,只有getAuthorities需要处理一下,用来返回用户的所有权限。

有了用户信息的实体存在了,当然还需要操作这些信息的实体,SS提供了另外一个接口UserDetailsService,这个接口只有一个方法loadUserByUsername(String s),用于根据用户名获取用户信息,我们编写一个SecurityManager类实现之
/**
 * 
 */
package admin.impl;

import java.util.List;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.security.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import admin.interfaces.SecurityManager;
import admin.model.Users;

/**
 * @author 
 */
@Service("securityManager")
public class SecurityManagerImpl extends HibernateDaoSupport implements UserDetailsService, SecurityManager {
    
    /**
     * Init sessionFactory here because the annotation of Spring 2.5 can not support override inject
     *  
     * @param sessionFactory
     */
    @Autowired
    public void init(SessionFactory sessionFactory) {
        super.setSessionFactory(sessionFactory);
    }
    
    /* (non-Javadoc)
     * @see org.springframework.security.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
     */
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException {
        List<Users> users = getHibernateTemplate().find("FROM Users user WHERE user.name = ? AND user.disabled = false", userName);
        if(users.isEmpty()) {
            throw new UsernameNotFoundException("User " + userName + " has no GrantedAuthority");
        }
        return users.get(0);
    }   
}


调整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.4.xsd">
	
	<http access-denied-page="/403.jsp">  
		<intercept-url pattern="/login.jsp*" filters="none"/>
    	<intercept-url pattern="/**" access="ROLE_USER" />
    	<form-login login-page="/login.jsp" default-target-url="/admin/hello.jsp" always-use-default-target="true" authentication-failure-url="/login.jsp?error=true"/>
	    <logout logout-success-url="/login.jsp"/>  
	</http> 
	
	<authentication-manager alias="authenticationManager"/>
	
	<authentication-provider user-service-ref="securityManager">
		<password-encoder hash="md5"/>
	</authentication-provider>
</beans:beans> 


看得出来就是把authentication-provider的策略从XML里直接写死,改成了使用数据库来进行管理,而中间的操作类就是自定义的实现了UserDetailsService接口的securityManager类。一切似乎明朗起来。
分享到:
评论

相关推荐

    SpringSecurity初体验之手动配置用户名密码

    此文章是记录博主在学习springsecurity时的笔记 第一步 创建一个SpringBoot工程,勾选上需要的依赖。 第二步 创建一个名为securityconfig的配置类,该类基础了父类WebSecurityConfigurerAdapter(提供用于创建...

    从入门到高级实战-深度探索SpringSecurity安全框架视频.zip

    02.Spring Security 初体验 03.基于内存定义 Spring Security 用户 04.Spring Security 自定义表单登录 05.Spring Security 登录表单配置细节 06.Spring Security 表单登录源码 07.Spring Security 中的 JSON 交互 ...

    spring-security初体验demo

    这个"spring-security初体验demo"很可能是为了帮助初学者理解如何在实际项目中集成和配置Spring Security。下面,我们将深入探讨Spring Security的核心概念、工作原理以及如何通过实践来设置一个简单的示例。 ...

    详解SpringBoot+SpringSecurity+jwt整合及初体验

    SpringBoot+SpringSecurity+jwt整合详解 SpringBoot是当前最流行的Java框架之一,它提供了便捷的方式来构建基于Web的应用程序。然而,在构建Web应用程序时,安全性是不可忽视的重要方面。因此,本文将详细介绍如何...

    springsecuritytotp:使用Google Authenticator登录Spring Security(基于时间的一次性密码算法,TOTP)

    在本文中,我们将深入探讨如何使用Google Authenticator与Spring Security集成,实现基于时间的一次性密码算法(TOTP)的双因素身份验证。这是一项重要的安全措施,它为应用程序提供了额外的安全层,防止未经授权的...

    Acegi(四):Acegi初体验及初解剖

    在初体验部分,博主可能会介绍如何设置Acegi以保护一个简单的Spring应用,包括配置Spring XML文件、定义安全拦截器(filter)以及创建用户凭证。 身份验证过程通常涉及用户登录,Acegi支持多种认证方式,如基于表单...

    univers-2.0:EE JavaEE,Vaadin框架,Spring,Spring Security,Spring Boot,Maven,JPA,JBoss-WildFly

    Spring Security是Spring框架的一个子项目,专注于安全控制,如身份验证、授权等,为Web应用提供了强大的安全保障。 Spring Boot是Spring框架的扩展,旨在简化Spring应用的初始设置和常规配置。它通过“起步依赖”...

    xfire 初体验

    《Xfire初体验:探索Java Web服务框架》 在IT领域,Web服务是软件系统间交互的重要手段,而Xfire则是早期流行的一款基于Java的Web服务框架。它为开发者提供了构建和消费Web服务的便捷工具,尤其在XML-RPC和SOAP协议...

    spring开发指南

    《Spring开发指南》是一本专为Java开发者设计的详尽教程,无论你是初涉Spring框架的新手,还是希望深入理解并提升Spring应用的老手,它都能提供宝贵的指导。Spring是Java领域中最流行的轻量级开源框架之一,以其模块...

    基于Spring Boot的个人博客系统设计与实现

    Spring Security可以用来实现用户认证和授权,确保博客系统的安全性。对于文章的分类与标签,可以使用树形结构或标签云来展示,提供灵活的文章组织方式。评论系统可以通过Ajax异步技术实现实时更新,提高用户体验。...

    128元尚硅谷Java视频教程_Spring Boot视频教程(下)整合篇

    4、尚硅谷-SpringBoot高级-缓存-@Cacheable初体验 5、尚硅谷-SpringBoot高级-缓存-缓存工作原理&@Cacheable运行流程 6、尚硅谷-SpringBoot高级-缓存-@Cacheable其他属性 7、尚硅谷-SpringBoot高级-缓存-@CachePut 8...

    初涉StrutsMenu

    StrutsMenu可以与权限框架结合,如Spring Security或Apache Shiro,实现根据用户角色动态调整菜单的功能。 5. **源码阅读与定制**:作为开源工具,StrutsMenu的源码提供了学习和扩展的可能性。开发者可以根据自身...

    springboot015基于SpringBoot的在线视频教育平台的设计与实现.zip

    SpringBoot集成了Spring Security,可以轻松实现用户的登录、注册、权限控制等功能。通过OAuth2或JWT(JSON Web Tokens)进行身份验证,确保用户数据的安全。 6. **支付集成** 如果平台包含付费课程,可以集成第...

    基于Vue+ElementUI+Springboot前后端分离网约车预约系统设计

    Spring Boot与Spring Security集成,可以轻松地实现权限管理,确保系统安全。对于网约车预约系统,这尤为重要,因为需要区分乘客、司机和管理员的权限,例如,乘客只能预约车辆,司机可以接受或拒绝订单,而管理员则...

    springboot企业客户信息反馈平台设计与实现.docx

    - **后端**:采用Spring Boot框架简化开发过程,集成Spring Security实现安全控制。 - **数据库**:MySQL作为关系型数据库存储数据。 ##### 开发流程 1. **环境搭建**:配置开发环境,安装必要的软件工具。 2. **...

    Java项目之springboot应急救援物资管理系统(源码)

    SpringBoot结合Spring Security或者Apache Shiro等安全框架,可以实现用户登录验证、角色权限划分,保证只有授权的用户才能访问特定资源,从而保障系统的安全性。 在界面设计方面,系统通常采用前后端分离的方式,...

    基于ssm+jsp的家居商城系统源码数据库.zip

    首先,系统设计之初,开发者通过Spring框架的IoC(Inversion of Control)和DI(Dependency Injection)特性,实现了松耦合的组件化设计,使得代码更易于维护和扩展。Spring的AOP(Aspect-Oriented Programming)...

    JavaEye新闻月刊 - 2010年01月 - 总第23期.pdf

    Spring Security,一个强大的安全框架,发布了新版本,提供了更全面的安全服务,包括身份验证、授权和加密等功能,为Java开发者提供了更强大的安全保护。 13. **ICEpdf 4.0发布,开源的Java PDF引擎**: ICEpdf是...

    基于ssm+vue的招聘系统.zip

    安全性方面,SSM框架本身就提供了权限管理和安全控制的功能,如Spring Security或Shiro,可以用来实现用户的登录验证、权限控制等。同时,前端Vue.js也需要考虑XSS、CSRF等安全问题,通过合理的数据绑定和验证机制来...

    Java精品项目第41期毕业设计管理系统

    1. 用户管理:用户注册、登录、权限分配等功能,这涉及到身份验证和授权机制,如Spring Security框架的应用。 2. 课程管理:课程信息录入、修改、删除,课程安排和调整,以及课程评价等。 3. 学生管理:学生个人信息...

Global site tag (gtag.js) - Google Analytics