Spring Security OAuth2 permitAll() 方法小记
程序员文章站
2024-03-19 14:10:34
...
1. 前言
在使用spring-security-oauth2
时,虽然配置了.antMatchers("/permitAll").permitAll()
,但如果在header
中 携带 Authorization Bearer xxxx
,OAuth2AuthenticationProcessingFilter
还是会去校验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时
3.5.2 配置permitAllSecurityConfig时
4. 代码下载
推荐阅读
-
Spring Security OAuth2 permitAll() 方法小记
-
Spring Security OAuth2实现使用JWT的示例代码
-
SpringBoot+Spring Security+JWT实现RESTful Api权限控制的方法
-
使用Spring Security控制会话的方法
-
Spring Security OAuth2实现使用JWT的示例代码
-
如何使用Spring Security手动验证用户的方法示例
-
自定义Spring Security的身份验证失败处理方法
-
使用Spring Security OAuth2实现单点登录
-
Spring Security结合JWT的方法教程
-
spring-boot集成spring-security的oauth2实现github登录网站的示例