spring安全框架Security(二)

好,我们往下看,接着就是应用我们实际项目里的自定义用户权限了

Java代码

<security:authentication-manager>  
     <security:authentication-provider user-service-ref="customUserDetailsService">  
         <security:password-encoder ref="passwordEncoder" />  
     </security:authentication-provider>  
</security:authentication-manager>  
  
    <!-- 对密码进行MD5编码 -->  
<bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />  
<bean id="customUserDetailsService" class="org.yzsoft.springmvcdemo.util.CustomUserDetailsService" />

首先是<security:authentication-manager>是指定我们自定义的身份验证策略,这里我们用customUserDetailsService这个bean,就是指向我们CustomUserDetailsService.java这个类。然后<security:password-encoder>指定我们密码使用MD5进行编码,调用Spring Security自带的MD5加密类。当然,还有加盐MD5或我们自己写的加密算法等安全性更加高的密码策略。这个按项目实际使用配置吧。

然后看到我们的CustomUserDetailsService.java

Java代码

package org.yzsoft.springmvcdemo.util;  
  
import java.util.ArrayList;  
import java.util.Collection;  
import java.util.List;  
  
import org.apache.log4j.Logger;  
import org.springframework.beans.factory.annotation.Autowired;  
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 org.yzsoft.springmvcdemo.serviceimpl.UsersServiceImpl;  
import org.yzsoft.springmvcdemo.vo.TUsers;  
  
/** 
 * 一个自定义的类用来和数据库进行操作. 即以后我们要通过数据库保存权限.则需要我们继承UserDetailsService 
 *  
 * @author  
 *  
 */  
public class CustomUserDetailsService implements UserDetailsService {  
  
    protected static Logger logger = Logger.getLogger("service");//log4j,不用解释了吧。。  
    @Autowired  
    private UsersServiceImpl usersService;  
  
    public UsersServiceImpl getUsersService() {  
        return usersService;  
    }  
  
    public void setUsersService(UsersServiceImpl usersService) {  
        this.usersService = usersService;  
    }  
  
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {  
  
        UserDetails user = null;  
  
        try {  
  
            // 搜索数据库以匹配用户登录名.  
            // 我们可以通过dao使用Hibernate来访问数据库  
            System.out.println(username + "   用户页面输入的用户名");  
            TUsers tusers = this.usersService.findByUsername(username);  
            System.out.println(tusers.getUsername() + "   数据库取出的用户名");  
            // Populate the Spring User object with details from the dbUser  
            // Here we just pass the username, password, and access level  
            // getAuthorities() will translate the access level to the correct  
            // role type  
            // 用户名、密码、是否启用、是否被锁定、是否过期、权限  
            user = new User(tusers.getUsername(), tusers.getPassword().toLowerCase(), true, true, true, true, getAuthorities(Integer.parseInt(tusers.getRole())));  
               
               
        } catch (Exception e) {  
            logger.error("用户信息错误!");  
            throw new UsernameNotFoundException("异常处理:检索用户信息未通过!");  
        }  
           
        return user;  
    }  
  
    /** 
     * 获得访问角色权限列表 
     *  
     * @param access 
     * @return 
     */  
    public Collection<GrantedAuthority> getAuthorities(Integer role) {  
        System.out.println("取得的权限是  :" + role);  
        List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();  
  
        // 所有的用户默认拥有ROLE_USER权限  
        if (role == 0) {  
            System.out.println("普通用户");  
            logger.debug("取得普通用户权限-->");  
            authList.add(new GrantedAuthorityImpl("ROLE_USERS"));  
        }  
        // 如果参数role为1.则拥有ROLE_ADMIN权限  
        if (role == 1) {  
            logger.debug("取得ADMIN用户权限-->");  
            authList.add(new GrantedAuthorityImpl("ROLE_ADMIN"));  
        }  
        System.out.println(authList.size()+"  权限列表长度");  
        return authList;  
    }  
}

这里就是把我们从数据库里面取得的用户权限和Spring Security的配置进行桥接,还记得上面配置文件里的ROLE_ADMIN吧,就是从这里来的,很奇怪的是,这个必须设置成ROLE_ 开头才有效。。郁闷。。。

这里我刚开始有一个疑惑,我们看这2句

Java代码

TUsers tusers = this.usersService.findByUsername(username);  
user = new User(tusers.getUsername(), tusers.getPassword().toLowerCase(), true, true, true, true, getAuthorities(Integer.parseInt(tusers.getRole())));

