SpringSecurity

2020-01-05  本文已影响0人  KnowNothing1998

Spring security主要流程(简单的说)


1. 登录验证拦截器AuthenticationProcessingFilter将用户输入的登录信息封装至Authentication,用户名和密码被过滤器获取到,封装成 Authentication, 通常情况下是 UsernamePasswordAuthenticationToken这个实现类。

2. AuthenticationManager认证管理器调用AuthenticationProvider,再由其调用UserDetailsService获取用户数据,再比对原有Autentication信息,认证成功后,AuthenticationManager 身份管理器返回一个被填充满了信息的(包括上面提到的权限信息,身份信息,细节信息,但密码通常会被移除)Authentication实例。

可以设置多个Provider处理不同的登录方式,ProviderManager 中的 List,会依照次序去认证,认证成功则立即返回,若认证失败则返回 null,下一个 AuthenticationProvider 会继续尝试认证,如果所有认证器都无法认证成功,则 ProviderManager会抛出一个 ProviderNotFoundException 异常。

3.如果需要分权限,那么需要设置FilterInvocationSecurityMetadataSource的方法来获取被拦截url所需的全部权限。

4. 再设置AccessDecisionManager比对用户所具有的权限与当前访问url所需权限是否符合,符合成功访问,不符合抛出异常信息。

5.ExceptionTranslationFilter会对异常进行处理。

认证是由AuthenticationManager 来管理的,但是真正进行认证的是 AuthenticationManager 中定义的 AuthenticationProvider。AuthenticationManager 中可以定义有多个 AuthenticationProvider。当我们使用 authentication-provider 元素来定义一个 AuthenticationProvider 时,如果没有指定对应关联的 AuthenticationProvider 对象,Spring Security 默认会使用 DaoAuthenticationProvider。DaoAuthenticationProvider 在进行认证的时候需要一个 UserDetailsService 来获取用户的信息 UserDetails,其中包括用户名、密码和所拥有的权限等。所以如果我们需要改变认证的方式,我们可以实现自己的 AuthenticationProvider;如果需要改变认证的用户信息来源,我们可以实现 UserDetailsService。

实现了自己的AuthenticationProvider 之后,我们可以在配置文件中这样配置来使用我们自己的 AuthenticationProvider。其中 myAuthenticationProvider 就是我们自己的 AuthenticationProvider 实现类对应的 bean。

如果需要添加自定义认证方式

修改后的多认证方式,更方便扩展。假如要增加一个邮箱+验证码。分成以下几步:

 1. 增加一个token (EmailCodeAuthenticationToken) 

2. 增加一个provider (EmailCodeAuthenticationProvider) 

3. 增加一个filter (EmailCodeAuthenticationProcessingFilter) 

总结

spring security的简单原理:

使用众多的拦截器对url拦截,以此来管理权限。但是这么多拦截器,笔者不可能对其一一来讲,主要讲里面核心流程的两个。

首先,权限管理离不开登陆验证的,所以登陆验证拦截器AuthenticationProcessingFilter要讲;还有就是对访问的资源管理吧,所以资源管理拦截器AbstractSecurityInterceptor要讲;但拦截器里面的实现需要一些组件来实现,所以就有了AuthenticationManager、accessDecisionManager等组件来支撑。

现在先大概过一遍整个流程,用户登陆,会被AuthenticationProcessingFilter拦截,调用AuthenticationManager的实现,而且AuthenticationManager会调用ProviderManager来获取用户验证信息(不同的Provider调用的服务不同,因为这些信息可以是在数据库上,可以是在LDAP服务器上,可以是xml配置文件上等),如果验证通过后会将用户的权限信息封装一个User放到spring的全局缓存SecurityContextHolder中,以备后面访问资源时使用。

访问资源(即授权管理),访问url时,会通过AbstractSecurityInterceptor拦截器拦截,其中会调用FilterInvocationSecurityMetadataSource的方法来获取被拦截url所需的全部权限,在调用授权管理器AccessDecisionManager,这个授权管理器会通过spring的全局缓存SecurityContextHolder获取用户的权限信息,还会获取被拦截的url和被拦截url所需的全部权限,然后根据所配的策略(有:一票决定,一票否定,少数服从多数等),如果权限足够,则返回,权限不够则报错并调用权限不足页面。

上一篇 下一篇

猜你喜欢

热点阅读