当使用 Okta 来保护 API 访问时,即使在控制器上放置 @CrossOrigin("*") ,从 localhost:4200 的 Angular 应用程序到 localhost:8080 的 Spring Boot 应用程序的跨域调用也将被阻止。
以下是开发者控制台中的错误:
来自原点“http://localhost:4200”的 XMLHttpRequest 访问已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:无“访问” -Control-Allow-Origin'标头存在于请求的资源上。
这是 Angular 应用程序的代码,它使用标头中的访问令牌向后端发出 GET 请求。
getMessages(): Observable<Message[]>{
const apiUrl = 'http://localhost:8080/api/messages';
const accessToken = this.oktaAuth.getAccessToken();
const headers = new HttpHeaders({'Authorization': 'Bearer ' + accessToken, 'Access-Control-Allow-Origin': 'http://localhost:4200'});
return this.http.get<Message[]>(apiUrl, {headers: headers});
}
前端和后端都集成了 Okta 身份验证。
如果从 POM 中删除 spring boot Okta starter 依赖项,则可以通过放置在控制器上的 @CrossOrigin("") 进行跨域调用。但是如果 Spring Boot Okta starter 包含在 POM 中,@CrossOrigin("") 将不起作用。看起来 OKta 正在响应来自浏览器的预检请求。
尝试通过以下方式启用 CORS https://developer.okta.com/docs/guides/enable-cors/main/ 并在 Trusted Origins 中列出 http://localhost:4200 (类型 CORS )。但这是行不通的。 Okta 表示 Trusted Origins 配置不适用于 OAuth2。这似乎是一个常见的场景。但我在互联网上找不到可行的解决方案。有人有解决方案吗?谢谢
尝试通过以下方式启用 CORS https://developer.okta.com/docs/guides/enable-cors/main/
将 Angular 应用程序配置为 OAuth2 客户端不再被认为是最佳实践。这适用于所有基于 Javascript 的框架。如果您使用浏览器调试工具查看 Gmail、Facebook、Linkedin、Github 等,您不会在
Bearer
标头中找到带有 Authorization
令牌的单个请求(您只会找到 session饼干)。
原因是 BFF 模式:OAuth2 客户端是服务器上的中间件,负责对浏览器和 Javascript 代码隐藏令牌。浏览器和该中间件之间的请求通过会话(以及针对 CSRF 的保护)进行保护。在将请求转发到下游资源服务器之前,BFF 将会话中的 cookie 替换为 OAuth2 令牌。
现在你的 CORS 要点:如果这个中间件用于代理你的 Angular 应用程序和 REST API,那么所有请求都将具有相同的来源,并且 abracadabra,你的 CORS 错误将消失。
如果您将其配置为 OAuth2 客户端并在路由到 Spring 资源服务器时添加spring-cloud-gateway
过滤器,则
TokenRelay=
可以用作 BFF。我写了一个完整的教程那里。