2.Spring security环境搭建、实现原理、流程分析

创建项目

spring boot
spring security

  • 认证:判断用户是否是系统合法用户过程
  • 授权:判断系统内用户可以访问或具有访问哪些资源权限

1.创建springboot应用

在这里插入图片描述

2.创建controller

@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String Hello(){
        System.out.println("spring security");
        return "hello spring security";
    }
}

在这里插入图片描述

3.启动项目进行测试

在这里插入图片描述

整合Spring Security

1.引入spring security依赖

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

2.再次启动项目

  • 启动项目后在控制台会生成一个密码
  • 访问hello发现直接跳转到登录页面
    在这里插入图片描述在这里插入图片描述

3.登录系统

  • 默认用户名:user
  • 默认密码:控制台输出的uuid
    在这里插入图片描述
    在这里插入图片描述

这就是Spring Security 的强大之处,只需要引入一个依赖,所有的接口就会自动保护起来!

思考?

  • 为什么引入Spring Security之后没有任何配所有请求就要认证呢?
  • 在项目中明明没有登录界面,登录界面怎么来的呢?
  • 为什么使用user和 控制台密码能登陆,登录时验证数据源存在哪里呢?

实现原理

在 Spring Security 中 认证、授权 等功能都是基于过滤器完成的。

在这里插入图片描述

在这里插入图片描述

需要注意的是,默认过滤器并不是直接放在 Web 项目的原生过滤器链中,而是通过一FilterChainProxy 来统一管理。Spring Security 中的过滤器链通过 FilterChainProxy 嵌入到 Web项目的原生过滤器链中。FilterChainProxy 作为一个顶层的管理者,将统一管理 Security Filter。FilterChainProxy 本身是通过 Spring 框架提供的 DelegatingFilterProxy 整合到原生的过滤器链中。

Security Filters

过滤器过滤器作用默认是否加载
ChannelProcessingFilter过滤请求协议 HTTP 、HTTPSNO
WebAsyncManagerIntegrationFilter将 WebAsyncManger 与 SpringSecurity 上下文进行集成YES
SecurityContextPersistenceFilter在处理请求之前,将安全信息加载到 SecurityContextHolder 中YES
HeaderWriterFilter处理头信息加入响应中YES
CorsFilter处理跨域问题NO
CsrfFilter处理 CSRF 攻击YES
LogoutFilter处理注销登录YES
OAuth2AuthorizationRequestRedirectFilter处理 OAuth2 认证重定向NO
Saml2WebSsoAuthenticationRequestFilter处理 SAML 认证NO
X509AuthenticationFilter处理 X509 认证NO
AbstractPreAuthenticatedProcessingFilter处理预认证问题NO
CasAuthenticationFilter处理 CAS 单点登录NO
OAuth2LoginAuthenticationFilter处理 OAuth2 认证NO
Saml2WebSsoAuthenticationFilter处理 SAML 认证NO
UsernamePasswordAuthenticationFilter处理表单登录YES
OpenIDAuthenticationFilter处理 OpenID 认证NO
DefaultLoginPageGeneratingFilter配置默认登录页面YES
DefaultLogoutPageGeneratingFilter配置默认注销页面YES
ConcurrentSessionFilter处理 Session 有效期NO
DigestAuthenticationFilter处理 HTTP 摘要认证NO
BearerTokenAuthenticationFilter处理 OAuth2 认证的 Access TokenNO
BasicAuthenticationFilter处理 HttpBasic 登录YES
RequestCacheAwareFilter处理请求缓存YES
SecurityContextHolder<br />AwareRequestFilter包装原始请求YES
JaasApiIntegrationFilter处理 JAAS 认证NO
RememberMeAuthenticationFilter处理 RememberMe 登录NO
AnonymousAuthenticationFilter配置匿名认证YES
OAuth2AuthorizationCodeGrantFilter处理OAuth2认证中授权码NO
SessionManagementFilter处理 session 并发问题YES
ExceptionTranslationFilter处理认证/授权中的异常YES
FilterSecurityInterceptor处理授权相关YES
SwitchUserFilter处理账户切换NO

