keycloak CORS 过滤器弹簧靴
Posted
技术标签:
【中文标题】keycloak CORS 过滤器弹簧靴【英文标题】:keycloak CORS filter spring boot 【发布时间】:2017-04-29 11:56:54 【问题描述】:我正在使用 keycloak 来保护我的休息服务。我指的是给定here 的教程。我创建了其余部分和前端。现在,当我在后端添加 keycloak 时,当我的前端调用 api 时出现 CORS 错误。
Spring Boot 中的 Application.java 文件看起来像
@SpringBootApplication
public class Application
public static void main( String[] args )
SpringApplication.run(Application.class, args);
@Bean
public WebMvcConfigurer corsConfiguration()
return new WebMvcConfigurerAdapter()
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/api/*")
.allowedMethods(HttpMethod.GET.toString(), HttpMethod.POST.toString(),
HttpMethod.PUT.toString(), HttpMethod.DELETE.toString(), HttpMethod.OPTIONS.toString())
.allowedOrigins("*");
;
application.properties 文件中的 keycloak 属性如下所示
keycloak.realm = demo
keycloak.auth-server-url = http://localhost:8080/auth
keycloak.ssl-required = external
keycloak.resource = tutorial-backend
keycloak.bearer-only = true
keycloak.credentials.secret = 123123-1231231-123123-1231
keycloak.cors = true
keycloak.securityConstraints[0].securityCollections[0].name = spring secured api
keycloak.securityConstraints[0].securityCollections[0].authRoles[0] = admin
keycloak.securityConstraints[0].securityCollections[0].authRoles[1] = user
keycloak.securityConstraints[0].securityCollections[0].patterns[0] = /api/*
我正在调用的示例 REST API
@RestController
public class SampleController
@RequestMapping(value ="/api/getSample",method=RequestMethod.GET)
public string home()
return new string("demo");
前端keycloak.json属性包括
"realm": "demo",
"auth-server-url": "http://localhost:8080/auth",
"ssl-required": "external",
"resource": "tutorial-frontend",
"public-client": true
我得到的 CORS 错误
XMLHttpRequest cannot load http://localhost:8090/api/getSample. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access. The response had HTTP status code 401.
【问题讨论】:
您可能更喜欢问一个具体的问题。否则,您可能会得到对您无效的答案。 你能提供整个堆栈跟踪吗? 服务器端没有错误。因此没有堆栈跟踪。当我的 angularJS 应用程序进行其余调用时,客户端出现错误我在浏览器控制台上收到 CORS 错误 你解决了这个问题吗?我有同样的问题 您解决了这个问题吗?我也遇到了同样的问题。 【参考方案1】:尝试像我的示例一样创建您的 CORS bean。我最近经历了同样的事情(让 CORS 工作),这是一场噩梦,因为 SpringBoot CORS 支持目前不如 MVC CORS 强大或简单。
@Bean
public FilterRegistrationBean corsFilter()
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
这就是我设置它以接受任何原始应用程序范围的方式,但是如果您更改一些参数,您应该能够复制您想要的内容。 IE。如果您只想添加您提到的方法,请链接一些addAllowedMethod()
。允许的来源将相同,然后您的 addMapping("/api/*")
将变为 source.registerCorsConfiguration("/api/*", config);
。
编辑:
Spring Data Rest and Cors
看看这个。 Sebastian 是 Spring 工程团队的一员,所以这与您将获得的官方答案一样好。
【讨论】:
下周假期回来后,我一定会告诉你的 将我的 bean 更改为您发布的内容不起作用。我认为我尝试使用 spring mvc 而根本不使用 spring boot【参考方案2】:我知道.. 问题很老了。 但是,如果您在使用 Spring Boot + Keycloak 进行本地开发时遇到问题,您可以使用 Config
keycloak.cors=true
在您的 application.properties 中。
干杯:)
【讨论】:
为我工作!如果您并不真正关心 CORS(例如构建一个应用程序来学习像我这样的东西),那就是要走的路。我还使用RepositoryRestConfigurer
禁用了CORS,就像这里***.com/a/60014831/9134945【参考方案3】:
我无权访问代码示例,但根据您包含的代码配置,似乎缺少配置会导致 spring 排除 CORS 标头。
J。 West 的回应类似于我最近遇到的 Spring 和 CORS 问题,但是我会提醒您查看 Spring 示例引用的实现,因为有两个。 Spring Security 和 Spring MVC Annotations。这两种实现相互独立,不能组合使用。
当您使用基于过滤器的方法时(甚至归结为),关键是将允许凭据设置为 true,以便浏览器跨域发送身份验证标头。我还建议使用上面提出的完整代码方法,因为这将允许您通过属性注入或服务注册表创建一个可配置得多的 Web 应用程序,以便在多个域或环境中进行部署。
【讨论】:
注释的要点。我编辑了我的答案,以包含一个指向 Spring 工程师活跃的类似问题的链接。如果你有同样的问题,我猜你在某个时候遇到过。【参考方案4】:Access-Control-Allow-Origin
标头应该由服务器应用程序根据向服务器应用程序的请求中提供的Origin
请求标头设置。通常,浏览器在感知到跨源请求时会在请求中设置Origin
标头。他们希望有一个Access-Control-Allow-Origin
标头作为响应以允许它。
现在,对于 keycloak,我遇到了同样的问题。查看this,似乎keycloak 没有添加Access-Control-Allow-Origin
标头以防错误响应。但是,对我来说,即使响应成功,它也不会在响应中添加此标头。
查看代码并添加断点,我注意到客户端对象的 webOrigin 没有从 Origin
标头中填充,即使已通过,因此 CORS 没有添加访问控制响应标头。
我能够通过在 CORS 构建调用之前添加以下代码行来使其工作:
client.addWebOrigin(headers.getRequestHeader("Origin").get(0));
之前:
Cors.add(request, Response.ok(res, MediaType.APPLICATION_JSON_TYPE)).auth().allowedOrigins(client).allowedMethods("POST").exposedHeaders(Cors.ACCESS_CONTROL_ALLOW_METHODS).build();
一旦我使用此更改构建代码并启动服务器,我就开始获取三个访问控制响应标头:
Access-Control-Expose-Headers: Access-Control-Allow-Methods
Access-Control-Allow-Origin: http://localhost:9000
Access-Control-Allow-Credentials: true
我正在使用客户端凭据授予类型;因此我只在buildClientCredentialsGrant
TokenEndpoint.java#L473 中添加了它。
我仍然需要做更多的代码潜水,以便确定这是一个成功响应的错误,并找到一个更好的位置在 keycloak 代码中的客户端对象上设置它(比如客户端对象在哪里正在建设中)
欢迎您试一试。
更新: 我收回这个。我在 keycloak 中重新注册了我的客户端,根 URL 为http://localhost:9000(这是我的前端的应用程序端口),我开始获取正确的访问控制响应标头。希望对您有所帮助。
【讨论】:
【参考方案5】:我来到这里时遇到了同样的问题并修复了它,只对 OPTIONS 方法省略了身份验证,如下所示:
keycloak.securityConstraints[0].security-collections[0].omitted-methods[0]=OPTIONS
它对我有用,因为 OPTIONS 请求 Keycloack 确实,不包括身份验证标头。
更新 我的浏览器缓存有问题,所以我看不到后端代码更改的真正影响。看起来真正对我有用的是在 @RestController 级别启用所有 CORS 起源,如下所示:
@CrossOrigin(origins = "*")
@RestController
public class UsersApi ...
【讨论】:
【参考方案6】:我知道问题太老了,但是我找到了更好的解决方案。 Read more at official documentation
在您的 application.yml 文件中
keycloak:
auth-server-url: http://localhost:8180/auth
realm: CollageERP
resource: collage-erp-web
public-client: true
use-resource-role-mappings: true
cors: true
cors-max-age: 0
principal-attribute: preferred_username
cors-allowed-methods: POST, PUT, DELETE, GET
cors-allowed-headers: X-Requested-With, Content-Type, Authorization, Origin, Accept, Access-Control-Request-Method, Access-Control-Request-Headers
或者您可以使用 application.properties 文件进行配置
keycloak.auth-server-url= http://localhost:8180/auth
keycloak.realm= CollageERP
keycloak.resource= collage-erp-web
keycloak.public-client= true
keycloak.use-resource-role-mappings= true
keycloak.cors= true
keycloak.cors-max-age= 0
keycloak.principal-attribute= preferred_username
keycloak.cors-allowed-methods= POST, PUT, DELETE, GET
keycloak.cors-allowed-headers= X-Requested-With, Content-Type, Authorization, Origin, Accept, Access-Control-Request-Method, Access-Control-Request-Headers
还有我的 java adaper 类
import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import javax.ws.rs.HttpMethod;
@KeycloakConfiguration
@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter
@Override
protected void configure(HttpSecurity http) throws Exception
super.configure(http);
http.cors().and().authorizeRequests()
.antMatchers(HttpMethod.OPTIONS).permitAll()
.antMatchers("/api/**")
.authenticated()
.anyRequest().permitAll();
http.csrf().disable();
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
auth.authenticationProvider(keycloakAuthenticationProvider());
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy()
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
@Bean
public KeycloakConfigResolver KeycloakConfigResolver()
return new KeycloakSpringBootConfigResolver();
【讨论】:
【参考方案7】:当您的客户端发送 Authentication 标头时,您不能使用 允许的起源(“*”)。您必须配置特定的源 URL。
【讨论】:
那行不通。我将 allowedOrigins 更改为运行客户端的 URL。在我的项目中,它在 localhost:9000 上运行。即使更改后我仍然收到错误【参考方案8】:由于您在 application.properties 文件中设置了属性 keycloak.cors = true
,因此您必须在 Keycloak 服务器中提及启用 CORS 的来源。为此,请按照以下步骤操作。
转到Clients -> Select the client (Token owner) -> Settings -> Web Origins
逐一添加来源或添加 * 以允许所有来源。
完成此操作后,您必须获得一个新令牌。 (如果您解码令牌,您将看到您的来源为allowed-origins": ["*"]
)
设置属性keycloak.cors = false
是另一种选择。但这完全禁用了 CORS。
【讨论】:
以上是关于keycloak CORS 过滤器弹簧靴的主要内容,如果未能解决你的问题,请参考以下文章
弹簧靴。 HMAC 认证。如何添加自定义 AuthenticationProvider 和 Authentication 过滤器?
弹簧靴。 HMAC 认证。如何添加自定义 AuthenticationProvider 和 Authentication 过滤器?