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

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>>extendsAbstractInterceptUrlConfigurer<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 {@Overridepublic 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");@Overridepublic 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 elseput("/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 {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.addFilterBefore(new DemoFilter(),AnonymousAuthenticationFilter.class).authorizeRequests().antMatchers("/css/**", "/js/**","/fonts/**").permitAll().anyRequest().authenticated();}@Autowiredpublic void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("admin").password("admin").roles("USER");}
}

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

小结

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

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

doc

  • spring security运行时配置ignore url

spring security免登录动态配置方案2相关推荐

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

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

  2. 7.Spring Security 退出登录

    Spring Security默认的退出登录URL为/logout,退出登录后,Spring Security会做如下处理: 是当前的Sesion失效: 清除与当前用户关联的RememberMe记录: ...

  3. Spring Security 实战:基于配置的接口角色访问控制

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | 码农小胖哥 来源 | 公众号「码农小胖哥」 1 ...

  4. Spring Security 退出登录(7)

    Spring Security默认的退出登录URL为/logout,退出登录后,Spring Security会做如下处理: 使当前的Sesion失效: 清除与当前用户关联的RememberMe记录: ...

  5. Spring Security MVC登录注销示例教程

    Spring Security MVC登录注销示例教程 今天我们将了解Spring Security Login Example.在阅读这篇文章之前,请先阅读我在"Spring 4 Secu ...

  6. Spring Security:自定义登录页面

    本文来说下Spring Security中如何自定义登录页面 文章目录 准备工作 自定义登录界面 本文小结 准备工作 添加模板引擎 这里使用了thymeleaf模板引擎,在pom.xml进行添加: & ...

  7. spring security+jwt 登录认证

    spring security+jwt 登录认证 1.综述 2.版本与环境 3.架构 4.数据库认证逻辑图 5.案例 security+jwt 5.1引入依赖 5.2新建工具类 5.2新建组件类 5. ...

  8. Spring Security默认登录页面

    使用Spring Security作为权限管理模块的小伙伴们一定醉心于其极少的配置即可满足权限管理需求,以及比springMVC更简洁的filter配置. 在刚开始技术验证的demo阶段相信很多人试过 ...

  9. Spring Security自定义登录验证及登录返回结果

    Spring Security自定义登录验证及登录返回结果 一.功能描述 二.处理逻辑 简单流程 自定义UserDetails 自定义UserDetailsDAO 自定义UserDetailsServ ...

  10. (二)Spring Security自定义登录成功或失败处理器

    目录 一:创建登录成功处理器 二:创建登录失败处理器 三:添加处理器 三. 项目地址 我们接着上一章 Spring Security最简单的搭建,进行开发 LoginSuccessHandler 和L ...

最新文章

  1. Oracle 10.2.0.5.4 Patch Set Update (PSU) – Patch No: p12419392
  2. Generator函数的语法以及异步的应用
  3. Git与Ftp协同工作
  4. “-bash: !”: event not found、echo sudo permission denied
  5. 分峰截幅c语言算法,面向桥梁健康监测的复合传感技术研究
  6. 19_05_01校内训练[划分]
  7. Java高阶部分知识点汇总(一)- 成员变量与局部变量详讲
  8. python为什么不能自动语法_Python 为什么不支持 i++ 自增语法,不提供 ++ 操作符?...
  9. arm clz指令c语言,协处理器及其他指令之:零计数指令CLZ-嵌入式系统-与非网
  10. word List35
  11. Springboot+MyBatis-plus+postgresSQL 的整合
  12. 重磅!阿里推出国产开源JDK!
  13. 排序算法 快速排序 python 0913
  14. python开发实践教程 于京_《Python开发实践教程》于京、宋伟 著著【摘要 书评 在线阅读】-苏宁易购图书...
  15. [导入]存储过程-分隔符号-多条件查询
  16. dropdownlist返回值设置方法
  17. JVM监控及诊断工具之JConsole
  18. java stringbuilder 构造函数_java---StringBuilder类的用法(转载)
  19. 超实用,一口气学会 Centos/Docker/Nginx/Node/Jenkins 等基础操作
  20. 代码测试,调试与优化小结

热门文章

  1. 二分法和牛顿迭代实现开根号函数:OC的实现
  2. MVC数据验证Model Validation
  3. 关于typedef的用法总结(转)
  4. 整合DZ .net论坛与.net整合。
  5. 入门排序(冒泡、选择、直接)
  6. 设计模式(1)-- 七大软件设计原则-开闭原则
  7. git中Bash基本操作命令
  8. 【带着canvas去流浪(13)】用Three.js制作简易的MARVEL片头动画(下)
  9. Python常用模块实战之ATM和购物车系统再升级
  10. 项目启动时 xml报错:Could not find SQL statement to include with refid 'mbgl.panDuanZbsfkxg'