以前用shiro的比较多,不过spring boot倒是挺推崇自家的spring security的,有默认的starter,于是也就拿来用了。

问题

对于免登陆的url,采用java config,可以这样配置:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overridepublic void configure(WebSecurity web) throws Exception {//ignoreweb.ignoring().antMatchers("/info","/health","/hystrix.stream");}
}

但是这样配置有个缺点,就是每次要新增一个免登陆的url的时候,就得重新启动一遍,这个就不是太好了。有没有解决方案呢。

方案1

方案1就是对于业务场景下的免登陆的url,都统一添加一个前缀,比如/open/xxxx,这样就可以固定死了

web.ignoring().antMatchers("/info","/health","/hystrix.stream","/open/**");

后续有免登陆的url,比如/share,那么改成/open/share这样就不用重新启动了

方案2

方案2就是去hack一下spring security,这个需要了解一下spring security的运行机制:

Spring Security 的底层是通过一系列的 Filter 来管理的,每个 Filter 都有其自身的功能,它们的顺序也是非常重要的。
里头比较重要的一个就是名为SPRING_SECURITY_FILTER_CHAIN的FilterChainProxy,Security 将会为每一个 http 元素创建对应的 FilterChain(DefaultSecurityFilterChain),同时按照它们的声明顺序加入到 FilterChainProxy。所以当我们同时定义多个 http 元素时要确保将更具有特性的 URL 配置在前。

public class FilterChainProxy extends GenericFilterBean {// ~ Static fields/initializers// =====================================================================================private static final Log logger = LogFactory.getLog(FilterChainProxy.class);// ~ Instance fields// ================================================================================================private final static String FILTER_APPLIED = FilterChainProxy.class.getName().concat(".APPLIED");private List<SecurityFilterChain> filterChains;private FilterChainValidator filterChainValidator = new NullFilterChainValidator();private HttpFirewall firewall = new DefaultHttpFirewall();// ~ Methods// ========================================================================================================public FilterChainProxy() {}public FilterChainProxy(SecurityFilterChain chain) {this(Arrays.asList(chain));}public FilterChainProxy(List<SecurityFilterChain> filterChains) {this.filterChains = filterChains;}//......}

ignore的原理

DefaultSecurityFilterChain的构造器如下
spring-security-web-4.1.4.RELEASE-sources.jar!/org/springframework/security/web/DefaultSecurityFilterChain.java

public final class DefaultSecurityFilterChain implements SecurityFilterChain {private static final Log logger = LogFactory.getLog(DefaultSecurityFilterChain.class);private final RequestMatcher requestMatcher;private final List<Filter> filters;public DefaultSecurityFilterChain(RequestMatcher requestMatcher, Filter... filters) {this(requestMatcher, Arrays.asList(filters));}public DefaultSecurityFilterChain(RequestMatcher requestMatcher, List<Filter> filters) {logger.info("Creating filter chain: " + requestMatcher + ", " + filters);this.requestMatcher = requestMatcher;this.filters = new ArrayList<Filter>(filters);}
}

需要一个RequestMatcher以及作用在它上面的filter,如果你不传filter的话,那就是这个RequestMatcher对应的url就是免登陆的。spring security会根据FilterChainProxy中的filter chain的顺序去挨个匹配当前请求的url,然后执行对应的filter逻辑,在前面的优先匹配。

思路

要在运行时增加免登陆url的话,就需要运行时去修改FilterChainProxy中的filterChains,不过源码里头返回了不可变的集合
4.1.4.RELEASE/spring-security-web-4.1.4.RELEASE-sources.jar!/org/springframework/security/web/FilterChainProxy.java

    /*** @return the list of {@code SecurityFilterChain}s which will be matched against and* applied to incoming requests.*/public List<SecurityFilterChain> getFilterChains() {return Collections.unmodifiableList(filterChains);}

因此这里需要hack一下,用反射去获取

方案

    List<SecurityFilterChain> addIgnoreUrl(String url){FilterChainProxy obj = (FilterChainProxy) ApplicationContextHolder.getContext().getBean("springSecurityFilterChain");List<SecurityFilterChain> filterChains = (List<SecurityFilterChain>) ReflectUtil.getProperty(obj,"filterChains");filterChains.add(0,new DefaultSecurityFilterChain(new AntPathRequestMatcher(url, null)));return filterChains;}

这里有几个要点

  • 反射获取可修改的filterChains
public static Object getProperty(Object obj, String fieldName) {try {Field field = obj.getClass().getDeclaredField(fieldName);field.setAccessible(true);return field.get(obj);} catch (Exception e) {e.printStackTrace();return null;}}
  • 添加到filterChains的最前面使其优先匹配到
  • filter要设置为null,表示免登陆

小结

这样就大功告成了,以后就无需重新启动来配置免登陆url了。其实这个还可以扩展一下,支持动态的权限配置,这个下次有机会再讲一下。

doc

  • 初识 Spring Security
  • Spring Security系列四 自定义决策管理器(动态权限码)

spring security运行时配置ignore url相关推荐

