Spring Security实现不同接口安全策略方法详解

 更新时间:2020年09月04日 09:40:48   作者:码农小胖哥  
这篇文章主要介绍了Spring Security实现不同接口安全策略方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

1. 前言

欢迎阅读 Spring Security 实战干货 系列文章 。最近有开发小伙伴提了一个有趣的问题。他正在做一个项目,涉及两种风格,一种是给小程序出接口,安全上使用无状态的JWT Token;另一种是管理后台使用的是Freemarker,也就是前后端不分离的Session机制。用Spring Security该怎么办?

2. 解决方案

我们可以通过多次继承WebSecurityConfigurerAdapter构建多个HttpSecurity。HttpSecurity 对象会告诉我们如何验证用户的身份,如何进行访问控制,采取的何种策略等等。

我们是这么配置的:

/**
 * 单策略配置
 *
 * @author felord.cn
 * @see org.springframework.boot.autoconfigure.security.servlet.SpringBootWebSecurityConfiguration
 * @since 14 :58 2019/10/15
 */
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true, securedEnabled = true)
@EnableWebSecurity
@ConditionalOnClass(WebSecurityConfigurerAdapter.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
public class CustomSpringBootWebSecurityConfiguration {

  /**
   * The type Default configurer adapter.
   */
  @Configuration
  @Order(SecurityProperties.BASIC_AUTH_ORDER)
  static class DefaultConfigurerAdapter extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
      super.configure(auth);
    }

    @Override
    public void configure(WebSecurity web) {
      super.configure(web);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
      // 配置 httpSecurity

    }
  }
}

上面的配置了一个HttpSecurity,我们如法炮制再增加一个WebSecurityConfigurerAdapter的子类来配置另一个HttpSecurity。伴随而来的还有不少的问题要解决。

2.1 如何路由不同的安全配置
我们配置了两个HttpSecurity之后,程序如何让小程序接口和后台接口走对应的HttpSecurity?

HttpSecurity.antMatcher(String antPattern)可以提供过滤机制。比如我们配置:

   @Override
    protected void configure(HttpSecurity http) throws Exception {
      // 配置 httpSecurity
      http.antMatcher("/admin/v1");

    }

那么该HttpSecurity将只提供给以/admin/v1开头的所有URL。这要求我们针对不同的客户端指定统一的URL前缀。

举一反三只要HttpSecurity提供的功能都可以进行个性化定制。比如登录方式,角色体系等。

2.2 如何指定默认的 HttpSecurity

我们可以通过在WebSecurityConfigurerAdapter实现上使用@Order注解来指定优先级,数值越大优先级越低,没有@Order注解将优先级最低。

2.3 如何配置不同的 UserDetailsService

很多情况下我们希望普通用户和管理用户完全隔离,我们就需要多个UserDetailsService,你可以在下面的方法中对AuthenticationManagerBuilder进行具体的设置来配置UserDetailsService,同时也可以配置不同的密码策略。

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
  daoAuthenticationProvider.setUserDetailsService(new UserDetailsService() {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
      // 自行实现
      return null ;
    }
  });
  // 也可以设计特定的密码策略
  BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
  daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder);
  auth.authenticationProvider(daoAuthenticationProvider);
}

2.4 最终的配置模板

上面的几个问题解决之后,我们基本上掌握了在一个应用中执行多种安全策略。配置模板如下:

