Spring Security

Spring Security


基本概念

SpringSecurity是Spring下的一个安全框架,与shiro 类似,一般用于用户认证(Authentication)和用户授权(Authorization)两个部分,常与与SpringBoot相整合。

认证

认证的主要目的就是“证明你是谁”,常见的认证方式:

  • 账号密码登录
  • 生物认证,例如指纹,人脸,瞳孔
  • 动态口令,例如例如手机验证码

授权

再认证之后,系统会赋予你一定的权利,这就是授权,即“你可以做什么”

授权模型

为了对权限的管理,我们通常把”权限相关的内容“存放在数据库中,一个用户可以拥有多个角色,而每个角色可以包含多个权限。

授权的方法(RBAC)

  • 基于角色的授权方法:当用户拥有某个角色时,且这个角色拥有某项操作权限,那么这个用户就拥有这个操作权限
  • 基于资源的授权方式:当用户拥有某个角色时拥有某项操作权限,那么这个用户就可以对这个资源进行相关操作

通常建议在程序层面采用基于资源的授权,而数据库层面采用 基于角色的授权,原因如下:

首先我们的授权系统需要保证是优秀的,那么什么是优秀的系统:

  • 便于对用户权限更改
  • 用户与权限之间,耦合度小
  • 代码精简

首先,先考虑程序层面,如果我们在程序层面用的是基于角色的授权方式,一旦我们需要对某个角色的权限做出修改,我们就不得不修改代码。如:

1
2
3
if(达芬奇.hasRole("画家")){
//他可以占用画室画画
}

画室不再对外开放,而达芬奇的画家身份又是不变的,我们就不得不修改代码,但如果我们在程序层面使用对资源的授权方式,就不需要修改代码。

1
2
3
if(达芬奇.hasAuth("使用画室")){
//他可以占用画室画画
}

当我们不希望达芬奇使用画室,我们就可以在数据库中,删除达芬奇”使用画室“的权限。也就是说,基于资源的授权方式更灵活。

接下来,考虑数据库层面,如果在数据库中,我们使用的是基于角色的授权方式,即只有三张表,用户表,权限表,用户权限关系表。此时我们对用户的授权就拥有了很大的麻烦,比如:

当一个用户注册,加入到了这个系统中,你需要赋予他一些初始的权限,由于系统可能很复杂,即使是初始权限,也会很多。在数据库中,我们需要多次调用insert操作,为一个用户授权,这样对于代码来讲,是很庞大的工作量,而且多次I/O操作也会导致性能很低。

但如果我们使用基于角色的方式,问题就会得到解决,在用户注册后,我们只需要给他赋予一个特定的角色,在数据库中,这个角色拥有着一些初始权限。这样很方便我们进行管理。也就是说,基于角色的权限管理更易管理。

总结

基于资源的授权方式更灵活。基于角色的权限管理更易管理。所以我们可以各取所长,放到合适的地方,在程序层面采用基于资源的授权,而数据库层面采用 基于角色的授权

Spring security原理

Spring security对于认证可授权的管理是基于session的,通过过滤器链,主要和两个类打交道,一个是认证类,一个是授权类。

  1. 首先他他会判断你有没有进行过认证,如果没有则会返回403或跳转到相应页面(这里可以自定义)
  2. 如果已经认证过,他会根据你带来的SesionID去Tomcat中查询此用户的权限,加入到当前会话中
  3. 当你访问特定API接口,他会判断当前会话是否拥有某个权限,如果有则会返回结果,没有返回403

认证流程

认证流程

  1. 首先用户提交账号密码
  2. 经过一系列转化,最终将账号密码发送给UserDetailsService
  3. UserDetailsService会根据发送来的用户名,从数据库(或本地内存)中获取相应的用户信息封装为UserDetails包含三部分
    • 用户名
    • 加密后的密码
    • 权限
  4. AuthenticationProvider会将用户发送来的信息,与UserDetails的信息相比对,如果成功,则生成SessionID,并将相应SessionID对应的权限保存到内存中
  • 在认证时,可以设置密码加密器(在数据库中,密码不会以明文形式存储)
  • 如果是在前后端分离的情况下,可以设置取消使用session

授权流程

  • 系统会根据发送过来的sessionid,来获取此用户的权限
  • 然后查询访问此接口,需要什么权限
  • 接下来,会判断用户权限,是否包含访问此接口需要的权限,如果是则返回结果,否则返回403

总结

Spring security为认证和授权进行了大部分的工作,但存在一个问题,这些都是基于Session的,也就是说不适合于前后端分离项目。当然也有解决方案,使用Spring security与JWT整合。


Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×