Spring Security之认证与授权的概念

前言

上一文中,留了一些坑,本文我们将从登录认证概念本身入手。

认证与授权基础概念

认证(Authentication)和授权(Authorization)是计算机安全方面的两个基础概念

认证(Authentication)

认证是验证用户身份的过程,即向系统证明用户是谁。这通常涉及到用户提供一些凭据,如用户名和密码,或者更复杂的认证方式,如双因素认证或生物识别认证。系统会对这些凭据进行验证,以确认用户的身份是否真实。如果凭据有效,用户就被认证为系统的合法用户。
认证是确保只有合法用户可以访问系统或资源的关键步骤,它是计算机领域安全性的基石之一。通过认证,系统可以防止未经授权的访问,保护敏感数据和功能不被非法访问。

  • 常见的认证实现
  1. 用户名和密码认证:这是最基本的认证方式,用户需要提供注册时设定的用户名和密码,系统将验证用户名和密码的匹配性来确认用户身份。
  2. 多因素认证(MFA):为了提高安全性,很多系统采用多因素认证,要求用户提供两种或更多种类型的凭证,例如密码加上指纹识别、动态令牌等。
  3. 单点登录(SSO):单点登录允许用户在一个中心认证服务器上进行一次身份验证后,无需再次输入用户名和密码即可访问多个相关联的应用系统。
  4. OAuth认证:OAuth是一种开放标准,用于授权第三方应用访问用户在其他服务上存储的私有资源,而无需将用户名和密码提供给第三方应用,常见的使用场景是社交媒体的登录。
  5. OpenID Connect认证:OpenID Connect是基于OAuth 2.0协议的身份认证层,提供了一种跨多个网站和应用的标准化方式来认证用户。
  6. 基于证书的认证:在这种方法中,用户或设备必须提供一个有效的数字证书来证明其身份,证书包含用户的公钥和一些标识信息,并由受信任的证书颁发机构(CA)签发。
  7. 基于令牌的认证:如JSON Web Tokens(JWTs),这是一种开放标准,定义了一种紧凑的、自包含的方式,用于在各方之间安全地传输信息,这些信息可以被验证和信任。
  8. HTTP Basic认证:HTTP Basic登录验证模式是Spring Security实现登录验证最简单的一种方式,它的目的并不是保障登录验证的绝对安全,而是提供一种简单的登录验证。

这些认证方式各有特点,适用于不同的场景和需求。在实际应用中,可以根据系统的安全需求和用户体验要求来选择合适的认证方式。同时,为了保证系统的安全性,建议定期更新和升级认证方式,以应对新的安全威胁和漏洞。

Spring Security支持如下认证方式:

  1. HTTP Basic认证:这是最简单的认证方式之一,其中用户的凭据(用户名和密码)以Base64编码格式在HTTP请求头中发送。它主要适用于RESTful Web服务。
  2. HTTP Digest认证:与Basic认证相比,Digest认证提供了更高的安全性,因为它使用摘要算法来传输凭据,而不是明文。
  3. 表单认证:这是Web应用程序中最常见的认证方式,其中用户通过表单输入用户名和密码,然后这些信息被发送到服务器进行验证。
  4. OAuth 2.0认证:OAuth 2.0是一个开放标准,允许用户授权第三方应用程序访问其账户信息,而无需共享密码。Spring Security通过集成Spring OAuth项目来支持OAuth 2.0。
  5. OpenID Connect认证:OpenID Connect是基于OAuth 2.0的一个身份认证层,它允许应用程序通过安全的方式验证用户的身份,并获取关于用户的基本信息。
  6. SAML 2.0认证:安全断言标记语言(SAML)是一种基于XML的开放标准,用于在身份提供者和服务提供商之间交换身份验证和授权数据。Spring Security可以与SAML 2.0兼容的身份提供商集成。
  7. LDAP认证:轻量级目录访问协议(LDAP)是一种用于查询和修改目录服务的协议,如Active Directory。Spring Security可以通过LDAP服务器进行用户认证。
  8. JAAS认证:Java认证和授权服务(JAAS)是Java平台的一个标准API,用于进行用户认证和访问控制。Spring Security可以与JAAS集成,以支持基于Java的认证机制。
  9. 预身份验证:这是一种机制,其中用户的身份已经在应用程序的外部进行了验证,并且以某种方式传递给了应用程序。例如,在使用代理服务器或负载均衡器时,用户可能已经在这些组件上进行了身份验证。例如SSO. 需要继承于AbstractPreAuthenticatedProcessingFilter来获取相关认证信息进行认证。
  10. X.509证书认证:在这种认证方式中,用户的身份通过客户端证书进行验证,该证书由受信任的证书颁发机构(CA)签发。
  11. 自定义认证:Spring Security还允许开发人员实现自定义的认证机制,以适应特定的业务需求。

