当前位置:   article > 正文

集成SpringSecurity+后期可加入JWT_认证过滤器和授权过滤器

认证过滤器和授权过滤器

目录

自定义认证授权过滤器

1、SpringSecurity内置认证流程

1.1 自定义认证过滤器

1.1 注入对应的bean

1.3 定义SecurityConfig类


自定义认证授权过滤器

1、SpringSecurity内置认证流程

通过研究SpringSecurity内置基于form表单认证的UsernamePasswordAuthenticationFilter过滤器,我们可以仿照自定义认证过滤器:

内置认证过滤器的核心流程:

核心流程梳理如下:

  • 认证过滤器(UsernamePasswordAuthentionFilter)接收form表单提交的账户、密码信息,并封装成UsernamePasswordAuthenticationToken认证凭对象;

  • 认证过滤器调用认证管理器AuthenticationManager进行认证处理;

  • 认证管理器通过调用用户详情服务获取用户详情UserDetails;

  • 认证管理器通过密码匹配器PasswordEncoder进行匹配,如果密码一致,则将用户相关的权限信息一并封装到Authentication认证对象中;

  • 认证过滤器将Authentication认证过滤器放到认证上下文,方便请求从上下文获取认证信息;

    1.1 自定义认证过滤器

    UsernamePasswordAuthentionFilter过滤器继承了模板认证过滤器AbstractAuthenticationProcessingFilter抽象类,我们也可仿照实现:

    1. public class MyUserNamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
    2. /**
    3. * 设置构造,传入自定义登录url地址
    4. * @param defaultFilterProcessesUrl
    5. */
    6. public MyUserNamePasswordAuthenticationFilter(String defaultFilterProcessesUrl) {
    7. super(defaultFilterProcessesUrl);
    8. }
    9. @Override
    10. public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
    11. //判断请求方法必须是post提交,且提交的数据的内容必须是application/json格式的数据
    12. if (!request.getMethod().equals("POST") ||
    13. ! (request.getContentType().equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE) || request.getContentType().equalsIgnoreCase(MediaType.APPLICATION_JSON_UTF8_VALUE))) {
    14. throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
    15. }
    16. //获取请求参数
    17. //获取reqeust请求对象的发送过来的数据流
    18. ServletInputStream in = request.getInputStream();
    19. //将数据流中的数据反序列化成Map
    20. HashMap<String,String> loginInfo = new ObjectMapper().readValue(in, HashMap.class);
    21. String username = loginInfo.get(USER_NAME);
    22. username = (username != null) ? username : "";
    23. username = username.trim();
    24. String password = loginInfo.get(PASSWORD);
    25. password = (password != null) ? password : "";
    26. //将用户名和密码信息封装到认证票据对象下
    27. UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
    28. // Allow subclasses to set the "details" property
    29. //setDetails(request, authRequest);
    30. //调用认证管理器认证指定的票据对象
    31. return this.getAuthenticationManager().authenticate(authRequest);
    32. }
    33. /**
    34. * 认证成功处理方法
    35. * @param request
    36. * @param response
    37. * @param chain
    38. * @param authResult
    39. * @throws IOException
    40. * @throws ServletException
    41. */
    42. @Override
    43. protected void successfulAuthentication(HttpServletRequest request,
    44. HttpServletResponse response,
    45. FilterChain chain,
    46. Authentication authResult) throws IOException, ServletException {
    47. response.getWriter().write("login success 666.....");
    48. }
    49. /**
    50. * 认证失败处理方法
    51. * @param request
    52. * @param response
    53. * @param failed
    54. * @throws IOException
    55. * @throws ServletException
    56. */
    57. @Override
    58. protected void unsuccessfulAuthentication(HttpServletRequest request,
    59. HttpServletResponse response,
    60. AuthenticationException failed) throws IOException, ServletException {
    61. response.getWriter().write("login failue 999");
    62. }
    63. }

    自己定义后要注入对应的bean

  • 1.2 注入对应的bean

    1. @Service("userDetailsService")
    2. public class MyUserDetailServiceImpl implements UserDetailsService {
    3. @Autowired
    4. private TbUserMapper tbUserMapper;
    5. /**
    6. * 使用security当用户认证时,会自动将用户的名称注入到该方法中
    7. * 然后我们可以自己写逻辑取加载用户的信息,然后组装成UserDetails认证对象
    8. * @param userName
    9. * @return 用户的基础信息,包含密码和权限集合,security底层会自动比对前端输入的明文密码
    10. * @throws UsernameNotFoundException
    11. */
    12. @Override
    13. public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
    14. //1.根据用户名称获取用户的账户信息
    15. TbUser dbUser=tbUserMapper.findUserInfoByName(userName);
    16. //判断该用户是否存在
    17. if (dbUser==null) {
    18. throw new UsernameNotFoundException("用户名输入错误!");
    19. }
    20. //2.组装UserDetails对象
    21. //获取当前用户对应的权限集合(自动将以逗号间隔的权限字符串封装到权限集合中)
    22. List<GrantedAuthority> list = AuthorityUtils.commaSeparatedStringToAuthorityList(dbUser.getRoles());
    23. /*
    24. 参数1:账户
    25. 参数2:密码
    26. 参数3:权限集合
    27. */
    28. User user = new User(dbUser.getUsername(), dbUser.getPassword(), list);
    29. return user;
    30. }
    31. }

    1.3 定义SecurityConfig类

    配置默认认证过滤器,保证自定义的认证过滤器要在默认的认证过滤器之前;

    1. /**
    2. * 配置授权策略
    3. * @param http
    4. * @throws Exception
    5. */
    6. @Override
    7. protected void configure(HttpSecurity http) throws Exception {
    8. http.csrf().disable();//禁用跨站请求伪造
    9. http.authorizeRequests()//对资源进行认证处理
    10. .antMatchers("/authentication/form").permitAll()//登录路径无需拦截
    11. .anyRequest().authenticated(); //除了上述资源外,其它资源,只有 认证通过后,才能有权访问
    12. http
    13. //坑-过滤器要添加在默认过滤器之前,否则,登录失效
    14. .addFilterBefore(myUserNamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    15. }
    16. @Bean
    17. public MyUserNamePasswordAuthenticationFilter myUserNamePasswordAuthenticationFilter() throws Exception {
    18. //设置默认登录路径
    19. MyUserNamePasswordAuthenticationFilter myUserNamePasswordAuthenticationFilter =
    20. new MyUserNamePasswordAuthenticationFilter("/authentication/form");
    21. myUserNamePasswordAuthenticationFilter.setAuthenticationManager(authenticationManagerBean());
    22. return myUserNamePasswordAuthenticationFilter;
    23. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/870214
推荐阅读
相关标签
  

闽ICP备14008679号