  1. ssm 返回json配置_摆脱困境:将运行时配置作为JSON返回

    ssm 返回json配置 如果需要确定部署到远程服务器的Spring Web应用程序的运行时配置,则需要读取从远程服务器找到的属性文件. 这很麻烦. 幸运的是,有更好的方法. 这篇博客文章描述了我们如 ...

  2. 摆脱困境:将运行时配置作为JSON返回

    如果需要确定部署到远程服务器的Spring Web应用程序的运行时配置,则需要读取从远程服务器找到的属性文件. 这很麻烦. 幸运的是,有更好的方法. 这篇博客文章描述了我们如何 启动我们的Web应用程 ...

  3. SpringSecurity权限管理框架系列(六)-Spring Security框架自定义配置类详解(二)之authorizeRequests配置详解

    1.预置演示环境 这个演示环境继续沿用 SpringSecurit权限管理框架系列(五)-Spring Security框架自定义配置类详解(一)之formLogin配置详解的环境. 2.自定义配置类 ...

  4. Spring Boot –使用执行器端点在运行时配置日志级别

    从Spring Boot 1.5开始,新的loggers器执行器端点允许在运行时查看和更改应用程序记录级别. 将spring-boot-actuator添加到您的项目 <dependency&g ...

  5. Spring Boot2 总结(二) Spring Security的基本配置

      Spring Boot对Spring Security提供了自动化配置方案,同时这也是在Spring Boot项目中使用Spring Security的优势,因此Spring Security整合 ...

  6. spring Security 重复登录配置无效的问题

    关于spring Security重复登录的配置,百度一大堆,我这里就不啰嗦了. 今天碰到 按照网上的配置,但是 感觉配置无效,同一用户还是可以登录,不知道为什么,开始以为是自己配置的又问题.再三确认 ...

  7. jvm jinfo 参数_jinfo:JVM运行时配置的命令行浏览

    jvm jinfo 参数 在最近的一些博客中(特别是在对Java EE 7性能调优和优化以及WildFly性能调优的书中的评论中),我引用了自己过去在某些Oracle JDK命令行工具上的博客文章. ...

  8. jinfo:JVM运行时配置的命令行浏览

    在最近的几篇博客中(特别是在对Java EE 7性能调优和优化以及WildFly性能调优的书的评论中),我引用了自己过去在某些Oracle JDK命令行工具上的博客文章. 令我震惊的是,我从来没有专门 ...

  9. Spring Security(02)认证配置

    前面只是简单使用了springsecurity的登录控制功能,当然实际使用中是一定需要写一些自定义配置的:本节将通过springsecurity配置一些功能: 通过数据库用户密码完成认证 使用自定义登 ...

最新文章

  1. vue 拷贝 数组_Vue实现对数组、对象的深拷贝、复制
  2. pandas中两个dataframe的交集和差集
  3. Protocol Buffer数据编码
  4. Linux epoll 笔记(高并发事件处理机制)
  5. docker 中运行 mysql
  6. Spring Boot返回的数据格式是XML 而不是JSON之原因探求的和解决
  7. linux内核分析及应用 -- Linux 的进程隔离技术与 Docker 容器
  8. MT4API外汇跟单软件使用分享
  9. php stack trace,PHP 异常处理
  10. H3C IRF2的三种配置情况「转载」
  11. Windows版bitcoin客户端编译
  12. 今天一篇文章告诉你Python 自动化测试 必会模块 Unittest
  13. 天猫精灵使用体验之二——家用电器的智能化改造(借助天猫精灵实现家用电器的语音控制)
  14. 骁龙888发布,小米11首发,有14家厂商首批搭载!
  15. 信号是受噪声Nt干扰的余弦波Xt = Acoswt + φ + Nt,试求它的自相关函数。假设φ是在[0, 2Π]上均匀分布的随机变量,Nt是均值为0方差为σ2的白噪声,且 Nt 与 φ 互不相关。
  16. GOPATH 与工作空间
  17. 解决 command not found: netstat
  18. 【兄弟反目成仇系列】:我只是写了一个爆炸信息窗口脚本,好兄弟追了我几条街~
  19. 发现一个安卓万能脱壳方法
  20. 【OpenCV--模板匹配】

热门文章

  1. SPSS工具:聚类分析(2)--系统聚类--员工绩效
  2. 低阶有限群的伽罗瓦表示
  3. 虚拟磁带库mhvtl的安装与使用
  4. 虚拟磁带库(VTL)简介
  5. iOS开发-------基于WKWebView的原生与JavaScript数据交互
  6. 无法作为数据库主体执行,因为主体 “dbo“ 不存在、无法模拟这种类型的主体,或您没有所需的权限
  7. 梅科尔工作室-位青-鸿蒙笔记4
  8. 第二十讲:神州路由器静态路由的配置
  9. 硬盘被计算机限制如果解锁,硬盘被加锁,怎么处理才行
  10. java调整字体_用java修改字体样式