首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OWIN身份验证在本地运行良好,但在dev环境中却不起作用。

OWIN身份验证在本地运行良好,但在dev环境中却不起作用。
EN

Stack Overflow用户
提问于 2016-10-07 15:27:48
回答 1查看 817关注 0票数 0

我正面临着一些奇怪的问题。我在弹出窗口中有一个登录表单。当表单提交时,AJAX请求会以加密登录、密码和防伪令牌为参数发送到服务器。调用控制器方法,此方法检查用户输入并返回:

( a)如果用户输入不正确,则部分视图(登录表单)的HTML将被注入,而不是现有的登录表单。

( b)如果用户输入正确,则刷新页面,并为验证用户重新显示页面.我使用OWIN对用户进行身份验证。

Javascript - AJAX调用

代码语言:javascript
复制
"use strict";(function ($, undefined) {
$(document).ready(function () {
    $(document).on('submit', 'div.modal-dialog form', function () {
        let $form = $(this),
            //token = $('input[name="__RequestVerificationToken"]', form).val(),
            logindata = $form.serialize(),
            $formParent = $form.parent();
        $.ajax({
            url: $form.attr('action'),
            type: 'POST',//form.attr('method'),
            data: {
                mdata: b64Encode(logindata),
            },
            success: function (result) {
                if (result.resultsuccess) {
                    location.reload(true);
                }
                let $resultHtml = $('<div/>').html(result).contents();
                let mbody = $resultHtml.find('div.modal-body');
                if (mbody.length) {
                    $formParent.children().remove();
                    $formParent.html($resultHtml.find('div.modal-body').children());
                }
            },
            error: function (result) {
                console.log(result);
            }
        });
        return false;
    });



function GetAntiForgeryToken() {
    let tokenField = $("input[type='hidden'][name$='RequestVerificationToken']");
    if (tokenField.length == 0) {
        return null;
    } else {
        return {
            name: tokenField[0].name,
            value: tokenField[0].value
        };
    }
}

$.ajaxPrefilter(
    function (options, localOptions, jqXHR) {
        if (options.type !== "GET") {
            let token = GetAntiForgeryToken();
            if (token !== null) {
                if (options.data.indexOf("X-Requested-With") === -1) {
                    options.data = "X-Requested-With=XMLHttpRequest" + ((options.data === "") ? "" : "&" + options.data);
                }
                options.data = options.data + "&" + token.name + '=' + token.value;
            }
        }
    }
 );})(jQuery);

控制器

代码语言:javascript
复制
public class AccountController : Controller
{
    private CustomUserManager cman;

    public AccountController()
    {
        cman = new CustomUserManager();
    }
    public AccountController(CustomUserManager customUserManager)
    {
        cman = customUserManager;
    }
    //[HttpGet]
    [AllowAnonymous]
    public PartialViewResult LoginView()
    {
        LoginViewModel lm = new LoginViewModel();
        return PartialView("Login",lm);
    }



    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(string mdata)
    {
        LoginViewModel model = LoginViewModel.FromFormData(mdata);
        ValidationContext context = new ValidationContext(model);
        List<ValidationResult> results = new List<ValidationResult>();
        bool isValid = Validator.TryValidateObject(model, context, results);
        if (isValid)
        {
            var user = await cman.FindAsync(model.Email, model.Password);
            if (user != null)
            {
                await SignInAsync(user, model.RememberMe);
                //return JavaScript("location.reload(true);");
                return Json(new { resultsuccess = "1" });
            }
            else
            {
                ModelState.AddModelError("", "Invalid username or password.");
                return PartialView(model);
            }
        }
        else
        {
            results.ForEach(entry => ModelState.AddModelError("", entry.ErrorMessage));
            return PartialView(model);
         }
    }

    [HttpPost]
    //[ValidateAntiForgeryToken]
    public ActionResult Logout()
    {
        AuthenticationManager.SignOut();
        return Redirect("~/");
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing && cman != null)
        {
            cman.Dispose();
            cman = null;
        }
        base.Dispose(disposing);
    }

    private IAuthenticationManager AuthenticationManager
    {
        get { return HttpContext.GetOwinContext().Authentication; }
    }

    private async Task SignInAsync(ApplicationUser user, bool isPersistent)
    {
        //AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
        var identity = await cman.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
        AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
    }

    private void AddErrors(IdentityResult result)
    {
        foreach (var error in result.Errors)
        {
            ModelState.AddModelError("", error);
        }
    }
}

OWIN启动文件

代码语言:javascript
复制
public void Configuration(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/")
            //,CookieSecure = CookieSecureOption.SameAsRequest
        });
        // app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);


    }

所有这些东西在我的本地机器上都很好用。但是在dev服务器上,只有当用户登录/密码错误时,此代码才能工作:返回带有验证摘要的部分视图。如果登录/密码正确,页面将不会像我预期的那样刷新。如果我手动刷新页面,用户仍未登录。

当我在Chrome中尝试AJAX调用时,它失败了,错误有: ERR_CONNECTION_RESET,状态为0,在边缘,错误是:网络错误0x2eff,由于错误00002eff,无法完成操作。在Firefox中没有错误,但是身份验证仍然不起作用。但是,它的状态为200 OK,响应是:{"resultsuccess":"1"} (在Firefox中)。

我试着包起来

代码语言:javascript
复制
await SignInAsync(user, model.RememberMe);

在“尝试/捕捉”中的控制器中,但没有抛出任何异常。

还尝试过从另一个控制器调用AJAX操作-工作得很好。所以我甚至不知道这个奇怪的问题会发生在什么地方: OWIN,XMLHTTPRequest,或者可能是DEV环境中的一些IIS/机器设置。

更新

已经用简单的非AJAX登录表单创建了测试页面。同样,用户在表单提交上进行本地身份验证,而不是在DEV服务器上验证。所以看起来XMLHTTPRequest并不是问题所在。

更新2,因此它是在本地机器上设置的身份验证cookie,但由于某种原因没有设置在DEV上。

SignInAsync方法调用失败或cookie未由IIS或ASP.Net发送到浏览器

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-12 15:22:53

我的本地机器和DEV服务器之间的主要区别是IIS版本: IIS 10 (Windows 10)在我的本地和在DEV上的IIS 8.5 (Windows server 2012)。试图使用IIS8.5-owin身份验证在虚拟机上部署站点的做法也不起作用。曾经尝试过here的解决方案,但还是没能成功。

因此,不幸的是,我不得不从项目中删除OWIN并实现自定义成员资格提供程序,以便在DEV服务器上进行身份验证。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39920856

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档