spring security免登录动态配置方案2

2023-11-11

之前有篇文章讲了怎么进行免登录动态配置的方案,动用了反射去实现,有点黑魔法的味道,这里再介绍另外一种方案

permitAll

spring-security-config-4.2.3.RELEASE-sources.jar!/org/springframework/security/config/annotation/web/configurers/ExpressionUrlAuthorizationConfigurer.java

public final class ExpressionUrlAuthorizationConfigurer<H extends HttpSecurityBuilder<H>>
        extends
        AbstractInterceptUrlConfigurer<ExpressionUrlAuthorizationConfigurer<H>, H> {
    static final String permitAll = "permitAll";
    private static final String denyAll = "denyAll";
    private static final String anonymous = "anonymous";
    private static final String authenticated = "authenticated";
    private static final String fullyAuthenticated = "fullyAuthenticated";
    private static final String rememberMe = "rememberMe";

    private final ExpressionInterceptUrlRegistry REGISTRY;

    //......
        /**
         * Specify that URLs are allowed by anyone.
         *
         * @return the {@link ExpressionUrlAuthorizationConfigurer} for further
         * customization
         */
        public ExpressionInterceptUrlRegistry permitAll() {
            return access(permitAll);
        }

        public ExpressionInterceptUrlRegistry access(String attribute) {
            if (not) {
                attribute = "!" + attribute;
            }
            interceptUrl(requestMatchers, SecurityConfig.createList(attribute));
            return ExpressionUrlAuthorizationConfigurer.this.REGISTRY;
        }

        private void interceptUrl(Iterable<? extends RequestMatcher> requestMatchers,
            Collection<ConfigAttribute> configAttributes) {
        for (RequestMatcher requestMatcher : requestMatchers) {
            REGISTRY.addMapping(new AbstractConfigAttributeRequestMatcherRegistry.UrlMapping(
                    requestMatcher, configAttributes));
        }
    }
}

permitAll操作将“permitAll”这个attribute以及对应的requestMatchers添加到REGISTRY

