Keycloak angular 不存在“Access-Control-Allow-Origin”标头
Posted
技术标签:
【中文标题】Keycloak angular 不存在“Access-Control-Allow-Origin”标头【英文标题】:Keycloak angular No 'Access-Control-Allow-Origin' header is present 【发布时间】:2017-12-16 13:00:15 【问题描述】:我已将 keycloak 与 Angular 应用程序集成。基本上,前端和后端都在不同的服务器上。后端应用程序在 apache tomcat 8 上运行。前端应用程序在 JBoss 欢迎内容文件夹上运行。
角度配置
angular.element(document).ready(function ($http)
var keycloakAuth = new Keycloak('keycloak.json');
auth.loggedIn = false;
keycloakAuth.init( onLoad: 'login-required' ).success(function ()
keycloakAuth.loadUserInfo().success(function (userInfo)
console.log(userInfo);
);
auth.loggedIn = true;
auth.authz = keycloakAuth;
auth.logoutUrl = keycloakAuth.authServerUrl + "/realms/app1/protocol/openid-connect/logout?redirect_uri=http://35.154.214.8/hrms-keycloak/index.html";
module.factory('Auth', function()
return auth;
);
angular.bootstrap(document, ["themesApp"]);
).error(function ()
window.location.reload();
);
);
module.factory('authInterceptor', function($q, Auth)
return
request: function (config)
var deferred = $q.defer();
if (Auth.authz.token)
Auth.authz.updateToken(5).success(function()
config.headers = config.headers || ;
config.headers.Authorization = 'Bearer ' + Auth.authz.token;
deferred.resolve(config);
).error(function()
deferred.reject('Failed to refresh token');
);
return deferred.promise;
;
);
module.config(["$httpProvider", function ($httpProvider)
$httpProvider.interceptors.push('authInterceptor');
]);
请求标头
Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:authorization
Access-Control-Request-Method:GET
Connection:keep-alive
Host:35.154.214.8:8080
Origin:http://35.154.214.8
Referer:http://35.154.214.8/accounts-keycloak/
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
网络控制台出错。
XMLHttpRequest cannot load http://35.154.214.8:8080/company/loadCurrencyList. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://35.154.214.8' is therefore not allowed access.
后端的 Cors 过滤器
@Component
public class CORSFilter implements Filter
static Logger logger = LoggerFactory.getLogger(CORSFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException
@Override
public void doFilter(ServletRequest request, ServletResponse res,
FilterChain chain) throws IOException, ServletException
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "*");
chain.doFilter(request, response);
public void destroy()
【问题讨论】:
您是否在运行后端的服务器上启用了CORS? 是的。再次检查问题。问题已更新。似乎令牌没有通过。 @boycod3 问题解决了吗? 【参考方案1】:我与 KeyCloak 和 CORS 以及所有这一切斗争了大约两周,这是我的解决方案(针对 keycloak 3.2.1):
这都是关于配置 KeyCloak 服务器的。 看来,您的领域的 WebOrigin 需要是
*只有一个来源“*”。
就是这样,我需要什么。
如果你输入你的服务器作为 WebOrigin,麻烦就开始了。 当您在 javascript 中调用 keycloak.init 时,keycloak 不会生成 CORS 标头,因此您必须手动配置它们,并且一旦您这样做,并在成功初始化后调用 keycloak.getUserInfo - 您会得到双 CORS 标头,这不是允许。
在 keycloak 邮件列表深处的某个地方声明,您需要在 keycloak.json 中设置 enable-cors=true,但在 keycloak.gitbooks.io 上没有任何内容。所以这似乎不是真的。
他们在描述 JavaScript 和 Node.Js 适配器时也没有提到 CORS,我不知道为什么,似乎根本不重要。
您似乎也不应该触摸 WildFly 配置来提供 CORS 标头。
此外,OIDC 中的 CORS 是一个特殊的 KeyCloak 功能(而不是错误)。
希望这个答案对您有帮助。
【讨论】:
enable-cors
在 Java 适配器部分的 Keycloak 文档中进行了描述和解释。
在生产环境中这样做是很糟糕的,并且违背了首先使用 keycloak 的原因(例如安全性)
“enable-cors 在 Java 适配器部分的 Keycloak 文档中进行了描述和解释”在 2 年的间歇性实验中,我仍然无法确定“enable-cors”是否在全部。在我尝试过的任何地方,它肯定从未做过一件事:启用 CORS 标头。
好痛苦
我正在使用 Keycloak 10.0.1 我为客户端 Web Origins 添加了一个 +,它在我的 Angular 9.1 应用程序中工作。【参考方案2】:
请务必注意,将您的网络来源设置为“*”会打开一个巨大的安全漏洞。它允许来自任何域的任何脚本在该用户的浏览器中代表该用户发出请求。
每当您发现自己以这样的方式禁用安全功能时,您需要考虑安全功能存在的原因。
参见8.1.1 of the Keycloak docs中的“Web Origins”
【讨论】:
我尝试设置 url 甚至尝试 *.我仍然得到同样的错误。任何想法?我正在使用 ajax 访问我的后端端点(由 keycloak 保护)【参考方案3】:对我有用的解决方案是将 Web Origins URL(我的客户端,而不是领域)从例如:http://localhost:3000/
设置为 http://localhost:3000
(请注意末尾缺少 /
)。这样,您就不会使用*
将其打开到所有 URL。
【讨论】:
我在非本地主机网络源上遇到了同样的问题,删除尾部斜杠也对我有用。谢谢 这个解决方案也对我有用。它应该是公认的答案。 是的,即使使用 15.0.2,这对我也有用,斜杠非常重要:|Valid Redirect URIs: http://localhost:9700/*
Base URL: http://localhost:9700
Web Origins: http://localhost:9700
【参考方案4】:
我遇到了同样的问题,并且(至少)对于 Keycloak Server 版本 8.0.1,您可以添加一个“+”作为“Web Origins”字段的输入,这似乎是最佳选择。
“+”的效果应该与添加(见下面的屏幕截图)“http://localhost:4200”作为“Web Origins”条目相同。
这就是“Web Origins”字段工具提示的意思:
“允许 CORS 来源。要允许“有效重定向 URI”的所有来源,请添加“+”。要允许所有来源,请添加“*”。”(参见下面的屏幕截图)
【讨论】:
【参考方案5】:我有同样的 CORS 错误。 KeyCloak 的新手。尝试将 web-origin 设置为“*”、“+”和特定的 url。没有任何效果。直到我将客户端设置上的“访问类型”更改为公开。然后将 web-origin 设置为特定 url 和 + 的两个选项都起作用。由于设置为 * 不安全,所以没有尝试。
当访问类型设置为机密时,它又开始出现 CORS 错误。我正在尝试使用 PKCE(代码流)进行授权流程。
使用版本 10.0.2。
有效设置的屏幕截图:
【讨论】:
您是否解决了机密访问类型问题?我有同样的问题,但我不想使用公共访问类型。这可能与同一站点的 cookie 政策有关吗?【参考方案6】:这是一个相当古老的问题,但无论如何我都会回答它。它可能会帮助某人。在 keycloak 管理页面中转到 clients->your client
。您可以在下面看到一个名为web origins
的字段。在那里您输入您的网址,您的问题将得到解决。
【讨论】:
【参考方案7】:您给出了自己问题的答案,在客户端级别(而不是领域级别!)将 WebOrigin 添加为 *,这对您有用,但在我自己的情况下却没有。实际上,删除 * 对我来说是个窍门,因为 KC 发送了两次 CORS 标头 - 删除它,剥离它一次......
感谢您的回答,我很幸运地找到了我的问题的答案...
我们都同意的是,KC 文档至少很差。
它是为傻瓜而写的,但是....我们不是傻瓜,主题也不是......
它没有解释技术细节。例如,端点的响应是什么。搜索网络(两周)确实有所帮助 - 但为什么没有在文档中列出?
一个例子。但是我有几个...
我们可以帮忙处理文档吗?
【讨论】:
当然你可以帮忙,这都是开源的,将你的拉取请求发送到github.com/keycloak/keycloak-documentation,我们将非常乐意审查它。 完全同意@SébastienBlanc,抱怨某事并不能让它变得更好。【参考方案8】:我遇到了同样的问题,在我的情况下,它是由在 keycloak js 适配器创建中使用选项对象引起的,其中身份验证服务器的 url 被错误地设置为 http 而不是 https:
const keycloak = Keycloak(
url: 'http://my-keycloak-auth-server/auth',
realm: 'myRealm',
clientId: 'myClient'
);
但正确的是
const keycloak = Keycloak(
url: 'https://my-keycloak-auth-server/auth',
realm: 'myRealm',
clientId: 'myClient'
);
【讨论】:
【参考方案9】:在使用 Angular 6、Spring Boot for REST Web Services 和 Keycloak 时遇到了同样的问题。
密钥斗篷地址:KEYCLOAK Angular 6 应用地址:ANGULAR_APP 两个使用 Keycloak 和 Spring Autoconfiguration 保护的 REST WS:AA、BB
流程是:Angular App request(GET) AA, AA request(GET) BB
使用 XMLHttpRequest 错误类似于: 无法加载 AA。对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问 Origin 'ANGULAR_APP'。
使用 Angular 的 Observable 是: 无法加载 AA:从“BB”重定向到“KEYCLOAK”已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问 Origin 'ANGULAR'。
尝试使用网络来源:* 没有解决方案
从来不知道为什么 Keycloak 会进行导致问题的重定向
当我将服务 AA 中的安全性从 Keycloak + Autoconfigure 切换到 Keycloak + Spring Security 时,问题神奇地消失了:https://developers.redhat.com/blog/2017/05/25/easily-secure-your-spring-boot-applications-with-keycloak/
因此失去了很多天的睡眠。只是留下这个,以防有人遇到类似的事情。
【讨论】:
【参考方案10】:我在初始化时添加了这一行...
this.keycloakAuth.init( onLoad: '需要登录', 流:'隐式' )
【讨论】:
【参考方案11】:虽然不是在 Angular 中,但与 keycloak-js
发生了类似的错误:我可以使用文档中的代码成功登录:
keycloak.init(
onLoad: 'login-required',
).then(function(authenticated)
alert(authenticated ? 'authenticated' : 'not authenticated');
).catch(function()
alert('failed to initialize');
);
但连续调用(在我的情况下为keycloak.loadUserProfile()
,调用account
端点)最终会出现CORS 错误。
后来我发现我以一种糟糕的方式操纵了我的代码,以至于连续调用与init
发生了竞争条件!事后看来很明显,但是..
TLDR;如果您在 init
调用完成之前调用 keycloak 端点,响应将缺少 CORS 标头,您将收到 CORS 错误!这只是意味着您没有经过身份验证。
【讨论】:
【参考方案12】:从 keycloak 12 升级到 15 后,我遇到了类似的问题。
还升级了 keycloak.js 文件后,在我的 Web 应用程序中找到:https://your-keycloak-server/auth/js/keycloak.js
,它又开始工作了。
【讨论】:
以上是关于Keycloak angular 不存在“Access-Control-Allow-Origin”标头的主要内容,如果未能解决你的问题,请参考以下文章
Angular2+、SpringBoot 2.1.9、Keycloak:CORS 配置不起作用
Angular - Spring Boot - Keycloak - 401错误