如何使用自定义标识详细信息将请求设置为已验证?

时间:2018-01-10 14:38:38

标签: c# asp.net-mvc authentication owin

我的项目需要自定义身份验证,包括用户名,密码和自定义的第三个元素。

我编写了自定义代码来验证输入的详细信息并确定它们是否经过身份验证,但是当我绘制屏幕时,请求似乎没有被标记为已通过身份验证。

_LoginPartial.cshtml

@using Microsoft.AspNet.Identity
@* this always evaluates to false - Why? *@
@if (Request.IsAuthenticated) 
{
    using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
    {
        @* stuff happens here *@
    }
}
else
{
        @* other stuff happens here *@
}

当我在调试中逐步执行时,我的处理登录请求的控制器遵循预期的流程。相关方法是:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    CustomAuthenticator authenticator = new CustomAuthenticator(repository);
    SignInStatus result = authenticator.Authenticate(model.CustomElement, model.UserName, model.Password);
    if (result == SignInStatus.Success)
    {
        CustomIdentity ident = (CustomIdentity)authenticator.Principal.Identity;
        HttpContext.GetOwinContext().Authentication.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
        HttpContext.GetOwinContext().Authentication.SignIn(new AuthenticationProperties { IsPersistent = true }, ident);
        if (returnUrl == null)
        {
            return View();
        }
        else
            return Redirect(returnUrl);
    }
    else
    {
        ModelState.AddModelError("", "Invalid login attempt.");
        return View(model);
    }
}

Authenticate()方法执行需要执行的操作来检查(非标识)表以验证提供的凭据。然后它创建自定义标识和主体。上面的Login()代码将此标识传递给OwinContext AuthenticationManager。

以下是自定义Principal的部分内容:

public class CustomPrincipal : IPrincipal
{
    public IIdentity Identity { get; set; }

    public CustomPrincipal(CustomIdentity identity)
    {
        Identity = identity;
    }
}

和身份:

public class CustomIdentity : ClaimsIdentity
{
    public CustomIdentity(string authenticationType) : base(authenticationType) { }

    public string CustomDetail { get; set; }
}

在Startup.cs中,我在Configuration()方法中有以下内容:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Login/Login"),
});

我参与了thisthis等身份教程以及其他一些没有成功的人。

我错过了什么?为什么我的成功身份验证过程没有将请求标记为已验证?

1 个答案:

答案 0 :(得分:0)

事实证明,我的问题是将字符串身份验证类型传递给我的CustomIdentity并传​​递给ClaimsIdentity基类。使用值“ApplicationCookie”,请求将以_LoginPartial.cshtml找到的方式标记为已验证。

public class CustomIdentity : ClaimsIdentity
{
    // Must set an authentication type for IsAuthenticated to be true
    public CustomIdentity(string authenticationType) : base(authenticationType) {}
    // ...
}

我在某处读过任何字符串都可以使用,并且最初使用诸如“密码”之类的值调用构造函数,例如。

ClaimsIdentity myIdentity = new CustomIdentity("Password");

当我将authenticationType的字符串值更改为“ApplicationCookie”时,所有操作都符合预期。

ClaimsIdentity myIdentity = new CustomIdentity("ApplicationCookie");

最后一点:我还有一个@ Html.AntiForgeryToken(),要求我明确包含名称标识符和身份提供者声明:

var claims = new List<Claim>
{
    new Claim(ClaimTypes.NameIdentifier, user.Id),
    new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "CEP_UAS")
};