如何将请求设置为已使用自定义身份详细信息进行身份验证?
How to set Request as Authenticated with Custom Identity details?
我的项目需要自定义身份验证,包括用户名、密码和自定义的第三个元素。
我已经编写了自定义代码来验证输入的详细信息并确定它们是否已通过身份验证,但是当我绘制屏幕时,请求似乎未被标记为已通过身份验证。
_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。
以下是自定义委托人的部分内容:
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"),
});
我已经完成了 this and this 和其他几个身份教程,但都没有成功。
我错过了什么?为什么我成功的身份验证过程没有将请求标记为已验证?
事实证明,我的问题出在传递到我的 CustomIdentity 和 ClaimsIdentity 基 class 的字符串身份验证类型中。值为 "ApplicationCookie" 时,请求将以 _LoginPartial.cshtml 可以找到的方式标记为已验证。
public class CustomIdentity : ClaimsIdentity
{
// Must set an authentication type for IsAuthenticated to be true
public CustomIdentity(string authenticationType) : base(authenticationType) {}
// ...
}
我在某处读到可以使用任何字符串,并且最初使用 "Password" 这样的值调用构造函数,例如
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")
};
我的项目需要自定义身份验证,包括用户名、密码和自定义的第三个元素。
我已经编写了自定义代码来验证输入的详细信息并确定它们是否已通过身份验证,但是当我绘制屏幕时,请求似乎未被标记为已通过身份验证。
_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。
以下是自定义委托人的部分内容:
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"),
});
我已经完成了 this and this 和其他几个身份教程,但都没有成功。
我错过了什么?为什么我成功的身份验证过程没有将请求标记为已验证?
事实证明,我的问题出在传递到我的 CustomIdentity 和 ClaimsIdentity 基 class 的字符串身份验证类型中。值为 "ApplicationCookie" 时,请求将以 _LoginPartial.cshtml 可以找到的方式标记为已验证。
public class CustomIdentity : ClaimsIdentity
{
// Must set an authentication type for IsAuthenticated to be true
public CustomIdentity(string authenticationType) : base(authenticationType) {}
// ...
}
我在某处读到可以使用任何字符串,并且最初使用 "Password" 这样的值调用构造函数,例如
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")
};