小工具知识网

当前位置: 首页 > 行业知识 > 【SpringSecurity】五、UserDetails接口和UserDetailsService接口(原理、流程)

行业知识

【SpringSecurity】五、UserDetails接口和UserDetailsService接口(原理、流程)

2026-11-11 16:59:43 来源:互联网转载

文章目录

  • 1、SpringSecurity原理
  • 2、重要接口源码
    • AuthenticationProvider
    • Authentication
    • UserDetails
    • UserDetailsService
    • 3、授权流程
    • 4、UserDetails接口
    • 5、UserDetailService接口
    • 6、权限配置

      1、SpringSecurity原理

      Spring Security是做安全访问控制,对所有进入系统的请求进行拦截,并做校验,这可以通过Filter或者AOP实现,Spring Security靠Filter。

      • 初始化Spring Security时,创建一个名为SpringSecurityFilterChain的Servlet过滤器,类型为org.springframework.security.web.FilterChainProxy,它实现了javax.servlet.Filter,因此外部的请求会经过此类
      • FilterChainProxy是一个代理,真正起作用的是FilterChainProxy中SecurityFilterChain所包含的各个Filter,同时这些Filter作为Bean被Spring管理
      • 这些Filter不负责认证或者授权,而是交给认证管理器(AuthenticationManager)和决策管理器(AccessDecisionManager)进行处理。(过滤器嘛,就是拦截下,获取点东西、修改点东西、干点操作)

        Spring Security功能的实现就是一系列过滤器链相互配合。

        • SecurityContextPersistenceFilter 这个Filter是整个拦截过程的入口和出口,也就是第一个和最后一个拦截器。会在请求开始时从配置好的 SecurityContextRepository 中获取 SecurityContext,然后把它设置给 SecurityContextHolder。在请求完成后将 SecurityContextHolder 持有的 SecurityContext 再保存到配置好的 SecurityContextRepository,同时清除 securityContextHolder 所持有的 SecurityContext;

        • UsernamePasswordAuthenticationFilter 用于处理来自表单提交的认证,该表单必须提供对应的用户名和密码,其内部还有登录成功或失败后进行处理的 AuthenticationSuccessHandler 和 AuthenticationFailureHandler,这些都可以根据需求做相关改变;(这些处理器的逻辑可自定义,重新实现一下这个处理器)

        • ExceptionTranslationFilter 能够捕获来自 FilterChain 所有的异常,并进行处理。但是它只会处理两类异常:AuthenticationException 和 AccessDeniedException,其它的异常它会继续抛出。

        • FilterSecurityInterceptor 是用于保护web资源的,使用AccessDecisionManager对当前用户进行授权访问

          SpringSecurity的执行流程:

          • 用户提交用户名密码,被安全过滤器链中的UsernamePasswordAuthenticationFilter过滤器拿到,并封装为请求Authentication,通常情况下是UsernamePasswordAuthenticationToken这个实现类
          • 然后过滤器将Authentication提交至认证管理器(AuthenticationManager)进行认证
          • 认证成功后,AuthenticationManager身份管理器返回一个被填充满了信息的(包括上面提到的权限信息,身份信息,细节信息,但密码通常会被移除)Authentication实例
          • SecurityContextHolder安全上下文容器将上一步填充了信息的Authentication,通过SecurityContextHolder.getContext().setAuthentication(…)方法,设置到其中
          • 以看出AuthenticationManager接口(认证管理器)是认证相关的核心接口,也是发起认证的出发点,它的实现类为ProviderManager
          • 而Spring Security支持多种认证方式,因此ProviderManager维护着一个List列表,存放多种认证方式,不同的认证方式用不同的AuthenticationProvider实现类,最终实际的认证工作是由AuthenticationProvider完成的。而web表单的对应的AuthenticationProvider实现类为DaoAuthenticationProvider,它的内部又维护着一个UserDetailsService负责UserDetails的获取。当UserDetailsService接口的loadUserByUsername()方法获取到的User Details对象中的密码和Authentication中的密码一致时,认证成功,最后AuthenticationProvider将UserDetails填充至Authentication

            总之,整个框架中,AuthenticationProvider(DaoAuthenticationProvider)承上启下,而通过实现UserDetailsService和UserDetails,可以完成对用户信息获取方式以及用户信息字段的扩展。

            2、重要接口源码

            AuthenticationProvider

            认证管理器AuthenticationManager委托AuthenticationProvider完成认证工作,AuthenticationProvider接口定义如下:

            public interface AuthenticationProvider {Authentication authenticate(Authentication authentication) throws AuthenticationException;//supports方法来表明自己支持的认证方式boolean supports(Class var1);}

            authenticate()方法定义了认证的实现过程。传参为Authentication,里面包含登录用户所提交的用户名密码等。返回也是Authentication对象,且是一个认证通过后,被填充权限等信息的Authentication。

            supports方法来表明自己支持的认证方式。如使用表单方式认证,在提交请求时Spring Security会生成UsernamePasswordAuthenticationToken(Authentication的子类),里面封装着用户提交的用户名、密码信息。

            //当web表单提交用户名密码时,Spring Security由DaoAuthenticationProvider处理//其supports方法中就是UsernamePasswordAuthenticationToken.classpublic boolean supports(Class authentication) {return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);}

            Authentication

            Authentication继承自Principal,Principal是框架用来表示一个抽象主体的类(如人、用户、公司),任何主体都有名称,因此其有个getName方法

            Authentication源码如下:

            public interface Authentication extends Principal, Serializable { //获取权限信息列表,默认是GrantedAuthority接口的一些实现类Collection

上一篇:数据结构从入门到精通——栈

下一篇:JS箭头实现图片翻图功能,轻松掌握的核心技巧