Spring Security安全框架入门篇

一、Spring Security相关概念

1.1.、Spring Security介绍:

Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全訪问控制解决方式的安全框架(简单说是对訪问权限进行控制嘛)。它提供了一组能够在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能。为应用系统提供声明式的安全訪问控制功能,降低了为企业系统安全控制编写大量反复代码的工作。

1.2、Spring Security实现原理:

Spring Security对Web安全性的支持大量地依赖于Servlet过滤器。通过这些过滤器拦截进入请求,推断是否已经登录认证且具訪问相应请求的权限。

要完毕訪问控制。Spring Security至少须要以下四个拦截器(调度器、认证管理器、权限资源关联器、訪问决策器)进行配合完毕:

<!-- mySecurityInterceptor这里我们把它命名为调度器吧 -->
<!-- 必须包括 authenticationManager,securityMetadataSource,accessDecisionManager 三个属性 -->
<!-- 我们的全部控制将在这三个类中实现 -->
<!-- 它继承AbstractSecurityInterceptor类并实现了Filter接口 -->
<bean id="mySecurityInterceptor" class="com.luo.Filter.MySecurityInterceptor">
    <b:property name="authenticationManager" ref="authenticationManager" />
    <b:property name="securityMetadataSource" ref="securityMetadataSource" />
    <b:property name="accessDecisionManager" ref="accessDecisionManager" />  

</bean>  

<!-- 认证管理器,实现用户认证的入口 -->
<authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="myUserDetailService" />
</authentication-manager>  

<!-- 在这个类中,你就能够从数据库中读入用户的password。角色信息等 -->
<!-- 主要实现UserDetailsService接口就可以,然后返回用户数据 -->
<bean id="myUserDetailService" class="com.luo.Filter.MyUserDetailService" />  

<!-- 权限资源关联器。将全部的资源和权限相应关系建立起来,即定义某一资源能够被哪些角色訪问 -->
<!-- 它实现了FilterInvocationSecurityMetadataSource接口 -->
<bean id="securityMetadataSource" class="com.luo.Filter.MyFilterInvocationSecurityMetadataSource" /> 

<!--訪问决策器。决定某个用户具有的角色,是否有足够的权限去訪问某个资源 -->
<!-- 它实现了AccessDecisionManager接口 -->
<bean id="accessDecisionManager" class="com.luo.Filter.MyAccessDecisionManager">

看完上面的配置。可能未必能够全然明确。以下我们再进一步说明。

(1)首先我们自己定义一个过滤器(调度器。这里我们命名为mySecurityInterceptor),这个过滤器继承AbstractSecurityInterceptor类(这里先说明,本文但凡不是自己定义的类或接口都是Spring Security提供的,无须深究)。 它至少包括 authenticationManager,accessDecisionManager,securityMetadataSource三个属性,我们的全部控制将在这三个类中实现。

(2)登录验证:自己定义类MyUserDetailService实现UserDetailsService接口和其loadUserByUsername方法,这种方法依据用户输入的username,从数据库里面获取该用户的全部权限细信息(统称用户信息)。Spring Security的AuthenticationProcessingFilter拦截器调用authenticationManager,类MyUserDetailService拿到用户信息后,authenticationManager对照用户的password(即验证用户),假设通过了,那么相当于通过了AuthenticationProcessingFilter拦截器,也就是登录验证通过。

(3)资源訪问控制:MySecurityInterceptor继承AbstractSecurityInterceptor、实现Filter是必须的。登陆后,每次訪问资源都会被MySecurityInterceptor这个拦截器拦截,它首先会调用MyFilterInvocationSecurityMetadataSource类的getAttributes方法获取被拦截url所需的权限,在调用MyAccessDecisionManager类decide方法推断用户是否够权限。

可能文字描写叙述还是比較抽象。通过实例应该能让大家更加清楚其原理。



补充说明一下:

UserDetailsService在身份认证中的作用:

Spring Security中进行身份验证的是AuthenticationManager接口,ProviderManager是它的一个默认实现,但它并不用来处理身份认证,而是托付给配置好的AuthenticationProvider。每一个AuthenticationProvider会轮流检查身份认证。

检查后或者返回Authentication对象或者抛出异常。

验证身份就是载入响应的UserDetails,看看是否和用户输入的账号、password、权限等信息匹配。

此步骤由实现AuthenticationProvider的DaoAuthenticationProvider(它利用UserDetailsService验证username、password和授权)处理。

因此,登录认证事实上能够不实现UserDetailsService,而是实现AuthenticationProvider,然后在AuthenticationProvider里面获取用户输入的username和password进行校验也是能够的。或者两者一起使用。

以下推荐两者一起使用的方式http://blog.sina.com.cn/s/blog_4adc4b090102uy2f.html

