springSecurity安全框架的学习和原理解读

一、Spring security框架简介

1、简介
一个能够为基于Spring的企业应用系统提供声明式的安全訪问控制解决方式的安全框架(简单说是对访问权限进行控制嘛),应用的安全性包括用户认证(Authentication)用户授权(Authorization) 两个部分。
①用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。
② 用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。
spring security的主要核心功能为 认证和授权,所有的架构也是基于这两个核心功能去实现的。

2、框架原理
众所周知 想要对对Web资源进行保护,最好的办法莫过于Filter,要想对方法调用进行保护,最好的办法莫过于AOP。所以springSecurity在我们进行用户认证以及授予权限的时候,通过各种各样的拦截器来控制权限的访问,从而实现安全。
对Web资源的保护,就是靠Filter实现的。如下图:在这里插入图片描述
一般来说,我们的Filter都是配置在web.xml中,但是springSecurity不一样,它在web.xml中配置的只是一个代理,而真正起作用的Filter是作为Bean配置在Spring中的。web.xml中的代理依次调用这些Bean,就实现了对Web资源的保护,同时这些Filter作为Bean被Spring管理,所以实现AOP也很简单,真的是一举两得啊。

springSecurity中提供的Filter不少,有十多个,一个一个学起来比较复杂。但是对于我们Web开发者来说,常用的就那么几个,如下图中的被红圈圈标记出来的:
在这里插入图片描述
从上到下,它们实现的功能依次是1、制定必须为https连接;2、从Session中提取用户的认证信息;3、退出登录;4、登录;5、记住用户;6、所有的应用必须配置这个Filter。

一般来说,我们写Web应用只需要熟悉这几个Filter就可以了,如果不需要https连接,连第一个也不用熟悉。但是有人肯定会想,这些Filter怎么和我的数据库联系起来呢?(解释:为什么要和数据库相联系的原因是“这些权限信息都保存在数据库中,哪些用户有这些权限,哪有用户有那些权限,这些数据信息都是存留在数据库中的”)不用着急,这些Filter并不直接处理用户的认证,也不直接处理用户的授权,而是把它们交给了认证管理器和决策管理器。如下图:
在这里插入图片描述
对于这两种管理器,那也是不需要我们写代码的,Acegi也提供了现成的类。那么大家又奇怪了:又是现成的,那怎么和我的数据库关联起来呢?别着急,其实这两个管理器自己也不做事,认证管理器把任务交给了Provider,而决策管理器则把任务交给了Voter,如下图:
在这里插入图片描述
现在我要告诉你们,这里的Provider和Voter也是不需要我们写代码的。不要崩溃,快到目标了。Acegi提供了多个Provider的实现类,如果我们想用数据库来储存用户的认证数据,那么我们就选择DaoAuthenticationProvider。对于Voter,我们一般选择RoleVoter就够用了,它会根据我们配置文件中的设置来决定是否允许某一个用户访问制定的Web资源。

而DaoAuthenticationProvider也是不直接操作数据库的,它把任务委托给了UserDetailService,如下图:
在这里插入图片描述
而我们要做的,就是实现这个UserDetailService。 图画得不好,大家不要见笑,但是说了这么多总算是引出了我们开发中的关键, 那就是我们要实现自己的UserDetailService,它就是连接我们的数据库和Acegi的桥梁。 UserDetailService的要求也很简单,只需要一个返回org.springframework.security.userdetails.User对象的loadUserByUsername(String userName)方法。因此,怎么设计数据库都可以,不管我们是用一个表还是两个表还是三个表,也不管我们是用户-授权,还是用户-角色-授权,还是用户-用户组-角色-授权,这些具体的东西Acegi统统不关心,它只关心返回的那个User对象。至于怎么从数据库中读取数据,那就是我们自己的事了。

反过来再看看上面的过程,我们发现,即使我们要做的只是实现自己的UserDetailService类,但是我们不得不在Spring中配置那一大堆的Bean,包括几个Filter,几个Manager,几个Provider和Voter,而这些配置往往都是重复的无谓的。好在springSecurity 2.0也认识到了这个问题,所以,它设计了一个标签,让springSecurity的配置得到了简化。下面是SpringSide 3中的配置的截图,大家可以看看:
在这里插入图片描述
下图是官方文章中的传统Filter设置和元素之间的对应关系:
在这里插入图片描述
下面的代码是SpringSide 3中实现UserDetailService的范例,在SpringSide 3的范例中,笔者使用了三个表User、Role、Authority。但是springSecurity不关心你用了几个表,它只关心UserDetails对象。而决定用户能否访问指定Web资源的是RoleVoter类,无需任何修改它可以工作得很好,唯一的缺点是它只认ROLE_前缀,所以搞得笔者的Authority看起来都象角色,不伦不类。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最后再来说说这个命名的问题,我对Authentication和Authority这两个单词比较反感,两个原因,一是因为它们太生僻了,二是因为它们长得太像了,明明一个是认证,一个是授权,意思相差很远,外貌却如此相似,确实很烦人。如果让我来选择,我喜欢Privilege这个单词,在我刚使用MySQL的时候就跟它很熟了,所以在我的项目中,我可能会用Privilege来代替Authority。如果我们只使用User-Role两级关系,使用RoleVoter默认的ROLE_前缀当然没有关系,如果是像笔者这样是用三层关系,最好还是把这个前缀改一改,以免混淆。

补充:
前文所讲的是我对springSecurity的一些理解,我认为只有把条理搞清楚了,才更容易深入。我想得比较简单,当然会漏掉一些细节。这里把它补充一下。

1、我上面讲到的主要内容,包含了认证和授权,但是漏掉了资源,资源就是我们需要保护的URL,或者一些类中的方法。要保护URL,在xml文件中按照前面的例子配置就可以了,要保护类中的方法,使用@secured就可以了。
但是它们是和Acegi中的哪个组件关联起来的呢?是FilterSecurityInterceptor和MethodSecurityInterceptor,这两个Interceptor都需要设置一个叫objectDefinitionSource的属性。所以,有人要问,如何把对资源的保护设置全部转移到数据库中,避免写在xml中,那就要从这个objectDefinitionSource着手了。

2、前面讲到了UserDetailService,事实上在Acegi中还需要配置别的Service,如RememberMeService,当然,该Service也是现成的,不需要我们写代码的,RememberMeProcessingFilter需要依赖这个Service。

3、springSecurity支持OpenID和CAS 3,这两个东西是干什么的呢?是可以实现单点登录功能的,也就是允许用户只登录一次,就可以使用多个网站。这对于那些很庞大的网站非常有用,可以把用户登录这样的操作集中在一台服务器上。要使用CAS,只需要配置Filter时选择CASProcessingFilte,配置Provider时选择CasAuthenticationProvider,其余的概念都是相通的。具体的实现细节,大家慢慢摸索吧。

如果不喜欢ROLE_这个前缀,可以通过下面的方式来替换
在这里插入图片描述

二、自定义安全配置的加载机制

1、前提 基于自身业务需要
有关springSecrity安全框架的理解参考:springSecurity安全框架介绍

未完待续:https://blog.csdn.net/liushangzaibeijing/article/details/81220610#%C2%A0%20%C2%A0%20%C2%A02%E3%80%81%E6%A1%86%E6%9E%B6%E5%8E%9F%E7%90%86

  • 1
    点赞
  • 0
    评论
  • 15
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值