gpt4 book ai didi

带有 Keycloak 的 Angular/Spring Boot 抛出 403

转载 作者:行者123 更新时间:2023-12-05 07:00:48 30 4
gpt4 key购买 nike

我在 this documentation 之后使用 Keycloak 11.0.2 和 Spring Security 保护我的 Spring Boot 应用程序.

我在 application.properties 中使用了基本的 Keycloak 配置:

    keycloak.auth-server-url=http://localhost:8085/auth
keycloak.realm=cirta
keycloak.resource=cirta-api
keycloak.public-client=false

我有一个单独的前端 Angular 应用程序,它在 Keylocak 中配置为不同的客户端;但与 Spring Boot 应用程序处于同一领域。从 Angular 应用程序,我在 HTTP header 中发送 Keycloak 提供的 token :

'Authorization' : 'Bearer ' + this.securityService.kc.token

当我访问调用 GET API 的 Angular 页面时,我收到一个blocked by CORS policy 错误:

Access to XMLHttpRequest at 'http://localhost:8080/api/modePaiements' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.

所以我尝试将 keycloak.cors=true 属性添加到 application.properties。添加该属性后,GET 调用就可以正常工作了。但是现在当我调用 POST/PUT API 时,我得到了一个Failed to load resource: the server responded with a status of 403 () 错误。

KeycloakWebSecurityConfigurerAdapter:

@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests().antMatchers("/api/*").hasRole("app-manager").anyRequest().permitAll();
}

Spring 示例应用程序: https://github.com/bilaldekar/kc

Angular 示例应用程序: https://github.com/bilaldekar/kc-ang

请求 header :

enter image description here

最佳答案

在我看来是一个 csrf 问题。

将以下内容添加到安全配置中

http.authorizeRequests().antMatchers("/api/*").hasRole("app-manager").anyRequest().permitAll()
.and().csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());

以上代码将在名为XSRF-TOKEN 的cookie 中设置CSRF token 。默认情况下,Angular 会读取此 cookie 以获取 CSRF token ,并将其添加到后续请求中。为了确保 Angular 可以读取它,我们将 Http only 设置为 False。这有其自身的安全隐患,因为现在可以通过脚本访问 CSRF token 。如果您不想这样做,另一种方法是从响应 header 中读取 X-XSRF-TOKEN token ,并使用 Angular 拦截器将其发送到后续请求 header 中。

更新:

在本地测试时,Angular 在 4200 上运行,Spring Boot 应用程序,Keycloak 服务器在 8080、8085 端口上运行。

通过以下步骤使用 Webpack Dev 服务器代理。 (你不再需要这个配置keycloak.cors=true)

environment.ts 中更新 apiUrl

apiUrl: '', //Spring Boot API

然后在src文件夹下添加一个proxy.conf.json,内容如下

{
"/api": {
"target": "http://localhost:8080",
"secure": false
},
"logLevel": "debug"
}

angular.json 服务命令中添加代理配置

"options": {
"browserTarget": "kc-ang:build",
"proxyConfig": "src/proxy.conf.json"
}

现在您会注意到 api 请求会发送到 localhost:4200/api/* 并且会通过上述配置路由到 spring boot 应用程序。

有了这个,与 XSRF 相关的 cookie 和 header 将成为请求的一部分,您应该不会遇到任何问题。

[![示例工作版本][1]][1]

更新 2:支持 CORS

如果你的前端和后端在不同的域,如果你必须支持 CORS,那么这就是需要做的

Spring 的安全配置应该允许 CORS 作为前端的来源(在本例中为 http://localhost:4200):

protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests().antMatchers("/api/*").hasRole("app-manager").anyRequest()
.permitAll()
.and().csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and().cors();
}

@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
configuration.setAllowCredentials(Boolean.TRUE);
configuration.addAllowedHeader("*");

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/api/*", configuration);
return source;
}

在 Angular 上,将 environment.ts 文件中的 apiUrl 更新为

apiUrl: '//localhost:8085'

在使用 Angular http 客户端进行任何写入操作(POST/PUT/DELETE)时,将 withCredentials 选项设置为 true。 (还要确保服务器端配置支持 CORS 的方法。在上面的 CORS 配置中,我们只允许 GET 和 POST。如果您需要支持 PUT/DELETE,请确保相应地更新 CORS 配置)

在这种情况下,更新 fournisseur.service.ts 中的以下方法

addFournisseur(fournisseur: Fournisseur): Observable<Fournisseur> {
return this.httpClient.post<Fournisseur>(this.envUrl + '/api/fournisseurs', fournisseur, {withCredentials: true});
}

关于带有 Keycloak 的 Angular/Spring Boot 抛出 403,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64025546/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com