spring security authorization server token端点配置跨域访问

版本

spring-security-oauth2-2.3.8

问题

在网页端跨域访问spring-security-oauth2搭建的授权服务器,以ClientCredentials授权模式获取token,发生跨域请求失败。

解决

方案1

  1. WebSecurityConfig 增加忽略OPTIONS请求配置
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(HttpMethod.OPTIONS, "/oauth/token");
    }
}
  1. AuthorizationServerConfig 增加CORS配置
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
	@Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    	...
    	CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.setMaxAge(3600L);
        Map<String, CorsConfiguration> corsConfigurationMap = new HashMap<>();
        corsConfigurationMap.put("/oauth/token", corsConfiguration);
        endpoints.getFrameworkEndpointHandlerMapping().setCorsConfigurations(corsConfigurationMap);
    }
}

方案2

增加CROS过滤器

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class MyCorsFilter implements Filter {

    public MyCorsFilter() {
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization");

        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }
}

分析

跨域请求时会先发送OPTIONS请求,而OPTIONS请求头并不会携带认证信息
Spring源码中地址/oauth/token默认的访问控制策略是”fullyAuthenticated“,导致跨域时OPTIONS请求因认证失败而跳转/ERROR返回错误响应。
org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerSecurityConfiguration

@Override
protected void configure(HttpSecurity http) throws Exception {
	AuthorizationServerSecurityConfigurer configurer = new AuthorizationServerSecurityConfigurer();
	FrameworkEndpointHandlerMapping handlerMapping = endpoints.oauth2EndpointHandlerMapping();
	http.setSharedObject(FrameworkEndpointHandlerMapping.class, handlerMapping);
	configure(configurer);
	http.apply(configurer);
	String tokenEndpointPath = handlerMapping.getServletPath("/oauth/token");
	String tokenKeyPath = handlerMapping.getServletPath("/oauth/token_key");
	String checkTokenPath = handlerMapping.getServletPath("/oauth/check_token");
	if (!endpoints.getEndpointsConfigurer().isUserDetailsServiceOverride()) {
		UserDetailsService userDetailsService = http.getSharedObject(UserDetailsService.class);
		endpoints.getEndpointsConfigurer().userDetailsService(userDetailsService);
	}
	// @formatter:off
	http
       	.authorizeRequests()
           	.antMatchers(tokenEndpointPath).fullyAuthenticated()
           	.antMatchers(tokenKeyPath).access(configurer.getTokenKeyAccess())
           	.antMatchers(checkTokenPath).access(configurer.getCheckTokenAccess())
       .and()
       	.requestMatchers()
           	.antMatchers(tokenEndpointPath, tokenKeyPath, checkTokenPath)
       .and()
       	.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
	// @formatter:on
	http.setSharedObject(ClientDetailsService.class, clientDetailsService);
}

posted on   路过君  阅读(69)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
历史上的今天:
2020-04-11 spring 启动时自动运行
2020-04-11 spring cloud oauth2授权服务 默认tokenService配置源码
2020-04-11 spring cloud 搭建oauth2授权服务 使用redis存储令牌
2020-04-11 spring cloud oauth2授权服务 clientDetails配置源码
2020-04-11 spring 验证框架
2020-04-11 IDEA 插件整理
2020-04-11 spring security笔记 默认登陆页面源码

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示