【问题标题】:Cross-Origin Request Blocked while authenticating身份验证时阻止跨域请求
【发布时间】:2016-08-05 00:47:22
【问题描述】:

我正在尝试设计一个保护各种后端 API 的 OAuth2 身份验证系统。我首先下载并安装the three interconnected Spring Boot / Cloud / OAuth2 apps in this github project

但我的项目需要两个主要的架构更改:

1.) The main portal UI must be running in Node.js, so that users can  
    view a public site and also login using a Node.js-hosted app that  
    makes REST calls to a backend authentication server, without feeling  
    like they are being redirected anywhere for authentication.   

2.) My app requires multi-factor authentication, so I need to create (or  
    at least customize) my own endpoints on the `authserver` app instead  
    of relying to the standard password authentication endpoint.  

需要进行哪些特定更改才能使我的 Node.js 托管 UI 应用程序能够成功地与 authserver 应用程序和 resource 应用程序交互?

目前,将 AngularJS 登录代码添加到我自己的 Node.js 门户应用程序或 github 示例中的 ui 应用程序会导致 FireFox 控制台在 AngularJS 代码尝试调用 @ 时显示以下错误消息987654332@ 应用在port 9000 上运行:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading  
the remote resource at http://localhost:9000/login-form. (Reason: CORS  
header 'Access-Control-Allow-Origin' missing). <unknown>

Cross-Origin Request Blocked: The Same Origin Policy disallows reading  
the remote resource at http://localhost:9000/login-form. (Reason: CORS  
request failed).

调用我添加到authserver 端点的新/login-form 端点的AngularJS 代码是:

$scope.credentials = {};

$scope.loginError = false;
$scope.showLogin = false;

$scope.loginShow = function() {
    $scope.showLogin = true;
    console.log('filler to add break point for debugger.');
};

$scope.loginLocal = function() {
    console.log('Just filler to add a break point in debugger.');
        var funcJSON = { 'type': 'Message',
                 'content1': $scope.credentials.username,
                 'content2': $scope.credentials.password
    };
        console.log('filler to add break point.');
    $http.post('http://localhost:9999/uaa/login-form', funcJSON).then(function(response) {
        if(response.data.content1==='success'){
            $scope.Oauthenticated = true;
            console.log('filler to add a break point');
        }else {
            $scope.Oauthenticated = false;
            $scope.loginError = true;
            console.log('filler to add break point');
        }
    });
};

FireFox 调试器显示上面显示的在 FireFox 控制台中引发错误的 AngularJS 代码行是:

$http.post('http://localhost:9999/uaa/login-form', funcJSON).then(function(response) {

我在authserver 应用程序中的AuthserverApplication.java 文件和you can read my entire new AuthserverApplication.java file at a file sharing site by clicking on this link 中添加了一个新的/login-form 端点。

我愿意在 Spring Boot 中运行主门户 UI 应用程序。我已经读过这需要使用 @EnableSidecar 注释。但是,无论新登录表单是从上面的 github 链接还是从我的 Node.js 托管的门户 UI 运行在 Spring Cloud ui 应用程序中,我都会收到相同的错误消息。 那么,我需要更改哪些内容才能从我的 Node.js 托管的门户应用程序管理此身份验证的安全方式?


正在进行的研究:


根据@Ulises 的建议,我添加了代码来覆盖AuthserverApplication.java 的方法。我还仔细检查了 url 并稍微更改了 $http.post(... 调用的 url(我在 OP 中在线更改了上面的内容以避免混淆。结果是 FireFox 控制台中的相同错误,加上 authserver 应用程序的 Spring Boot 日志中的请求的显式日志。

您可以read my new AuthserverApplication.java class including @Ulises's suggestion at a file sharing site by clicking this link发起调用的 Node.js 托管应用正在 port 7000 上运行。

你可以read the entire Spring Boot log for the request at a file sharing site by clicking on this link


同样,当我将建议的方法更改为:

@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/login-form").allowedOrigins("http://localhost*");
}

我收到the Spring Boot error log that you can read at a file sharing site by clicking on this link。 FireFox 调试器的“网络”选项卡给出了 401 错误,并带有以下原始标头:

请求头:

Host: localhost:9999
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://localhost:7000
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type,x-requested-with
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

响应头:

Cache-Control: no-cache, no-store, max-age=0, must-revalidate, no-store
Content-Type: application/xhtml+xml;charset=UTF-8
Date: Wed, 13 Apr 2016 09:32:40 GMT
Expires: 0
Pragma: no-cache, no-cache
Server: Apache-Coyote/1.1
Transfer-Encoding: chunked
WWW-Authenticate: Bearer realm="null", error="unauthorized", error_description="Full authentication is required to access this resource"
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
x-content-type-options: nosniff

即使我将以下方法添加到 AuthserverApplication.java 内部的 LoginConfig 内部类以尝试让 Spring Security 忽略 /login-form 端点,同样的新错误仍然存​​在:

@Override
public void configure(WebSecurity webSecurity) throws Exception {
    webSecurity.ignoring().antMatchers("/login-form", "/error");
}

我目前正在阅读the Spring OAuth2 Developer's Guide at this link,它指的是sample apps on github at this link。但是,示例应用程序使用已过时的 JSP,并且没有解决本 OP 中描述的用例。

【问题讨论】:

    标签: spring spring-security spring-boot spring-cloud spring-security-oauth2


    【解决方案1】:

    在您的AuthServerApplication 覆盖方法addCorsMapping(CorsRegistry) 中来自WebMvcConfigurerAdapter,如下所示:

        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/login-form").allowedOrigins("http://localhost:9000");
        }
    

    或者您从哪里调用它。您还可以使用* 来处理所有内容和/或添加任何细粒度配置

    【讨论】:

    • 这并没有解决问题。我会在几分钟后发布更新。
    • 我刚刚在我的 OP 末尾的 ONGOING RESEARCH 部分中添加了尝试您的建议的结果。还有其他想法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-08
    • 1970-01-01
    • 2016-05-04
    • 2021-06-26
    • 2014-10-13
    相关资源
    最近更新 更多