授权(Authorization)

授权在认证之后进行的,它决定了用户在系统内被允许执行哪些操作或访问哪些资源。这涉及到为用户分配权限的过程,权限决定了用户可以执行哪些任务或访问哪些数据。例如,在某些系统中,只有具有特定权限的用户才能访问特定资源,或者只有管理员才能执行某些操作。

  • 常见的授权实现
    在计算机系统中,授权是指控制用户或实体对系统资源的访问权限的过程。以下是授权的一些常见实现方式:
  1. 基于角色的访问控制(RBAC):这是最常见的授权方式之一。在RBAC中,权限被分配给角色,而角色则被分配给用户。例如,一个系统可能有“管理员”、“编辑”和“读者”等角色,每个角色有不同的权限集合。用户根据其被分配的角色来获得相应的权限。
  2. 基于属性的访问控制(ABAC):在这种方法中,访问决策是基于请求者、资源、环境条件和策略的属性来动态计算的。ABAC提供了更细粒度的控制,因为它可以根据多个属性来允许或拒绝访问。例如:根据用户所属机构来授予权限.
  3. 基于策略的访问控制(PBAC):PBAC是一种灵活的授权模型,它允许管理员定义策略来控制对资源的访问。这些策略可以基于时间、位置、用户行为或其他条件。
  4. 访问控制列表(ACL):ACL是一种授权机制,它明确指定哪些用户或用户组可以访问特定的资源,以及他们可以执行哪些操作。ACL通常与文件系统或数据库等系统资源关联。参照Linux的文件权限管理。
  5. 基于声明的访问控制(Claims-Based Access Control):在这种模型中,用户Principals的身份Identities被封装在一组声明Claims中,这些声明描述了用户的属性和权限。系统根据这些声明来做出授权决策.适用于大型系统.
  6. 能力为基础的访问控制(CapBAC):这是一种较新的授权模型,它强调赋予实体(如用户或进程)特定的“能力”,这些能力定义了它们可以执行的操作。CapBAC旨在减少权限管理的复杂性,并增强系统的安全性。
  7. 强制访问控制(MAC):强制访问控制是一种严格的访问控制策略,通常由系统强制执行,而不是由用户或进程控制。在MAC系统中,每个用户和对象都被分配一个安全级别,系统根据这些级别来允许或拒绝访问。

Spring Security支持的授权方式
在Spring Security中,授权通常通过RBAC和ACL来实现,但也可以结合其他模型来提供灵活的授权解决方案。Spring Security进行了抽象,主要由UserDetailsServiceUserDetailsGrantedAuthority三大接口来组织授权方式。

前面我们说过,在认证成功后,紧接着就是授权。但是实际上在SpringSecurity并不是这样实现的。在认证之前,SpringSecurity需要先找到当前想要登录的用户信息,然后才能进行凭证(密码)比较。而SpringSecurity则要求查找到的目标用户是完整的用户信息,也就是,把权限也查出来。所以当认证成功,就相当于自动完成授权了。

因此,不管我们要实现什么样的授权方式,只需要实现这三大接口进行扩展即可。PS:暂且不谈后续鉴权,如何处理,不是当前重点。

UserDetailService

Spring Security自己的实现
Spring Security原生的UserDetailService

UserDetailService的实现,有两个:
InMemoryUserDetailsManager是基于内存的,用户信息保存在Map中。
JdbcUserDetailsManager则是基于数据库的,相关的表结构不妨看看其父类org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl的注释

使用JDBC查询从数据库中检索用户详细信息(用户名、密码、启用标志和权限)

包含两个表:“users”和“authorities”

用户表:users

列:username、password、enabled

权限表:authorities

列:username、authority

分组支持

通过将enableGroups属性设置为true,可以启用对基于组的权限的支持

使用这种方法,权限被分配给组,用户的权限基于他们所属的组来确定。

当使用组时,将使用“groups”,“group_members”和“group_authorities”表

PS: 下面的表结构是我补充的

分组表: groups

列:id、group_name

分组成员:group_members

列:username、group_id

分组权限:group_authorities

列:group_id、authority

实际上,我们基本上不会直接使用原生的UserDetailService,因为我们的表不会如此简单。因此通常都是自己实现一个UserDetailService。

UserDetails

public interface UserDetails extends Serializable {

	/**
	 * 返回用户被授予的权限。不能返回null。
	 * @return 被自然顺序排好的权限。不能为null
	 */
	Collection<? extends GrantedAuthority> getAuthorities();

