安全策略_Spring Security 实战干货:如何实现不同的接口不同的安全策略

5277eb8d07f4113e1c6a527f63dd2422.png

1. 前言

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

2. 解决方案

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

如果你看过之前的教程,我们是这么配置的:

/**
 * 单策略配置
 *
 * @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());


        }
    }
}

3. 总结

今天我们解决了如何针对不同类型接口采取不同的安全策略的方法,希望对你有用,如果你有什么问题可以留言。多多关注:码农小胖哥,更多干货奉上。

往期推荐:

984ac4ec5c0be6ac8f797ffcc3ce25d7.png

Java开发常用技术栈盘点

9f69fc6329af824c1ac00df51397c0cf.png

订阅发布模式到底是不是观察者模式?

e43ee1548922e00e10d057f36ac2f8ac.png

                                                                                                  732709260619607e55ef3e88c2adde5a.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/527485.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python外星人入侵怎么发给别人_python_外星人入侵(1-1)

sys:system的简称。包含了一些与系统有关的函数。 step1:构建游戏的主框架 import sys import pygame def run_game(): 初始化游戏并创建一个屏幕对象 pygame.init() # 创建一个显示窗口,宽1200像素,高800像素 screen pygame.dis…

delphi listview 添加数据 慢_Delphi 二十四岁, Delphi 10.3.1 发布

Delphi1 是 Borland于1995年2月14日发布,因此2019年2月14日是该产品发布的24周年纪念日。如果你想了解一些关于该产品及其发布的历史,你可以参考文章“22 Years of Delphi and it Still Rocks”。在那篇文章中,我收集了一些早期产品的照片&am…

找规律万能公式_有一个万能公式,可以帮你解决任何烦恼!

有一个万能公式,可以帮你解决任何烦恼。我是在十几年前学到的,一直使用到现在。不仅简单,而且非常有效,只有3步,马上就能现学现用。如果你目前正好碰到了什么难题,不妨试试这个万能公式。01第一步&#xff…

vue 判断两对象是否一致_你的.vue文件就已经是你的文档了

更新:文档地址:http://vuese.org昨天发布了vuese1.0,这是我的一个新的开源项目,用来解析Vue SFC并生成markdown文档,如下:HcySunYang/vuese​github.com这篇文章不会介绍如何使用,至于如何使用大…

centos7 oracle_Centos7主机名变成bogon的原因及解决方法

问题描述虚拟机在设置完静态IP后,莫名其妙地主机名就变成了bogon,并且问题会稳定复现,就是说每次重启都会。如下图所示:看着不顺眼不说,听说可能还会影响某些服务,如可能导致oracle安装过程网络配置出错等问…

get 参数太长怎么办_新买的手表表带太长了该怎么办?表带调节操作方法get你~...

表表哥点击☝上方蓝字关注我们表带是手表的重要组成部分,同时表带决定着手表佩带的舒适性,方便性,对手表的安全也有关系。现在表带的材质也很多,最常见的就是不锈钢的和真皮的。买过手表的人应该都知道,只有是专门定制…

elasticsearch初次查询超时_ElasticSearch的工作流程

1.ElasticSearch的工作流程​ 1.启动过程​ 当ElasticSearch节点启动时,使用发现(discovery)模块来发现集群中的其他节点(配置文件的集群名称)并连接.ElasticSearch会发送广播,以找到相同集群名称其他节点。​ 集群选举一个节点为主节点。该节点负责分发…

modbus slave如何使用_【干货】如何进行PLC远程监控?只需三个步骤,马上帮你解决问题!...

工厂里的工程师小威最近真的很头痛,公司客户的一台或多台设备分布在不同的地区或国外,如果要对其PLC、HMI等自控产品进行远程控制、调试和维护。除了问题,经常要千里迢迢奔赴国外进行维护。最近有事特殊时期,国外疫情比较乱套&…

智能卡门禁管理系统_出入口门禁控制系统与消防火灾报警系统怎么联动?

门禁系统作为一个控制进出的设备,在发生火灾时如何快速打开所有防火逃生门时,是需要弱电单位对门禁系统要行动考虑,否则容易出现隐患,万一出现火灾,因为门禁是常闭门造成人员无法快速逃生那是肯定要负一定的责任的。如…

两表格合并_六个高效办公Excel小技巧,让你提前下班两小时!

每天下午一点,PPT技能进步一点大家中午好呀!大家好这是我们的抖音号PPT模板抖音搜索“PPT1080”就可以啦更多福利等你来拿!小编发现抖音里无奇不有有关于Excel的小知识点也很多今天就带大家盘点一下抖音里最火爆的6个Excel小技巧点滴积累可以…

卷的作用_还在盲目的制作蛋糕卷吗?先来搞懂这几种蛋糕卷面糊~

柔软湿润的蛋糕卷制作简单,可以随意搭配各种柔滑的馅料使得蛋糕卷的口味变化多端。不分男女老少,任谁都能恣意品尝,只要随手一切,你一块我一块地与人一同享用,其乐融融。蛋糕卷の基础材料要做好蛋糕卷首先要认识基本材…

android接口类命名规范_超全面的UI基础设计规范来啦,还不收藏 ~

写在前面的话 很多刚入行的UI设计师开始接触移动端UI设计的时候,对于基础的界面尺寸规范可能会有一定的模糊认知,导致做出来的界面往往会感觉不是那么和谐,却也不知道怎么去完善和改进。对于大多数的刚入行者来说,如果不是有天赋…

layer中嵌套的页面如何操作父页面_vue中8种组件通信方式,值得收藏

有不少网友提出组件之间通信方式还有很多, 这篇文章便是专门总结组件之间通信的vue是数据驱动视图更新的框架, 所以对于vue来说组件间的数据通信非常重要,那么组件之间如何进行数据通信的呢? 首先我们需要知道在vue中组件之间存在什么样的关系, 才更容易…

镜头视场角计算工具_再谈远心镜头的设计及其独特的性能

1.远心镜头的设计与对比镜头可以分为非远心和远心;远心镜头也可以分为物方远心、像方远心和双远心。相关概念的简单说明:孔径光阑在物空间的像称为入射光瞳。同样,孔径光阑被其后面的光学零件成在像空间的像,称为出射光瞳。入射光…

collector list 多个分组_【S01E07】groupby方法、GroupBy对象、groupby方法的分组键

Hadley Wickham(许多热门R语言包的作者)创造了一个用于表示分组运算的术语"split-apply-combine"(拆分-应用-合并),这个词很好的描述了整个过程。分组运算的第一个阶段,pandas对象(无…

清理垃圾代码bat_来买个小内存u盘么咯?盘内带电脑垃圾清理.bat那种丨heibai.org...

在某宝个别店铺购买了小内存u盘到货后插入电脑,发现自带了一个名为电脑垃圾清理的小程序。对就是这货怀揣着这家店真好,还带了垃圾清理软件的想法,我试着运行了软件.但是好像没有卵用.正好小表弟好像对这个比较了解,我去问问他咋回…

射灯安装方法图解_家居射灯怎么选?第三代宜美SMD射灯给你正解

前段时间,刚把自己的房子完成硬装,在灯具选择的过程中,家人的意见就不太统一。其父母觉得选灯只要够亮就行,而媳妇觉得选灯选贵的才行。到底谁的选灯方法好呢?其实家人们的建议并不是完全不对,灯够亮只是其…

c标签判断true false jsp_北京尚学堂卓越班252天[第042天]——Jsp

1. JSP的核心运行原理1) 客户端浏览器发送请求到服务器,访问a.jsp文件。http://localhost:8989/应用名/a.jsp2) 服务器端接收到请求后所做的处理a) 创建request和response两个对象b) 根据请求中的应用名找到该应用下面的web.xml文件,发现该应用的配置文件…

js aes加密_某高考咨询网js逆向分析笔记

一、某高考资讯网逆向分析某网站的js加密分析,安全签名signsafe HmacSHA1 AES一年前分析过网站数据还没有加密,最近需要获取新的数据发现原先的爬虫失效,请求和响应都经过加密。于是重新分析,记录下分析思路以及分析过程中遇到的…

opencv 的norm_22、OpenCV用卷积Filter2D进行滤波器

迄今为止,看到的函数中,卷积的操作发生在OpenCV函数的内部。理论上,图像卷积就是将内核与图像覆盖区域对应位置相乘之后求和。从调用函数上来看,它需要一个数组参数来描述内核。在实践层面,有一个重要的微妙因素会对结…