《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》

摘要: 原创出处 http://niocoder.com/2018/05/21/Spring-Security-Oauth2-permitAll()方法小记/ 「龙飞」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

黄鼠狼在养鸡场山崖边立了块碑,写道:“不勇敢地飞下去,你怎么知道自己原来是一只搏击长空的鹰?!”

从此以后

黄鼠狼每天都能在崖底吃到那些摔死的鸡!

https://raw.githubusercontent.com/longfeizheng/longfeizheng.github.io/master/images/spring-security-OAuth207.png

1. 前言

上周五有网友问道,在使用spring-security-oauth2时,虽然配置了.antMatchers("/permitAll").permitAll(),但如果在header 中 携带 Authorization Bearer xxxxOAuth2AuthenticationProcessingFilter还是会去校验Token的正确性,如果Token合法,可以正常访问,否则,请求失败。他的需求是当配置.permitAll()时,即使携带Token,也可以直接访问。

2. 解决思路

根据Spring Security源码分析一:Spring Security认证过程得知spring-security的认证为一系列过滤器链。我们只需定义一个比OAuth2AuthenticationProcessingFilter更早的过滤器拦截指定请求,去除header中的Authorization Bearer xxxx即可。

3. 代码修改

3.1 添加PermitAuthenticationFilter类

添加PermitAuthenticationFilter类拦截指定请求,清空header中的Authorization Bearer xxxx

@Component("permitAuthenticationFilter")
@Slf4j
public class PermitAuthenticationFilter extends OncePerRequestFilter {

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

log.info("当前访问的地址:{}", request.getRequestURI());
if ("/permitAll".equals(request.getRequestURI())) {

request = new HttpServletRequestWrapper(request) {
private Set<String> headerNameSet;

@Override
public Enumeration<String> getHeaderNames() {
if (headerNameSet == null) {
// first time this method is called, cache the wrapped request's header names:
headerNameSet = new HashSet<>();
Enumeration<String> wrappedHeaderNames = super.getHeaderNames();
while (wrappedHeaderNames.hasMoreElements()) {
String headerName = wrappedHeaderNames.nextElement();
if (!"Authorization".equalsIgnoreCase(headerName)) {
headerNameSet.add(headerName);
}
}
}
return Collections.enumeration(headerNameSet);
}

@Override
public Enumeration<String> getHeaders(String name) {
if ("Authorization".equalsIgnoreCase(name)) {
return Collections.<String>emptyEnumeration();
}
return super.getHeaders(name);
}

@Override
public String getHeader(String name) {
if ("Authorization".equalsIgnoreCase(name)) {
return null;
}
return super.getHeader(name);
}
};

}
filterChain.doFilter(request, response);

}
}

3.2 添加PermitAllSecurityConfig配置

添加PermitAllSecurityConfig配置用于配置PermitAuthenticationFilter

@Component("permitAllSecurityConfig")
public class PermitAllSecurityConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain,HttpSecurity> {

@Autowired
private Filter permitAuthenticationFilter;

@Override
public void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(permitAuthenticationFilter, OAuth2AuthenticationProcessingFilter.class);
}
}

3.3 修改MerryyouResourceServerConfig,增加对制定路径的授权

@Override
public void configure(HttpSecurity http) throws Exception {

// @formatter:off
http.formLogin()
.successHandler(appLoginInSuccessHandler)//登录成功处理器
.and()
.apply(permitAllSecurityConfig)
.and()
.authorizeRequests()
.antMatchers("/user").hasRole("USER")
.antMatchers("/forbidden").hasRole("ADMIN")
.antMatchers("/permitAll").permitAll()
.anyRequest().authenticated().and()
.csrf().disable();

// @formatter:ON
}

3.4 修改测试类SecurityOauth2Test

添加permitAllWithTokenTest方法

@Test
public void permitAllWithTokenTest() throws Exception{
final String accessToken = obtainAccessToken();
log.info("access_token={}", accessToken);
String content = mockMvc.perform(get("/permitAll").header("Authorization", "bearer " + accessToken+"11"))
.andExpect(status().isOk())
.andReturn().getResponse().getContentAsString();
log.info(content);
}

  • Authorization bearer xxx 11后面随机跟了两个参数

3.5 效果如下

3.5.1 不配置permitAllSecurityConfig时

https://raw.githubusercontent.com/longfeizheng/longfeizheng.github.io/master/images/security/spring-security-oauth207.gif

3.5.2 配置permitAllSecurityConfig时

https://raw.githubusercontent.com/longfeizheng/longfeizheng.github.io/master/images/security/spring-security-oauth208.gif

4. 代码下载

5. 推荐文章

  1. Java创建区块链系列
  2. Spring Security源码分析系列
  3. Spring Data Jpa 系列
  4. 【译】数据结构中关于树的一切(java版)
  5. SpringBoot+Docker+Git+Jenkins实现简易的持续集成和持续部署
文章目录
  1. 1. 1. 前言
  2. 2. 2. 解决思路
  3. 3. 3. 代码修改
    1. 3.1. 3.1 添加PermitAuthenticationFilter类
    2. 3.2. 3.2 添加PermitAllSecurityConfig配置
    3. 3.3. 3.3 修改MerryyouResourceServerConfig,增加对制定路径的授权
    4. 3.4. 3.4 修改测试类SecurityOauth2Test
    5. 3.5. 3.5 效果如下
      1. 3.5.1. 3.5.1 不配置permitAllSecurityConfig时
      2. 3.5.2. 3.5.2 配置permitAllSecurityConfig时
  4. 4. 4. 代码下载
  5. 5. 5. 推荐文章