Spring Security做JWT认证与授权
发布时间:2023-03-25 14:14:49 所属栏目:教程 来源:
导读:自定义的 Provider -> DaoAuthenticationProvider -> AbstractUserDetailsAuthenticationProvider -> AuthenticationProvider
ProviderManager -> AuthenticationManager
自定义的 UsernamePasswordAuthentica
ProviderManager -> AuthenticationManager
自定义的 UsernamePasswordAuthentica
自定义的 Provider -> DaoAuthenticationProvider -> AbstractUserDetailsAuthenticationProvider -> AuthenticationProvider ProviderManager -> AuthenticationManager 自定义的 UsernamePasswordAuthenticationToken -> UsernamePasswordAuthenticationToken -> AbstractAuthenticationToken -> Authentication -> Principal Spring Security的架构 按照惯例,在使用之前我们先讲一下简单的架构。不知道是因为spring-security后出来还是因为优秀的设计殊途同归,对于核心模块,spring-security和shiro有80%以上的设计相似度。所以下面介绍中会多跟shiro做对比,如果你对shiro不了解也没关系,跟shiro对比的部分跳过就好。 spring-security中核心概念 AuthenticationManager,用户认证的管理类,所有的认证请求(比如login)都会通过提交一个token给AuthenticationManager的authenticate()方法来实现。当然事情肯定不是它来做,具体校验动作会由AuthenticationManager将请求转发给具体的实现类来做。根据实现反馈的结果再调用具体的Handler来给用户以反馈。这个类基本等同于shiro的SecurityManager。 AuthenticationProvider,认证的具体实现类,一个provider是一种认证方式的实现,比如提交的用户名密码我是通过和DB中查出的user记录做比对实现的,那就有一个DaoProvider;如果我是通过CAS请求单点登录系统实现,那就有一个CASProvider。这个是不是和shiro的Realm的定义很像?基本上你可以帮他们当成同一个东西。按照Spring一贯的作风,主流的认证方式它都已经提供了默认实现,比如DAO、LDAP、CAS、OAuth2等。 前面讲了AuthenticationManager只是一个代理接口,真正的认证就是由AuthenticationProvider来做的。一个AuthenticationManager可以包含多个Provider,每个provider通过实现一个support方法来表示自己支持那种Token的认证。AuthenticationManager默认的实现类是ProviderManager。 UserDetailService,用户认证通过Provider来做,所以Provider需要拿到系统已经保存的认证信息,获取用户信息的接口spring-security抽象成UserDetailService。虽然叫Service,但是我更愿意把它认为是我们系统里经常有的UserDao。 AuthenticationToken,所有提交给AuthenticationManager的认证请求都会被封装成一个Token的实现,比如最容易理解的UsernamePasswordAuthenticationToken。这个就不多讲了,连名字都跟Shiro中一样。 SecurityContext,当用户通过认证之后,就会为这个用户生成一个唯一的SecurityContext,里面包含用户的认证信息Authentication。通过SecurityContext我们可以获取到用户的标识Principle和授权信息GrantedAuthrity。在系统的任何地方只要通过SecurityHolder.getSecruityContext()就可以获取到SecurityContext。在Shiro中通过SecurityUtils.getSubject()到达同样的目的。 我们大概通过一个认证流程来认识下上面几个关键的概念 毫无疑问,对于spring框架使用最多的还是web系统。对于web系统来说进入认证的最佳入口就是Filter了。spring security不仅实现了认证的逻辑,还通过filter实现了常见的web攻击的防护。 常用Filter 下面按照request进入的顺序列举一下常用的Filter: SecurityContextPersistenceFilter,用于将SecurityContext放入Session的Filter UsernamePasswordAuthenticationFilter,登录认证的Filter,类似的还有CasAuthenticationFilter,BasicAuthenticationFilter等等。在这些Filter中生成用于认证的token,提交到AuthenticationManager,如果认证失败会直接返回。 RememberMeAuthenticationFilter,通过cookie来实现remember me功能的Filter AnonymousAuthenticationFilter,如果一个请求在到达这个filter之前SecurityContext没有初始化,则这个filter会默认生成一个匿名SecurityContext。这在支持匿名用户的系统中非常有用。 ExceptionTranslationFilter,捕获所有Spring Security抛出的异常,并决定处理方式 FilterSecurityInterceptor, 权限校验的拦截器,访问的url权限不足时会抛出异常 Filter的顺序 既然用了上面那么多filter,它们在FilterChain中的先后顺序就显得非常重要了。对于每一个系统或者用户自定义的filter,spring security都要求必须指定一个order,用来做排序。对于系统的filter的默认顺序,是在一个FilterComparator类中定义的,核心实现如下。 FilterComparator() { int order = 100; put(ChannelProcessingFilter.class,order); order += STEP; put(ConcurrentSessionFilter.class,order); order += STEP; put(WebAsyncManagerIntegrationFilter.class,order); order += STEP; put(SecurityContextPersistenceFilter.class,order); order += STEP; put(HeaderWriterFilter.class,order); order += STEP; put(CorsFilter.class,order); order += STEP; put(CsrfFilter.class,order); order += STEP; put(logoutFilter.class,order); order += STEP; filterToOrder.put( "org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter",order); order += STEP; put(X509AuthenticationFilter.class,order); order += STEP; put(AbstractPreAuthenticatedProcessingFilter.class,order); order += STEP; filterToOrder.put("org.springframework.security.cas.web.CasAuthenticationFilter",order); order += STEP; filterToOrder.put( "org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter",order); order += STEP; put(UsernamePasswordAuthenticationFilter.class,order); order += STEP; filterToOrder.put( "org.springframework.security.openid.OpenIDAuthenticationFilter",order); order += STEP; put(DefaultLoginPageGeneratingFilter.class,order); order += STEP; put(DigestAuthenticationFilter.class,order); order += STEP; put(BasicAuthenticationFilter.class,order); order += STEP; put(RequestCacheAwareFilter.class,order); order += STEP; put(SecurityContextHolderAwareRequestFilter.class,order); order += STEP; put(JaasApiIntegrationFilter.class,order); order += STEP; put(RememberMeAuthenticationFilter.class,order); order += STEP; put(AnonymousAuthenticationFilter.class,order); order += STEP; put(SessionManagementFilter.class,order); order += STEP; put(ExceptionTranslationFilter.class,order); order += STEP; put(FilterSecurityInterceptor.class,order); order += STEP; put(SwitchUserFilter.class,order); } (编辑:汽车网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