首页 > 解决方案 > 重定向到 Keycloak 时来自 Angular 的 CORS 错误

问题描述

我在 Apache 端部署了一个 SPA 应用程序作为静态文件。
我使用 apache 模块 mod_auth_openidc 作为 RP 对用户进行身份验证。
我使用 Spring Boot 作为后端 API。我使用 Keycloak 作为 IDP。
在第一次身份验证期间,正确完成了对 Keycloak 的重定向,并且从 SPA 到 Java 后端的 API 调用工作正常。但是,会话到期后,当用户单击 SPA 中的链接时,他会自动重定向到 IDP(通过 HTTP 302 代码)。但这一次浏览器引发了 CORS 错误。因为 MIME 类型不正确。

这是 Apache 端使用的配置。

OIDCCryptoPassphrase a-random-secret-used-by-apache-oidc-and-balancer
OIDCClientID myapp
OIDCClientSecret xxxxxxxxxxxxxxxxxxx
OIDCScope "openid"
OIDCProviderMetadataURL https://keycloak-host/auth/realms/myclient/.well-known/openid-configuration
OIDCRedirectURI https://myapp-host/myapp/accueil

Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Credentials "true"
Header always set Access-Control-Allow-Methods "GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS"
Header always set Access-Control-Max-Age "3600"
Header always set Access-Control-Allow-Headers "Content-Type, Accept, X-Requested-With, Authorization"

<Location /myapp/>
    AuthType openid-connect
    Require valid-user
    LogLevel debug
</Location>

# only Api request is forwaded to backend Java
SetEnvIf Request_URI !"/myapp/api/*" no-j 
JkMount  /myapp/api/* app1

这是 Keycloak 配置:
有效的重定向 URIs = 'https://myapp-host/*'
Web Origins = '+'

您知道错误的原因吗?这是 Chrome 控制台中的错误:

拒绝执行来自 'https://keycloak-host/auth/realms/intradef/protocol/openid-connect/auth?response_type=code&scope=openid&client_id=mayapp&state=cdPzfatA1au8hWag3puQWeYXzlc&redirect_uri=https%3A%2F%2F10.29.150.131% 的脚本2Fmyapp%2Faccueil&nonce=MxMAAJWaVX0dCcHgHSp94S24_JTDJA6D8D4i6UloCx8' 因为它的 MIME 类型 ('text/html') 不可执行,并且启用了严格的 MIME 类型检查。

标签: angularkeycloaksingle-page-applicationmod-auth-openidc

解决方案


1.) 您为 SPA 使用了不合适的流程

没有理由保护静态文件。SPA 应该使用OpenId Connect Auth Code Flow + PKCE. 通常,为您的 SPA 技术使用一些经过认证的库就可以了。

顺便说一句:静态 CORS 配置不符合规范: https ://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers

在带有凭据的请求中,它被视为没有特殊语义的文字标头名称“*”。请注意,授权标头不能使用通配符,并且始终需要明确列出。

2.) API 也没有正确响应

它应该响应 401(未授权),而不是 302 重定向。302 被重定向到 Web 应用程序,而不是 SPA API 调用。SPA API 调用在后台,因此用户不会在后台看到任何登录屏幕。

整体设计不是 SPA/API 方法的最佳选择。我会使用更好的实现,然后你就不会遇到 CORS 问题。


推荐阅读