AuthenticationManager, ProviderManager 和 AuthenticationProvider

AuthenticationManager是一个接口:

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

ProviderManager是AuthenticationManager的实现类:

public class ProviderManager implements AuthenticationManager, MessageSourceAware,
        InitializingBean {

    ......

    private List<AuthenticationProvider> providers = Collections.emptyList();

    ...... 

    public Authentication authenticate(Authentication authentication)
            throws AuthenticationException {
        ......
        }
}

从以上代码中可以看到ProviderManager有一个List<AuthenticationProvider> providers成员变量。AuthenticationProvider也是一个接口:

public interface AuthenticationProvider {
    Authentication authenticate(Authentication authentication)
            throws AuthenticationException;
    boolean supports(Class<?> authentication);
}

可以看到包含两个成员函数authenticate和supports。

接下来我们看一下整个的认证过程:

认证是通过AuthenticationManager的authenticate函数实现的。也就是通过AuthenticationManager实现类ProviderManager的authenticate函数认证,ProviderManager的authenticate函数会轮训ProviderManager的List<AuthenticationProvider> providers成员变量,如果该providers中如果有一个AuthenticationProvider的supports函数返回true,那么就会调用该AuthenticationProvider的authenticate函数认证,如果认证成功则整个认证过程结束。如果不成功,则继续使用下一个合适的AuthenticationProvider进行认证,只要有一个认证成功则为认证成功。

如果上述过程没有认证成功,且该ProviderManager的成员变量AuthenticationManager parent不为null,那么会使用该parent继续认证。一般不会用到该AuthenticationManager parent,稍微留意以下即可。

另:Authentication

可以看到authenticate函数返回Authentication,Authentication是一个接口,通过该接口可以获得用户相信信息,代码:

public interface Authentication extends Principal, Serializable {
    Collection<? extends GrantedAuthority> getAuthorities();
    Object getCredentials();
    Object getDetails();
    Object getPrincipal();
    boolean isAuthenticated();
    void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;
}

另:DaoAuthenticationProvider

<authentication-provider>默认实例化AuthenticationProvider的一个实现:DaoAuthenticationProvider。DaoAuthenticationProvider通过接口UserDetailsService的实现类从内存或DB中获取用户信息UserDetails(UserDetails十分类似Authentication,也是一个接口,但是与Authentication用途不同,不要搞混)。DaoAuthenticationProvider通过函数authenticate比较入参authentication与UserDetails是否相符,来判断用户是否可以登录。如果相符,会将获得的UserDetails中的信息补全到一个Authentication实现类,并将该实现类作为认证实体返回。以后便可以通过当前上下文的认证实体Authentication获取当前登录用户的信息。

UserDetails代码:

public interface UserDetails extends Serializable {
    Collection<? extends GrantedAuthority> getAuthorities();
    String getPassword();
    String getUsername();
    boolean isAccountNonExpired();
    boolean isAccountNonLocked();
    boolean isCredentialsNonExpired();
    boolean isEnabled();
}

UserDetails和Authentication区别:

接口 目的
Authentication
它存储安全实体的标识、密码以及认证请求
的上下文信息。它还包含用户认证后的信息
(可能会包含一个 UserDetails 的实例)
。通常
不会被扩展,除非是为了支持某种特定类型
的认证。

UserDetails
为了存储一个安全实体的概况信息,包含名
字、e-mail、电话号码等。通常会被扩展以支
持业务需求。

时间: 2024-12-27 07:01:58

AuthenticationManager, ProviderManager 和 AuthenticationProvider的相关文章

OAuth2.0学习(4-4)关于系统中有多少个 authenticationManager

文章参考:http://blog.csdn.net/foggysource/article/details/39456963 首先是http的配置,authentication-manager-ref="authenticationManager"指定了默认的authentication-manager<http auto-config="true" authentication-manager-ref="authenticationManager&

SpringSecurity3.X--remember-me

http://blog.sina.com.cn/s/blog_8020e411010155lf.html SpringSecurity3.X--remember-me (2012-04-20 15:03:14) 转载▼ 标签: it 分类: javaEE 在SpringSecurity中配置remember-me时,遇到这样的问题,remember-me没有起作用,按照官方文档的讲解,只需要在<http>中增加<remember-me />配置,并在login.jsp中增加如下代码

Spring Security 3.1 自定义 authentication provider

前言 在使用Spring Security的时候,遇到一个比较特殊的情况,需要根据用户名.邮箱等多个条件去验证用户或者使用第三方的验证服务来进行用户名和密码的判断,这样SS(Spring Security,一下简称SS)内置的authentication provider和user detail service就不能用了,花了一些时间去寻找其他的办法. 前置条件 Spring MVC 结构的Web项目 Spring Security 使用第三方的Service验证用户名密码(并非数据库或者Ope

Spring Security身份认证之UserDetailsService

zhiqian我们采用了配置文件的方式从数据库中读取用户进行登录.虽然该方式的灵活性相较于静态账号密码的方式灵活了许多,但是将数据库的结构暴露在明显的位置上,绝对不是一个明智的做法.本文通过Java代码实现UserDetailsService接口来实现身份认证. 1.1 UserDetailsService在身份认证中的作用 Spring Security中进行身份验证的是AuthenticationManager接口,ProviderManager是它的一个默认实现,但它并不用来处理身份认证,

spring security使用和原理简析(2)

转自https://pjmike.github.io/2018/10/12/%E6%B5%85%E6%9E%90Spring-Security-%E6%A0%B8%E5%BF%83%E7%BB%84%E4%BB%B6/ 上一篇我们主要讲述了如何搭项目,这里我们就来简单探究一下原理 Spring Security的核心类 Spring Security的核心类主要包括以下几个: SecurityContextHolder: 存放身份信息的容器 Authentication: 身份信息的抽象接口 A

Spring Security 解析(二) —— 认证过程

Spring Security 解析(二) -- 认证过程 ??在学习Spring Cloud 时,遇到了授权服务oauth 相关内容时,总是一知半解,因此决定先把Spring Security .Spring Security Oauth2 等权限.认证相关的内容.原理及设计学习并整理一遍.本系列文章就是在学习的过程中加强印象和理解所撰写的,如有侵权请告知. 项目环境: JDK1.8 Spring boot 2.x Spring Security 5.x 一.@EnableGlobalAuth

springsecurity基于数据库验证用户

之前的springsecurity程序都是将数据存放在内存中的,通过 1 <security:user-service> 2 <security:user name="user" password="user" authorities="ROLE_USER"/> 3 <security:user name="admin" password="admin" authorities

Spring security oauth2最简单入门环境搭建

关于OAuth2的一些简介,见我的上篇blog:http://wwwcomy.iteye.com/blog/2229889 PS:貌似内容太水直接被鹳狸猿干沉.. 友情提示 学习曲线:spring+spring mvc+spring security+Oauth2基本姿势,如果前面都没看过请及时关闭本网页. 我有信心我的这个blog应该是迄今为止使用spring security oauth2最简单的hello world app介绍了,如果你下下来附件源码还看不懂,请留言.. 其他能搜到的如h

SpringSecurity数据库中存储用户、角色、资源

这几天项目中用到了SpringSecurity做登陆安全.所以在这写一下也许可以帮助一下其他人,自己也熟悉一下 SpringSecurity配置文件如下: <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w