可以看出,Spring Security 提供了 30 多个过滤器。默认情况下Spring Boot 在对 Spring Security 进入自动化配置时,会创建一个名为 SpringSecurityFilerChain 的过滤器,并注入到 Spring 容器中,这个过滤器将负责所有的安全管理,包括用户认证、授权、重定向到登录页面等。

SpringBootWebSecurityConfiguration

这个类是 spring boot 自动配置类,通过这个源码得知,默认情况下对所有请求进行权限控制:

@Configuration(proxyBeanMethods = false)
@ConditionalOnDefaultWebSecurity
@ConditionalOnWebApplication(type = Type.SERVLET)
class SpringBootWebSecurityConfiguration {
	@Bean
	@Order(SecurityProperties.BASIC_AUTH_ORDER)
	SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) 
    throws Exception {
			http.authorizeRequests().anyRequest()
      .authenticated().and().formLogin().and().httpBasic();
		return http.build();
	}
}

在这里插入图片描述这就是为什么在引入 Spring Security 中没有任何配置情况下,请求会被拦截的原因

通过上面对自动配置分析,我们也能看出默认生效条件为:

  • 条件一 classpath中存在 SecurityFilterChain.class, HttpSecurity.class
  • 条件二 没有自定义 WebSecurityConfigurerAdapter.class, SecurityFilterChain.class

默认情况下,条件都是满足的。WebSecurityConfigurerAdapter 这个类极其重要,Spring Security 核心配置都在这个类中:
在这里插入图片描述
如果要对 Spring Security 进行自定义配置,就要自定义这个类实例,通过覆盖类中方法达到修改默认配置的目的。

流程分析

在这里插入图片描述

  1. 请求 /hello 接口,在引入 spring security 之后会先经过一些列过滤器
  2. 在请求到达 FilterSecurityInterceptor时,发现请求并未认证。请求拦截下来,并抛出 AccessDeniedException 异常。
  3. 抛出 AccessDeniedException 的异常会被 ExceptionTranslationFilter 捕获,这个 Filter 中会调用 LoginUrlAuthenticationEntryPoint#commence 方法给客户端返回 302,要求客户端进行重定向到 /login 页面。
  4. 客户端发送 /login 请求。
  5. /login 请求会再次被拦截器中 DefaultLoginPageGeneratingFilter 拦截到,并在拦截器中返回生成登录页面。

就是通过这种方式,Spring Security 默认过滤器中生成了登录页面,并返回!

默认用户生成

  1. 查看 SpringBootWebSecurityConfiguration#defaultSecurityFilterChain 方法表单登录
    在这里插入图片描述
    2.处理登录为 FormLoginConfigurer 类中 调用 UsernamePasswordAuthenticationFilter这个类实例
    在这里插入图片描述3.查看类中 UsernamePasswordAuthenticationFilter#attempAuthentication 方法得知实际调用 AuthenticationManager 中 authenticate 方法
    在这里插入图片描述4.调用 ProviderManager 类中方法 authenticate
    在这里插入图片描述
    5.调用了 ProviderManager 实现类中 AbstractUserDetailsAuthenticationProvider类中方法
    在这里插入图片描述
    6.最终调用实现类 DaoAuthenticationProvider 类中方法比较
    在这里插入图片描述

在这里插入图片描述看到这里就知道默认实现是基于 InMemoryUserDetailsManager 这个类,也就是内存的实现!

UserDetailService

通过刚才源码分析也能得知 UserDetailService 是顶层父接口,接口中 loadUserByUserName 方法是用来在认证时进行用户名认证方法,默认实现使用是内存实现,如果想要修改数据库实现我们只需要自定义 UserDetailService 实现,最终返回 UserDetails 实例即可。

public interface UserDetailsService {
	UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}

在这里插入图片描述

总结

  • AuthenticationManager、ProviderManger、以及 AuthenticationProvider 关系

在这里插入图片描述

  • WebSecurityConfigurerAdapter扩展 Spring Security 所有默认配置
    在这里插入图片描述
  • UserDetailService 用来修改默认认证的数据源信息
    在这里插入图片描述
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个双子座的Java攻城狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

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

抵扣说明:

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

余额充值