大家好,我是卷心菜。本篇主要讲解Spring Security的基本介绍和架构分析,如果您看完文章有所收获,可以三连支持博主哦~,嘻嘻。
作者简介:在校大学生一枚,Java领域新星创作者,Java、Python正在学习中,期待和大家一起学习一起进步~
个人主页:我是一棵卷心菜的个人主页
本文专栏:Spring Security知识学习
自我提醒:多学多练多思考,编程能力才能节节高!
官方文档:
https://spring.io/projects/spring-security
Spring Security是⼀个功能强大、可高度定制的身份验证
和访问控制
框架。它是保护基于Spring的应用程序的事实标准。
Spring Security是⼀个面向Java应用程序框架。与所有Spring项目⼀样,Spring Security的真正威力在于它可以轻松地扩展以满足定制需求。
认证
和授权
。简单来说,认证就是用户的登录认证;授权就是登录成功之后,用户可以访问资源的多少。基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制 ,按照安全规则 或者 安全策略控制用户 可以访问而且只能访问自己被授权的资源。权限管理包括用户身份认证和授权两部分,简称认证授权。对于需要访问控制的资源用户首先经过身份认证,认证通过后用户具有该资源的访问权限才可访问。
认证 ,就是判断⼀个用户是否为合法用户的处理过程。最常用的简单身份认证方式是系统通过核对用户输入的用户名和口令(密码),看其是否与系统中存储的该用户的用户名和口令⼀致,来判断用户身份是否正确。这就好比我们登录QQ、微信、游戏账号等等需要的账号和密码~
授权 ,即访问控制,控制谁能访问哪些资源。主体进行身份认证后需要分配权限才可访问系统的资源,对于某些资源没有权限是无法访问的。这就好比学校的网站,有学生可以访问的资源,然而老师的资源学生就无法访问~
在Spring Security的架构设计中, 认证
和 授权
是分开的,但无论使用什么样的认证方式。都不会影响授权,这是两个独立的存在,这种独立带来的好处之⼀,就是可以非常方便地整合⼀些外部的方案。
AuthenticationManager
接口,在Spring Security中认证是由 AuthenticationManager 来负责的,接口定义为:public interface AuthenticationManager {
Authentication authenticate(Authentication var1)
throws AuthenticationException;
}
注意:当返回Authentication 时,表示认证成功;当返回AuthenticationException异常时,表示认证失败。
AuthenticationManager 主要实现类为 ProviderManager,在 ProviderManager 中管理了众多AuthenticationProvider实例。在⼀次完整的认证流程中,Spring Security允许存在多个
AuthenticationProvider ,用来实现多种认证方式,这些 AuthenticationProvider 都是由
ProviderManager 进行统⼀管理的。
Authentication
接口,认证以及认证成功的信息主要是由 Authentication 的实现类进行保存的,接口定义如下:public interface Authentication extends Principal, Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
Object getCredentials();
Object getDetails();
Object getPrincipal();
boolean isAuthenticated();
void setAuthenticated(boolean var1) throws IllegalArgumentException;
}
方法介绍:
SecurityContextHolder
类,SecurityContextHolder 用来获取登录之后用户信息。定义如下(省略了一些属性和方法):public class SecurityContextHolder {
public static void clearContext() {
strategy.clearContext();
}
public static SecurityContext getContext() {
return strategy.getContext();
}
public static int getInitializeCount() {
return initializeCount;
}
public static void setContext(SecurityContext context) {
strategy.setContext(context);
}
public static void setStrategyName(String strategyName) {
strategyName = strategyName;
initialize();
}
public static SecurityContextHolderStrategy getContextHolderStrategy() {
return strategy;
}
public static SecurityContext createEmptyContext() {
return strategy.createEmptyContext();
}
public String toString() {
return "SecurityContextHolder[strategy='" + strategyName + "'; initializeCount=" + initializeCount + "]";
}
}
AccessDecisionManager
和AccessDecisionVoter
。AccessDecisionManager (访问决策管理器),用来决定此次访问是否被允许。接口定义如下:
public interface AccessDecisionManager {
void decide(Authentication var1, Object var2, Collection<ConfigAttribute> var3) throws AccessDeniedException, InsufficientAuthenticationException;
boolean supports(ConfigAttribute var1);
boolean supports(Class<?> var1);
}
AccessDecisionVoter (访问决定投票器),投票器会检查⽤户是否具备应有的角色,进而投出赞成、反对或者弃权票。接口定义如下:
public interface AccessDecisionVoter<S> {
int ACCESS_GRANTED = 1;
int ACCESS_ABSTAIN = 0;
int ACCESS_DENIED = -1;
boolean supports(ConfigAttribute var1);
boolean supports(Class<?> var1);
int vote(Authentication var1, S var2, Collection<ConfigAttribute> var3);
}
需要注意的是:AccessDecisionManager中会挨个遍历 AccessDecisionVoter,进而决定是否允许用户访问。
ConfigAttribute,用来保存授权时的角色信息。接口定义如下:
public interface ConfigAttribute extends Serializable {
String getAttribute();
}
ROLE_
前缀,投票器AccessDecisionVoter 所做的事情,其实就是比较用户所具各的角色和请求某个资源所需的 ConfigAtuibute 之间的关系。感谢阅读,一起进步,嘻嘻~