/**
 * 多个策略配置
 *
 * @author felord.cn
 * @see org.springframework.boot.autoconfigure.security.servlet.SpringBootWebSecurityConfiguration
 * @since 14 :58 2019/10/15
 */
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true, securedEnabled = true)
@EnableWebSecurity
@ConditionalOnClass(WebSecurityConfigurerAdapter.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
public class CustomSpringBootWebSecurityConfiguration {

  /**
   * 后台接口安全策略. 默认配置
   */
  @Configuration
  @Order(1)
  static class AdminConfigurerAdapter extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
      DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
      //用户详情服务个性化
      daoAuthenticationProvider.setUserDetailsService(new UserDetailsService() {
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
          // 自行实现
          return null;
        }
      });
      // 也可以设计特定的密码策略
      BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
      daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder);
      auth.authenticationProvider(daoAuthenticationProvider);
    }

    @Override
    public void configure(WebSecurity web) {
      super.configure(web);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
      // 根据需求自行定制
      http.antMatcher("/admin/v1")
          .sessionManagement(Customizer.withDefaults())
          .formLogin(Customizer.withDefaults());

    }
  }

  /**
   * app接口安全策略. 没有{@link Order}注解优先级比上面低
   */
  @Configuration
  static class AppConfigurerAdapter extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
      DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
      //用户详情服务个性化
      daoAuthenticationProvider.setUserDetailsService(new UserDetailsService() {
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
          // 自行实现
          return null;
        }
      });
      // 也可以设计特定的密码策略
      BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
      daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder);
      auth.authenticationProvider(daoAuthenticationProvider);
    }

    @Override
    public void configure(WebSecurity web) {
      super.configure(web);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
      // 根据需求自行定制
      http.antMatcher("/app/v1")
          .sessionManagement(Customizer.withDefaults())
          .formLogin(Customizer.withDefaults());

    }
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • "Method Not Allowed"405问题分析以及解决方法

    "Method Not Allowed"405问题分析以及解决方法

    项目中在提交表单时,提示“HTTP 405”错误——“Method Not Allowed”这里显示的是,方法不被允许,下面这篇文章主要给大家介绍了关于"Method Not Allowed"405问题分析以及解决方法的相关资料,需要的朋友可以参考下
    2022-10-10
  • javaWeb自定义标签用法实例详解

    javaWeb自定义标签用法实例详解

    这篇文章主要介绍了javaWeb自定义标签用法,结合实例形式分析了javaweb自定义标签的功能、定义方法及执行原理,需要的朋友可以参考下
    2017-04-04
  • Open Feign之非SpringCloud方式使用示例

    Open Feign之非SpringCloud方式使用示例

    这篇文章主要为大家介绍了Open Feign之非SpringCloud方式使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • 如何让java只根据数据库表名自动生成实体类

    如何让java只根据数据库表名自动生成实体类

    今天给大家带来的知识是关于Java的,文章围绕着如何让java只根据数据库表名自动生成实体类展开,文中有非常详细的介绍,需要的朋友可以参考下
    2021-06-06
  • 通过实例了解java spring使用构造器注入的原因

    通过实例了解java spring使用构造器注入的原因

    这篇文章主要介绍了通过实例了解spring使用构造器注入的原因,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • Java中StringBuilder常用构造方法解析

    Java中StringBuilder常用构造方法解析

    这篇文章主要介绍了Java中StringBuilder常用构造方法解析,StringBuilder是一个可标的字符串类,我们可以吧它看成是一个容器这里的可变指的是StringBuilder对象中的内容是可变的,需要的朋友可以参考下
    2024-01-01
  • Java常用时间工具类总结(珍藏版)

    Java常用时间工具类总结(珍藏版)

    这篇文章主要为大家详细介绍了Java中一些常用时间工具类的使用示例代码,文中的代码简洁易懂,对我们学习Java有一定帮助,需要的可以参考一下
    2022-07-07
  • Java多线程开发工具之CompletableFuture的应用详解

    Java多线程开发工具之CompletableFuture的应用详解

    做Java编程,难免会遇到多线程的开发,但是JDK8这个CompletableFuture类很多开发者目前还没听说过,但是这个类实在是太好用了,本文就来聊聊它的应用吧
    2023-03-03
  • Java实现基于token认证的方法示例

    Java实现基于token认证的方法示例

    这篇文章主要介绍了Java实现基于token认证的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • 基于Spring Boot的Logback日志轮转配置详解

    基于Spring Boot的Logback日志轮转配置详解

    本篇文章主要介绍了基于Spring Boot的Logback日志轮转配置详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10

最新评论