这里根本不需要用户输入的密码,只要了用户名,然后直接根据用户名去取权限,就直接设置进Spring Security的User对象里面去,我不禁一身冷汗,这不相当于说有了用户名就直接去查数据库么,而且是不用密码的。。。。

但经过查看官方文档和网上的解释,这才放心,原来是这样的,Spring Security的确是直接根据用户名去查,但是查得出来的Spring Security  User对象之后,它会根据这个对象的属性值去数据库查询与这个对象匹配的数据,我们这里设置的是(用户名,密码,是否启用、是否被锁定、是否过期、权限。。。),那么如果数据库存在这个对象,就返回真,否则返回假,这样也就不用担心了,完全可靠。就是我们在前台要做好限制,不能给用户不输密码就访问, 不然挤爆你数据库连接。。。。。

最后登陆页面index.jsp

Java代码

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
<%  
String path = request.getContextPath();  
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
%>  
  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
<html>  
  <head>  
    <base href="<%=basePath%>">  
      
    <title>My JSP ‘index.jsp‘ starting page</title>  
    <meta http-equiv="pragma" content="no-cache">  
    <meta http-equiv="cache-control" content="no-cache">  
    <meta http-equiv="expires" content="0">      
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
    <meta http-equiv="description" content="This is my page">   
  </head>  
    
  <body>  
    用户登陆 <br>  
     ${SPRING_SECURITY_LAST_EXCEPTION.message}  
      <form action="j_spring_security_check" method="post">  
        USERNAME:<input type="text" name="j_username" value="${sessionScope[‘SPRING_SECURITY_LAST_USERNAME‘]}" /><br/>  
        PASSWORD:<input type="password" name="j_password" value="" /><br/>  
        <input type="checkbox" name="_spring_security_remember_me" />两周之内不必登陆(这个功能没有做的)<br/>  
        <input type="submit">       
    </form>  
  </body>  
</html>

这里我还是使用Spring Security默认的j_username和j_password,表单目标也用默认的j_spring_security_check,会默认跳到Spring Security进行拦截。其他的应该不用解释了吧。。。。

最后 ,我们整理一下Spring Security的整个控制过程:

——>用户登陆

——> <security:authentication-manager> 拦截

——>交给customUserDetailsService处理,并且声明密码采用MD5策略

——>根据输入的用户名去数据库查这条记录,验证身份

——>取出该条记录的用户权限(锁定、禁用、过期和实际权限等)

——>根据取得的权限列表去security:intercept-url匹配、授权,然后判断是否放行。

这就完成了一整个的权限控制流程。

接下来我们来测试一下看是否真的生效了:

1、测试匿名访问页面,直接地址栏访问:

2、普通用户登陆

3、然后访问后台管理页面,跳回了登陆页

4、管理员用户登陆

退出后成功跳转回登陆页,点击后退再执行其他操作,这时候session已经注销了的,不能执行,又跳回了登陆页。是我们想要的效果,OK,成功了。

好 了,Spring Security的简单使用就讲到这里,其实这只是Spring Security的一小部分,而且这里我还没有用权限表对用户权限进行专门的管理,很多东西还是用Spring Security 默认的,还有Spring Security CAS (单点登陆)以及更加高级的权限控制和更完善的Spring Security 配置,以后我们再慢慢去研究吧。发现Spring Security 这个技术不仅简化了我们的用户权限管理,要知道我们做管理系统的时候这是个大问题,也差不多颠覆了我一贯以来用户权限管理的观念,但是掌握了这种思维之 后,又发现,其实,程序并不是只有一种实现方式,它激发了我写程序时要去寻找多种解决方案的想法。学习的路上,就是要不断推翻自己固有的思维,去见识多种 新事物,才能有进步。

时间: 2024-10-28 19:31:38

spring安全框架Security(二)的相关文章

Spring.Net框架二:配置Spring.Net框架环境

一.下载DLL文件 去Spring的官方网站下载并解压,然后直接添加dll文件的引用就可以了.在上一篇文章中,已经介绍过Spring.Net框架中需要使用到的dll文件.这些程序集文件位于Spring.NET-1.3.1\Spring.NET\bin\net\4.0\debug或Spring.NET-1.3.1\Spring.NET\bin\net\4.0\release中. 二.编程方式的容器 在Spring.Net中,对于通过编程方式使用容器的环境,提供了Spring.Context.Sup

