1

我必须将 aspnetboilerplate (Asp.Net MVC + AngularJS 前端) Web 与 API 部分分开,并同时在 AngularJS + ASP.Net MVC 中对用户进行身份验证。这适用于单个域。当 API 托管在另一台服务器上时不起作用。

我的 MVC AccountController 操作登录:

AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = rememberMe }, identity);
return Json(new AjaxResponse {Success = true, TargetUrl = Request.ApplicationPath });

我的 Login.js 文件:

    $("#LoginButton").click(function(e) {
        e.preventDefault();
        abp.ui.setBusy(
            $("#LoginArea"),
            abp.ajax({
                url: "http://internallyAccesibleServer/Account/Login",
                //url: abp.appPath + "Account/Login",
                type: "POST",
                crossDomain: true,
                data: JSON.stringify({
                    tenancyName: $("#TenancyName").val(),
                    usernameOrEmailAddress: $("#EmailAddressInput").val(),
                    password: $("#PasswordInput").val(),
                    rememberMe: false
                })
            })
            .done(function(response) {
                abp.message.info("Login succeeded");})
            .fail(function(data) {
                abp.message.error(data.details, data.message);
            })
        );
    });

当我在 hxxp://internallyAccesibleServer/ 上运行它时 - 登录成功,我可以通过 AngularJS 访问授权资源。如果我从任何其他服务器运行相同的 Login.js 代码-我会暂时看到“登录成功”消息(我还在 internalAccesibleServer 上看到数据库/日志记录 - 所以 AJAX 请求工作正常),然后是 HTTP 响应 302 ,女巫是由 MVC 框架从 401 转换而来的,并且 Location 标头中的 URL 是“hxxp://otherserver/account/login” - 所以是请求的来源。

我关于 CORS 的 Web.config:

<httpProtocol>
    <customHeaders>
       <add name="Access-Control-Allow-Origin" value="*" />
       <add name="Access-Control-Allow-Methods" value="GET, POST, HEAD, OPTIONS" />
       <add name="Access-Control-Allow-Headers" value="Content-Type, x-xsrf-token" />
    </customHeaders>
 </httpProtocol>  

我相信这与 AJAX 和 MVC 之间的 cookie 共享有关。有人可以帮我解决这个问题,还是我应该开始在没有任何 MVC Razor 视图的情况下以完整的 Angular 重写 GUI 并使用其他身份验证类型,如 Bearer?已经使用 Razor 视图开发了完整的应用程序 :-(

我已经阅读了所有相关的 forum.aspnetboilerplate.com 消息,但是对于这个确切的问题没有答案。抱歉,如果链接将过期 - 添加主题名称以供参考。

分布式 WEBAPI 和 MVC 站点 hxxps://forum.aspnetboilerplate.com/viewtopic.php?f=2&t=871

在 3 层部署 ABP hxxps://forum.aspnetboilerplate.com/viewtopic.php?f=2&t=2376

3 层部署。与应用程序分离的 GUI hxxps://forum.aspnetboilerplate.com/viewtopic.php?f=2&t=3301

非常相似的问题(但没有解决方案):hxxps://stackoverflow.com/questions/43747413/sending-cookie-cross-domain-with-cors-using-jquery-hosted-with-mvc-troubleshoo

我还尝试在 .Web 层中实现我自己的 WebClient 并将 cookie 公开给后续的 AJAX 调用,但没有成功。让 AJAX 调用在浏览器中进行身份验证的最佳方法是什么?

PS这是我的OWIN启动配置寻址身份验证:

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationMode = AuthenticationMode.Active,
            CookieHttpOnly = false,
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            LogoutPath = new PathString("/Account/Logout"),
            Provider = new CookieAuthenticationProvider
            {
                OnApplyRedirect = ctx =>
                {
                    if (!IsAjaxRequest(ctx.Request))
                    {
                        ctx.Response.Redirect(ctx.RedirectUri);
                    }
                }
            }
        }); 

我将非常感谢任何答案。

4

2 回答 2

1

我认为这里的问题是 cookie 没有发送到浏览器。要解决这个问题,您首先需要添加以下标头来告诉浏览器将响应公开给您的前端 JS 代码。

<add name="Access-Control-Allow-Credentials" value="true" />

然后在您登录 JS 代码时,您需要使用

XMLHttpRequest.withCredentials

属性以启用使用 cookie 的跨站点请求。您可以执行以下操作:

$.ajax({
        url: "http://internallyAccesibleServer/Account/Login",
        type: "POST",
        contentType: "application/json",
        data: JSON.stringify({
            tenancyName: $("#TenancyName").val(),
            usernameOrEmailAddress: $("#EmailAddressInput").val(),
            password: $("#PasswordInput").val(),
            rememberMe: false
        }),
        xhrFields: {
            withCredentials: true
        }

关于重定向。根据 ABP文档,如果在响应中设置了 targetUrl 属性,那么它会重定向到它。

于 2019-04-18T09:06:55.357 回答
1

请按照此处的步骤操作:

在 ASP.NET Web API 2 中启用跨域请求

https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api

全局启用 CORS 上述方法也可用于跨 API 启用,而无需注释每个控制器:

public static void Register(HttpConfiguration config)
{
    var corsAttr = new EnableCorsAttribute("http://example.com", "*", "*");
    config.EnableCors(corsAttr);
}
于 2017-06-28T06:31:55.643 回答