思路

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/css/**", "/js/**","/fonts/**").permitAll()
                .anyRequest().authenticated();
    }
}

这里重点注意这个anyRequest().authenticated(),可以看到没有配置permitAll的请求,都要求authenticated这个级别的,而AnonymousAuthenticationFilter设置的匿名级别只是anonymous。

于是我们的思路就来了,新建一个filter,插入在AnonymousAuthenticationFilter之前,对于免登录的设置为authenticated

DemoFilter

public class DemoFilter extends GenericFilterBean {

    private Object principal = "annoUser";

    private List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ROLE_ANNO");

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        private final Map<String,HttpMethod[]> annoPatternMap = new HashMap<String,HttpMethod[]>(){{
        //for demo, you can change it and read from db or else
        put("/index/demo",new HttpMethod[]{HttpMethod.GET});
    }};
    
        String uri = ((HttpServletRequest) servletRequest).getRequestURI();
        if(annoPatternMap.containsKey(uri)){
            if(SecurityContextHolder.getContext().getAuthentication() == null){
                SecurityContextHolder.getContext().setAuthentication(
                        createAuthentication((HttpServletRequest) servletRequest));
            }
        }else{
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            System.out.println(auth == null);
            if(auth != null && auth instanceof UsernamePasswordAuthenticationToken){
                if(principal.toString().equals(auth.getPrincipal().toString())){
                    SecurityContextHolder.getContext().setAuthentication(null);
                }
            }
        }
        filterChain.doFilter(servletRequest, servletResponse);
    }
    
    protected Authentication createAuthentication(HttpServletRequest request) {
        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
                principal, "N/A", authorities);
        auth.setDetails(authenticationDetailsSource.buildDetails(request));

        return auth;
    }
}

这里创建了一个伪造的UsernamePasswordAuthenticationToken

这里有一点要注意一下,就在判断不是配置的允许匿名访问的url的时候,如果之前的token是我们设置的,则需要重新清空,防止一旦访问匿名url之后获取session再去越权访问其他没有配置的url。

配置filter

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .addFilterBefore(new DemoFilter(),AnonymousAuthenticationFilter.class)
                .authorizeRequests()
                .antMatchers("/css/**", "/js/**","/fonts/**").permitAll()
                .anyRequest().authenticated();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .inMemoryAuthentication()
                .withUser("admin").password("admin").roles("USER");
    }
}

在AnonymousAuthenticationFilter之前提前设置好SecurityContextHolder里头的authentication。

小结

这样基本就大功告成了,不过有几点需要注意:

  • 自定义的filter,可能存在执行两遍的问题,这点后面的文章来讲
  • 获取到的uri无法处理pathvariable的情况,需要根据url pattern来处理,这点后面再讲述一下

doc

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

spring security免登录动态配置方案2 的相关文章

随机推荐

  • Linux系统点亮LED

    目录 应用层操控硬件的两种方式 sysfs 文件系统 sysfs 与 sys 总结 标准接口与非标准接口 LED 硬件控制方式 编写LED 应用程序 在开发板上测试 对于一款学习型开发板来说 永远都绕不开LED 这个小小的设备 基本上每块板
  • webstorm配置sass

    最近用webstorm 做项目 使用create react app创建项目 安装node sass chokidar 使用命令行来将sass转换为css 不尽人意的是 在vscode 可以正常使用 到了webstorm TM 一直不会自动
  • 视频点播服务器的配置如何选择,需要多大的带宽

    对于普通的企业网站 服务器带宽只需5M 10M 每天面对1w用户是没有问题的 图片网站 10M带宽可能只支持100 1k人 天访问 然后 如果是一个视频点播网站 服务器的带宽将增加几十倍 特别是对于视频点播服务器 瓶颈是带宽 视频点播服务器
  • 知识星球-伙伴匹配系统笔记2

    朋友伙伴匹配系统笔记2 1 前端整合路由 下载vue router 由于我们使用的是vue3 所以对应的是4版本的路由 npm install vue router 4 或者 yarn add vue router 4 如下图 前端整合路由
  • BootLoader介绍

    文章目录 一 BootLoader的引入 二 BootLoader的启动方式 三 BootLoader的结构和启动过程 四 自己写一个BootLoader 1 BootLoader第一阶段 2 BootLoader第二阶段 一 BootLo
  • Python爬虫常见HTTP状态码及解决方案

    爬虫工程师在数据采集过程中 不可避免地会遇到各种各样的问题 我们需要快速地对HTTP请求返回的各种异常状态码来判断处理 以便于我们及时调整爬虫策略 优化思路 及时完成作业 正常情况下 在使用代理IP时会出现以下错误状态码 一 代理链接失败
  • vue3使用高德地图,自定义点标记、默认点聚合样式、点击点标记获取信息

    1 需求 根据不用的类型和经纬度展示不同的自定义点标记 点标记太多 使用点聚合优化 参考 https blog csdn net qq 39157025 article details 120287561 2 在index html使用CD
  • Java学习笔记18——接口

    接口 接口概述 接口的特点 新建接口 创建一个实现类 Demo测试 总结 接口的成员特点 成员变量 构造方法 成员方法 类和接口的关系 类和类的关系 类和接口的关系 接口和接口之间的关系 抽象类与接口之间的区别 成员区别 关系区别 设计理念
  • c#基础知识---集合之队列

    队列 Queue 代表了一个先进先出的对象集合 当您需要对各项进行先进先出的访问时 则使用队列 当您在列表中添加一项 称为入队 当您从列表中移除一项时 称为出队 Queue 类的方法和属性 下表列出了 Queue 类的一些常用的 属性 属性
  • MySQL进阶(终篇)

    无知的我正在复习MySQL进阶知识 笔记特点是 我重新整理了涉及资料的一些语言描述 排版 而使用了自己比较容易理解的描述 同样是回答了一些常见关键问题 如果有遇到有任何无法进展问题或者疑惑的地方 应该在讨论区留言 或者 其他途径以寻求及时的
  • [开发工具使用基础-vs2013] 增加外部文件到项目工程

    此文适合于在vs2013中入门C 编程的人员借鉴 主要功能是添加外部文件 比如你网上下载的 cpp文件和 h头文件 到本项目工程 过程演示 1 新建一个C 空项目NewProgram 项目名自取 对于你的话就是你自己的项目了 完成后解决方案
  • Unity资源管理——使用UnityWebRequest从云端下载Assetbundle包

    1 环境 基于Unity2018 2 2 思路 1 使用UnityWebRequest Get方法去获取AB包 2 在协程中返回UnityWebRequest实例对象的SendWebRequest方法返回值 3 当UnityWebReque
  • wpf 保存图片到任意格式jpg,png,bmp

    private void ExportBtn Click object sender RoutedEventArgs e SaveFileDialog saveFileDialog new SaveFileDialog saveFileDi
  • nodejs中文教程-windows下nodejs开发环境的安装与配置

    么是Node js 还服务器端javascript 对于这个概念我在这篇文章不做解释 可以自己去搜索了解下 服务器端js不是新技术 只是最近的node js的火爆让他爆发了 我会在以后的文章里解释什么是node js 这里只是纯粹的搭建 连
  • HarmoneyOS鸿蒙系统零代码编程入门

    文章目录 前言 学习资源网址 工具以及基本环境准备 搭建HarmonyOS项目 申请成为华为开发者 实现 您好 世界 入门程序 前言 2021年6月3日 华为终于推出了HarmoneyOS 即鸿蒙操作系统公测 着实振奋人心 分布式操作系统
  • Linux学习篇 1.Linux的磁盘规划

    历时1个月的学习 对Linux终于小有了解 初步可以做些操作了 同时对Linux有了更深的理解 以前没接触的时候觉得高不可攀 经过一段时间的学习才发现 原来也没想象中的那么难 哈哈 独乐乐不如群乐乐 下面是我以做笔记的方式写的文章 有些生硬
  • 用py写一个时间盲注的脚本(初学向)

    用py写一个时间盲注的脚本 1 首先我们要清楚时间盲注的特点是利用了sql中sleep这个函数 借助的是响应时间不同来判断构造语句的对错 那么我们主要思路就要通过记录响应时间来执行一系列操作 下面是我写的一个简单脚本 2 import re
  • 告诉你如何应对HR索要薪资证明!

    有些企业的HR会要求求职者提供薪资证明 尤其是对于 骑驴找马 的求职者 HR不便于进行背景调查 更倾向于让求职者提供薪资证明 面对这种情况 根据前程无忧论坛的调查数据显示 有26 的受访者愿意提供薪资证明 其余的受访者要么拒绝提供 要么直接
  • 基于SpringBoot开发的停车位管理系统(调用百度地图api)

    文章目录 项目介绍 主要功能截图 前台 后台 部分代码展示 设计总结 项目获取方式 作者主页 超级无敌暴龙战士塔塔开 简介 Java领域优质创作者 简历模板 学习资料 面试题库 关注我 都给你 文末获取源码联系 项目介绍 基于SpringB
  • spring security免登录动态配置方案2

    序 之前有篇文章讲了怎么进行免登录动态配置的方案 动用了反射去实现 有点黑魔法的味道 这里再介绍另外一种方案 permitAll spring security config 4 2 3 RELEASE sources jar org sp