另外,仅仅实现AuthenticationProvider而不实现UserDetailsService的方式,这类是重写AuthenticationProvider的authenticate方法的代码:

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    String inputLoginId = authentication.getName();   //获取用户输入的username
    String inputPasswd = authentication.getCredentials().toString(); /获取用户输入的password

    LOGGER.info("用户{}登录", inputLoginId);
    try{
        // 查询此用户信息
        myUser myUser = null;  //依据username到数据库里面查询用户数据
        if (myUser == null ) {
            throw new Exception("您输入的账号不存在");
        }
        if (myUser.getUserStatus() == UserStatus.locked) {
            throw new Exception("您的账号已被锁定");
        }

        String encodedPassword = myUser.getLoginPasswd();
        // 校验password是否正确
        boolean authenticated = verifyPassword(inputPasswd, encodedPassword);
        if (authenticated) {
            // 认证成功处理
            updateLoginInfo(myUser.getLoginId(), 0, null);
        } else {
            // 认证失败处理
            authenticateErrorProcess(portalUser);
        }

        List<GrantedAuthority> grantedAuths = new ArrayList<GrantedAuthority>();
        for (MyRole myRole : myUser.allRoleList()) {
            grantedAuths.add(new SimpleGrantedAuthority(myRole.getRoleCode()));
        }
        MyAuthUser authUser = new PortalAuthUser(inputLoginId, inputPasswd, true, true, true, true, grantedAuths);
        authUser.setPortalUser(portalUser);
        return new UsernamePasswordAuthenticationToken(authUser, null, authUser.getAuthorities());
    }catch(Exception e){
        LOGGER.warn("用户登录失败", e);
        throw new Exception(" 请确认username或者password是否正确);
    }
}

二、Spring Security实例具体说明

本实例环境:eclipse + maven

本实例採用的主要技术:spring + springmvc + spring security

时间有限这里仅仅对其訪问控制原理进行了阐述,样例后面再补上,只是关于实例推荐參考博文:http://blog.csdn.net/u012367513/article/details/38866465,这篇文章写得很具体!

这是春节前最后一篇博客了。过春节回来还有另外的学习计划。可能这个样例的TODO有点遥遥无期啊……..哈哈

时间: 2024-10-14 05:38:06

Spring Security安全框架入门篇的相关文章

Spring Security安全框架

今天来简单介绍一下Spring Security安全框架 简介 Spring Security 提供了基于javaEE的企业应有个你软件全面的安全服务.这里特别强调支持使用SPring框架构件的项目,Spring框架是企业软件开发javaEE方案的领导者.如果你还没有使用Spring来开发企业应用程序,我们热忱的鼓励你仔细的看一看.熟悉Spring特别是一来注入原理两帮助你更快更方便的使用Spring Security. 人们使用Spring Secruity的原因有很多,单大部分都发现了jav

Farseer.net轻量级开源框架 入门篇:使用前说明

导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 框架性能测试 下一篇:Farseer.net轻量级开源框架 入门篇: 增.删.改.查操作演示 本篇讲解使用或者学习Farseer前需要知道一些事项: 在后续很多演示中,使用了很多扩展方法.但作者并没有明确出哪些是扩展的方法.所以读者要注意.在使用框架的时候,都需要引用扩展方法的命名空间:using FS.Extend; 为了方便,扩展方法统一放到FS.Extend中,在这里特别说

spring security 安全框架remember me,demo学习

本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/50018001未经博主允许不得转载. 博主地址是:http://blog.csdn.net/freewebsys 1,spring security Spring Security 的前身是 Acegi Security ,是 Spring 项目组中用来提供安全认证服务的框架. 在安全框架这边使用最多的就是spring security. 论坛资料比较充实. 一个哥们写的例子,使

Farseer.net轻量级开源框架 入门篇:Where条件的终极使用

导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 查询数据详解 下一篇:Farseer.net轻量级开源框架 中级篇: 事务的使用 这里,我把一些常用Where用到的条件都写在这里,方便大家学习 1 // 这是最常用的 属性判断 2 Users.Data.Where(o => o.ID == 1) 3 Users.Data.Where(o => o.ID > 1) 4 Users.Data.Where(o => o

Farseer.net轻量级开源框架 入门篇:删除数据详解

导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 修改数据详解 下一篇:Farseer.net轻量级开源框架 入门篇: 查询数据详解 相对于修改,删除则简单的多: 1 // 字段值指定 加 1 2 Users.Data.Where(o => o.ID == 1).Delete(); 1 Users.Data.Delete(1); 1 var lst = new List<int> { 1, 2, 3, 4, 5 }; 2

Farseer.net轻量级开源框架 入门篇:查询数据详解

导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 删除数据详解 查询列表的几种方式 1 // 字段值指定 加 1 2 Users.Data.Where(o => o.ID == 1).ToList(); 1 // 查询前10条数据 2 Users.Data.ToList(10); 1 // 批量查询 2 var lst = new List<int> { 1, 2, 3, 4, 5 }; 3 Users.Data.ToL

Farseer.net轻量级开源框架 入门篇:修改数据详解

导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 添加数据详解 下一篇:Farseer.net轻量级开源框架 入门篇: 删除数据详解 Update的几种方式(基本) 1 Users info = new Users(); 2 info.UserName = "张三"; 3 info.PassWord = "密码"; 4 5 // 指定用户ID为1的的数据进行修改. 6 Users.Data.Wher

Farseer.net轻量级开源框架 入门篇:添加数据详解

导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 分类逻辑层 下一篇:Farseer.net轻量级开源框架 入门篇: 修改数据详解 前面讲的大多数是原理及说明,大家在理解上会比较枯燥,接下来的几篇,倾向于实战,会比较有意思些. 这里的话,还是拿Users实体类来讲解在我们框架的几种添加方式. Insert的几种方式 1 Users info = new Users(); 2 info.UserName = "张三";

Farseer.net轻量级开源框架 入门篇:分类逻辑层

导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 缓存逻辑层 下一篇:Farseer.net轻量级开源框架 入门篇: 添加数据详解 分类逻辑层 分类逻辑层,主要用在一些需要支持无限递归的树数据.树数据是:必须有一个根节点,根节点有无限个子节点,没有节点限制.比如我们常用的有:(频道.xxx分类) 这里与BaseCacheModel的操作是完全一致.唯一不同的是,BaseCateModel是继承自ModelCateInfo.这个类