spring security认证流程
大概流程如下:
面试话术:
1.客户端提交用户登陆表单,通过UsernamePasswordAuthenticationFilter后,会被封装成一个authentication对象。
2.同时会调用AuthenticationManager的实现类ProviderManager中的authenticate方法。该方法会去DaoAuthenticationProvider中调用loadUserByUsername。它会去数据库查询我们的用户信息,包括权限等,然后返回一个userDetails对象。
3.然后会通过passwordEncoder来对比authentication对象和userDetails对象中的密码正不正确。正确则将userDetails对象中的信息设置到authentication对象中。返回给UsernamePasswordAuthenticationFilter,最后将信息设置到写入到SecurityContextHolder中SecurityContext的属性authentication上面。其他过滤器依靠其信息作过滤判断。
以下内容可忽略
以下内容可忽略
jwt+springsecurity具体实现:
①引入依赖。登陆实体类实现userdetail。重写getAuthorities();
②写登陆接口,传入用户名和密码,验证码以及request等
③request.getSession().getAttribute(“captcha”);获得验证码并比较
④用userDetailsService.loadUserByUsername(username);判断提交的与数据库的是否一致
⑤用passwordEncoder.matches(password, userDetails.getPassword()比较密码
⑥判断是否处于禁用状态,然后用new UsernamePasswordAuthenticationToken
(userDetails , null, userDetails.getAuthorities());获得authenticationToken。
⑦用authenticationToken更新登陆对象,用userDetails生成token
⑧用map存入token和tokenHead并返回
对于security:
①配置类需要继承websecurityconfigadapter,重写三个configure,一个用来放行,哪些请求路径不需过滤
一个用来解析比较密码是否一致,指定了BCryptPasswordEncoder作为加密后比较
另一个用来指定使用jwt作为请求过滤,可以添加addFilterBefore来自定义jwt登陆授权过滤器,以及一些未授权和未登录的返回结果。
同时还能用withObjectPostProcessor来实现动态权限配置:
object.setAccessDecisionManager(customUrlDecisionManager);
object.setSecurityMetadataSource(customFilter);
②重写了UserDetailsService,来设置角色。
判断用户角色:implements AccessDecisionManager
判断url需要什么角色:implements FilterInvocationSecurityMetadataSource
判断是否登陆或者token失效,即认证失败时:implements AuthenticationEntryPoint
判断没有权限时:implements AccessDeniedHandler
自定义jwt过滤器:extends OncePerRequestFilter::::JwtAuthencationTokenFilter extends OncePerRequestFilter
登陆认证流程:
客户端发起一个请求,进入 Security 过滤器链。
1.当到 LogoutFilter 的时候判断是否是登出路径,
如果是登出路径则到 logoutHandler ,如果登出成功则到 logoutSuccessHandler 登出成功处理。
如果不是登出路径则直接进入下一个过滤器。
2.当到 UsernamePasswordAuthenticationFilter 的时候判断是否为登录路径,
如果是,则进入该过滤器进行登录操作,如果登录失败则到 AuthenticationFailureHandler ,
登录失败处理器处理,如果登录成功则到 AuthenticationSuccessHandler 登录成功处理器处理,如果不是登录请求则不进入该过滤器。
3.进入认证BasicAuthenticationFilter进行用户认证,
成功的话会把认证了的结果写入到SecurityContextHolder中SecurityContext的属性authentication上面。
如果认证失败就会交给AuthenticationEntryPoint认证失败处理类,或者抛出异常被后续ExceptionTranslationFilter过滤器处理异常,
如果是AuthenticationException就交给AuthenticationEntryPoint处理,如果是AccessDeniedException异常则交给AccessDeniedHandler处理。
4.当到 FilterSecurityInterceptor 的时候会拿到 uri ,根据 uri 去找对应的鉴权管理器,
鉴权管理器做鉴权工作,鉴权成功则到 Controller 层,否则到 AccessDeniedHandler 鉴权失败处理器处理。