SpringSecurity学习笔记(一)springSecurity的整体架构

参考视频,编程不良人。

1、什么是SpringSecurity?

首先我们要知道SpringSecurity是Spring家族中的一员,是基于spring框架提供的一套web应用安全性的完整解决方案,包括可高度定制的认证、授权、鉴权等一系列的流程。
它在和springcloud进行整合时候具有其他的框架无法比拟的优势,因此逐渐成为微服务时代首选的安全框架。

除了SpringSecurity以外还有其他的框架也能够提供安全的支持,比如

  • Shiro:阿帕奇旗下的比较老牌的安全框架,轻量、简单、易于集成、可以单独在Javase环境中使用而不用在spring环境中使用。但是在微服务时代,它的扩展性比较差,显得力不从心。
  • 自定义安全框架:这个一般是有一定的难度的,需要考虑各种防御策略。一般只有比较大型的公司才会有能力自研自己的安全框架。

2、springSecurity的整体架构

SpringSecurity学习笔记(一)springSecurity的整体架构_第1张图片

认证

  • 认证AuthenticationManager

在这里插入图片描述

public interface AuthenticationManager {
    Authentication authenticate(Authentication var1) throws AuthenticationException;
}

返回Authentication 表示认证成功,抛出AuthenticationException表示认证失败。它的实现类有几种
在这里插入图片描述
主要实现类是ProviderManager,它管理着很多AuthenticationPrividor 实例,SpringSecurity允许存在多个AuthenticationPrividor 用来实现多种认证方式。

  • 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维护用户信息

SpringSecurity会将用户的认证信息保存在session中。SecurityContextHolder中维护了Authentication ,方便获取用户的信息。SecurityContextHolder中的数据保存是通过ThrealLocal来实现的,将用户的请求数据和当前处理用户请求的线程绑定在了一起。当用户登录完成之后就会清空SecurityContextHolder中的数据然后将用户的认证信息保存在session中,后面每当有请求过来的时候都会从session中取出用户的认证信息放到SecurityContextHolder中和当前线程绑定在一起,这样就可以实现在controller、service层都能够获取到用户的认证数据,当请求处理完成之后就会将认证信息放回session中然后删除SecurityContextHolder中的数据。

授权

  • 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);
}

AccessDecisionManagerAccessDecisionVoter都有众多的实现类,在AccessDecisionManager 中会遍历所有的AccessDecisionVoter进而判断用户是否拥有对应的访问权限。

  • ConfigAttribute用来保存授权时的角色信息

当一个请求过来的时候AccessDecisionManager会将当前用户的角色封装成ConfigAttribute然后和AccessDecisionVoter进行遍历对比,如果投出了赞成票则用户对该资源有访问权限,否则没有访问权限,抛出异常。

public interface ConfigAttribute extends Serializable {
    String getAttribute();
}

3、springSecurity环境搭建

搭建一个springboot项目编写接口
SpringSecurity学习笔记(一)springSecurity的整体架构_第2张图片
访问测试
SpringSecurity学习笔记(一)springSecurity的整体架构_第3张图片
然后加入我们的security的start依赖

<dependency>
	    <groupId>org.springframework.boot</groupId>
	    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

这个时候我们再启动项目

可以发现启动日志里面多了一条信息

Using generated security password: 40ea0442-79c3-4b2d-ae39-deeb27e3e279

然后我们继续访问刚才的接口
SpringSecurity学习笔记(一)springSecurity的整体架构_第4张图片
发现这里直接跳转到了登录页上面去,原来的接口已经无法直接访问到了。

然后我们登录,使用用户名user,密码40ea0442-79c3-4b2d-ae39-deeb27e3e279,这个就是刚才日志打印的uuid密码。然后就跳转到了正常的接口返回,这个时候访问其他的接口都可以实现访问。
SpringSecurity学习笔记(一)springSecurity的整体架构_第5张图片

4、springSecurity实现原理(官方文档)

以下图片来自官网

在架构上的实现是基于servlet容器中的过滤器来实现的。但是基于过滤器进行了一些封装。
SpringSecurity学习笔记(一)springSecurity的整体架构_第6张图片
DelegatingFilterProxy(委派过滤器代理类)就相当于是一个桥梁,连通servlet容器的生命周期和spring的ApplicationContext。官方大概的意思就是说提供了可以将servlet的过滤器使用springbean的方式来实现。

SpringSecurity学习笔记(一)springSecurity的整体架构_第7张图片

Spring Security的Servlet支持包含在FilterChainProxy中。FilterChainProxy是Spring Security提供的一种特殊过滤器,允许通过SecurityFilterChain委托给许多过滤器实例。由于FilterChainProxy是一个Bean,因此它通常包装在DelegatingFilterProxy中。

SpringSecurity学习笔记(一)springSecurity的整体架构_第8张图片
SpringSecurity学习笔记(一)springSecurity的整体架构_第9张图片

你可能感兴趣的:(springsecurity,架构,学习,java)