用Maven整合SpringMVC+Spring+Hibernate 框架,实现简单的插入数据库数据功能(二)

前一篇写的有些多,大家先看前一篇,传送门 具体的资源已将上传到资源了. 附地址:MySQL.zip启动 用Maven整合SpringMVC+Spring+Hibernate 框架 上文我们直接搭建前的准备和资源配置都写好了,下面进入具体代码编写.承接上文的小3 3.我习惯建立接口,这样对整个项目感觉更合理. (1.)建立IBaseService(业务逻辑层,有的习惯写成BaseServiceI)都可以,都是标注接口的,我只是简单的贴下代码 package com.jesus.sshframewo

spring boot 框架实用技巧(二)

1.现在我们就开始上手一下spring boot 框架的使用. 学习任何框架我觉得最简单的方式就是从它的事例上学习,还有个前提就是你至少以前学习过至少一种框架的使用,这样的话上手会很快. 首先如上图import spring 的项目选中spring getting started content,然后呢如下图: 选中spring boot 之后需要等一下,当finish 出现了就可以点击了,然后就开始下载项目文件,这里要注意一下项目默认的方式如上图的我选的是maven进行项目包的管理,也可以选g

框架-------(二)Spring和SpringMVC框架(序列一初始原理概念)

1.什么是Spring? Spring是个java企业级应用的开源框架.Spring主要目标就是简化开发,并通过pojo为基础的编程模型促进良好的编程习惯. 2.为什么要使用Spring框架 它是轻量级的开源框架,基本的版本大约2MB. 控制反转IOC:Spring通过控制反转实现了松散耦合,对象们给出他们的依赖,而不是直接创建或者查找依赖的对象. 面向切面编程:AOP,Spring支持面向切面编程,应用业务逻辑和系统服务分开. 容器:Spring包含并管理应用中对象的生命周期和配置 MVC框架

Spring MVC 框架搭建及详解

一.Spring MVC环境搭建:(Spring 2.5.6 + Hibernate 3.2.0) 1. jar包引入 Spring 2.5.6:spring.jar.spring-webmvc.jar.commons-logging.jar.cglib-nodep-2.1_3.jar Hibernate 3.6.8:hibernate3.jar.hibernate-jpa-2.0-api-1.0.1.Final.jar.antlr-2.7.6.jar.commons-collections-3

SSH(Struts2+Spring+Hibernate)框架搭建流程&lt;注解的方式创建Bean&gt;

此篇讲的是MyEclipse9工具提供的支持搭建自加包有代码也是相同:用户登录与注册的例子,表字段只有name,password. SSH,xml方式搭建文章链接地址:http://www.cnblogs.com/wkrbky/p/5912810.html 一.Hibernate(数据层)的搭建: 实现流程 二.Spring(注入实例)的使用: 实现流程 三.Struts2(MVC)的搭建: 实现流程 这里注意一点问题: Struts2与Hibernate在一起搭建,antlr包,有冲突.MyE

Spring.net(一)----Spring.NET框架简介及模块说明

简介:    Spring.NET框架包括很多功能,Spring.NET 1.0包括完整的IoC容器和AOP类库.1.1版加入Web.ORM和数据模块.Spring.NET的下载包中并不包含与其它类库(如NHibernate,TIBCO EMS,Anthem,和IIOP.NET)集成的模块,如果需要您可以单独下载. Spring Framework天生丽质,因为其先进的架构和对一系列前沿开发思想的集成,使它从一产生就深得开发者欢迎,它将设计模式运用到了炉火纯青的地方,它的幽雅和魅力征服了许多JA

“Zhuang.Data”轻型数据库访问框架(二)框架的入口DbAccessor对象

目录: “Zhuang.Data”轻型数据库访问框架(一)开篇介绍 “Zhuang.Data”轻型数据库访问框架(二)框架的入口DbAccessor对象 先来看一段代码 DbAccessor dba = DbAccessor.Create(); var dt = dba.QueryDataTable("select * from sys_product where productid=#Id#",new {Id=1}); Console.WriteLine(DataTableUtil.

spring mvc+mybatis整合 (二)

转:http://lifeneveralone.diandian.com/post/2012-11-02/40042292065 本文介绍使用spring mvc结合Mybatis搭建一个应用程序框架. demo源码下载:springMVC-Mybatis 1.准备工作: spring的jar包: spring-beans-3.1.0.RELEASE.jar spring-core-3.1.0.RELEASE.jar spring-web-3.1.0.RELEASE.jar spring-web