	String getPassword();
	String getUsername();
	boolean isAccountNonExpired();
	boolean isAccountNonLocked();
	boolean isCredentialsNonExpired();
	boolean isEnabled();
}

Spring Security的实现:
org.springframework.security.core.userdetails.User。如果我们只是基于GrantedAuthority扩展的权限实现,用它倒也够用了。

GrantedAuthority

public interface GrantedAuthority extends Serializable {

	/**
	 * 如果是可以用String来表示的权限,那么足以{@link AccessDecisionManager}执行访问控制逻辑了。
     * 只需要返回String就行。
     * 
	 * 如果不能用String来表示,那么应当返回null。而返回null的,将需要一个特定的AccessDecisionManager实现来支持。
     * 所以非必要,应当避免返回null。
     * 
     * @return 返回一个授予的权限(或者当无法用String表示的时候,返回null)
	 */
	String getAuthority();

}

实际上,AccessDecisionManager已经被AuthorizationManager所取代。对应地安全过滤器也存在取代关系。
但个人认为,新的AuthorizationFilter比原来的FilterSecurityInterceptor更加容易理解和掌握,不管是整体设计还是职责。
不过这是后面处理鉴权的时候要聊的,姑且跳过。

GrantedAuthority的简单实现:SimpleGrantedAuthority。
他只存了一个字符串。因此,我们可以基于他来实现一个RBAC的授权方式。不过,这个字符串里面填啥东西,全凭我们在加载UserDetails的时候往里面装啥东西了。你懂的,但可不要乱装哦。

好了,到此三大授权相关的组件就介绍完了。有了此三大组件,想要实现什么授权方式,不是全凭使用者如何定制了嘛。

小结

应该说,Spring Security支持哪些授权方式是不准确的,因为只要基于三大组件进行扩展,怎么都行。
且说Spring Security提供哪些原生支持的授权方式。
从实现上来说,Spring Security提供原生支持授权方式:

  1. 基于角色的访问控制(RBAC): 只是在授权相关的三大组件上,还有在鉴权的支持上:AuthoritiesAuthorizationManager.
  2. 基于属性的访问控制(ABAC):这种方式主要体现在鉴权上,因为用户信息本身就包含用户的相关属性。可以基于Spel实现。
  3. 访问控制列表(ACL):引入ACL依赖实现。

后记

其实在SpringSecurity的文档中, 个人认为Authorization更多代表的是鉴权, 而不是授权. 正如我们前面所说, 授权是在认证之后, 给用户分配权限的过程. 这一点与我们在讨论的授权方式这一概念上有很大区别. 甚至在我们聊到与授权相关的三大组件也没有出现Authorization这一单词的身影. 这也是我最初在概念上犯迷糊的地方.
下一节, 我们先聊聊权限配置. 只有搞懂了怎么配置权限, 我们才能知道怎么样进行鉴权. 至于为什么不从认证开始, 因为认证比较难, 先挑软骨头上手, 容易建立信心.

参照

什么是访问控制?| 授权与身份验证

ASP.NET Core 基于声明的访问控制到底是什么鬼?

  • 16
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Security是一个在Java应用程序中提供身份验证和授权的框架。它通过使用各种身份验证和授权技术,帮助开发人员实现应用程序的安全性。 在Spring Security中,身份验证包括验证用户的身份以确保其是合法的,并且授权包括确定用户是否有权访问特定功能或资源。以下是Spring Security中的一些关键概念和用法: 1. 身份验证:Spring Security提供了许多身份验证机制,例如基于表单的身份验证、基于HTTP基本身份验证、基于LDAP的身份验证等。开发人员可以选择适合他们应用程序需求的身份验证机制。 2. 授权Spring Security使用许可(Permission)和角色(Role)的概念来控制访问权限。可以使用特定的注解或编程方式将这些权限和角色应用到方法或URL上。 3. 认证授权流程:Spring Security认证授权过程中使用了一系列的过滤器和提供者。它们分别负责处理身份验证和授权的不同方面。开发人员可以根据需要定制这些组件来满足自己的应用程序需求。 4. AccessDecisionManager:这是Spring Security中的一个重要组件,用于决定用户是否有权限访问特定的资源或功能。开发人员可以实现自己的AccessDecisionManager来根据自己的逻辑进行权限决策。 5. UserDetails:在Spring Security中,用户信息通过UserDetails接口进行封装。开发人员可以根据自己的需求实现自定义的UserDetails接口,并提供用户的身份验证和授权信息。 6. 匿名认证Spring Security支持为匿名用户建立一个匿名Authentication对象。这样,无需再对匿名用户进行额外的验证,可以直接将其当作正常的Authentication对象来使用。 综上所述,Spring Security提供了全面的身份验证和授权机制来保护应用程序的安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值