【发布时间】:2016-05-25 10:46:39
【问题描述】:
在我的 ASP.NET MVC 5 应用程序中,我需要使用自定义身份验证。基本上是一个自定义库,我在其上调用一个方法并返回一个包含用户信息的对象。
我创建了一个新的 MVC 5 应用程序并选择了“无身份验证”选项。然后我添加了一个 Http 模块,目前看起来像这样:
private void Context_AuthenticateRequest(object sender, EventArgs e)
{
// Make the call to authenticate.
// This returns an object with user information.
AuthResult result = new AuthLib().SignOn();
// Inspect the returned object and create a list claims.
var claims = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, result.Username),
new Claim(ClaimTypes.GivenName, result.Name)
}
claims.AddRange(result.Groups.Select(g => new Claim(ClaimType.Role, g));
// Create principal and attach to context
var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, "Sso");
HttpContext.Current.User = principal;
Thread.CurrentPrincipal = principal;
}
private void Context_PostAuthenticateRequest(object sender, EventArgs e)
{
var principal = ClaimsPrincipal.Current;
ClaimsAuthenticationManager transformer = FederatedAuthentication.SessionAuthenticationModule.FederationConfiguration.IdentityConfiguration.ClaimsAuthenticationManager;
transformer.Authenticate(string.Empty, principal);
}
我的 claimtransformer 如下所示:
public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
{
if (!incomingPrincipal.Identity.IsAuthenticated)
{
return base.Authenticate(resourceName, incomingPrincipal);
}
ClaimsPrincipal newPrincipal = CreateApplicationPrincipal(incomingPrincipal);
EstablishSession(newPrincipal);
return newPrincipal;
}
private void EstablishSession(ClaimsPrincipal newPrincipal)
{
var sessionToken = new SessionSecurityToken(newPrincipal, TimeSpan.FromHours(8));
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken);
}
private ClaimsPrincipal CreateApplicationPrincipal(ClaimsPrincipal incomingPrincipal)
{
// Convert AD group to known role in our application.
string group = incomingPrincipal.FindFirst(ClaimTypes.Role).Value;
string role = new ADGroupToRoleConverter().ConvertADGroupToRole(group);
// Add claims for group.
// These would be loaded from a db.
List<Claim> claims = new ClaimDb().GetClaimsForRole(role);
// Just copy the claims for id and given name.
claims.Add(incomingPrincipal.FindFirst(ClaimTypes.NameIdentifier));
claims.Add(incomingPrincipal.FindFirst(ClaimTypes.GivenName));
return new ClaimsPrincipal(new ClaimsIdentity(claims, "MyApp"));
}
我面临的主要问题是,即使存在会话,也会为每个请求调用身份验证步骤。如何检测会话存在并仅加载会话而不是完成整个身份验证过程。
另一个问题是对身份验证库的调用可能需要一段时间。我想理想情况下它也应该移到索赔转换器中?
任何进一步改进此代码的想法也非常感谢。
如果有不清楚的地方或者我需要提供更详细的信息,请告诉我。
【问题讨论】:
-
看起来您需要缓存声明 - 这看起来接近您所追求的。 stackoverflow.com/questions/16904639/…
标签: c# asp.net-mvc asp.net-mvc-5