Sea*_*een 7 c# asp.net authentication claims-based-identity asp.net-mvc-4
我正在尝试使用基于声明的身份验证重新登录系统.
单步执行,它似乎正确评估用户名和密码并正确创建声明主体(包括添加身份验证类型,以便根据此SO问题将IsAuthenticated设置为true .)
不知何故,身份似乎没有正确设置在线上.结果,我被直接重定向回登录页面.
我有以下内容global.asax:
private void Application_PostAuthenticateRequest(object sender, EventArgs e)
{
var currentPrincipal = ClaimsPrincipal.Current;
var transformer = new ClaimsTransformer(); //My own custom transformer; code below.
var newPrincipal = transformer.Authenticate(string.Empty, currentPrincipal); // does the transformation
// as I understand, it is proper & recommnded to set both of these
Thread.CurrentPrincipal = newPrincipal;
HttpContext.Current.User = newPrincipal;
}
Run Code Online (Sandbox Code Playgroud)
在我的登录控制器中,我对会员数据库进行了简单的测试.我在调试时验证了这newCP是一个有效的,经过身份验证的身份,具有预期的名称.
[HttpPost]
[AllowAnonymous]
public ActionResult UserLogin(LoginViewModel viewModel)
{
var loginSuccess = Membership.ValidateUser(viewModel.UserName, viewModel.Password);
if (loginSuccess)
{
// CustomApplicationIdentity puts some identity-based logic into business domain terms and uses Claims underneath.
//Should have done it at the IPrincipal level, but instead I created the ToAuthenticatedStandardClaimsIdentity() which returns a new authenticated ClaimsIdentity.
var newIdentity = new CustomApplicationIdentity(viewModel.UserName);
var cp = new ClaimsPrincipal(newIdentity.ToAuthenticatedStandardClaimsIdentity());
var newCP = new ClaimsTransformer().Authenticate(string.Empty, cp);
System.Web.HttpContext.Current.User = newCP;
Thread.CurrentPrincipal = newCP;
if (!string.IsNullOrWhiteSpace(viewModel.ReturnUrl))
{
return Redirect(viewModel.ReturnUrl);
}
return RedirectToAction("Index", "Identity");
}
}
Run Code Online (Sandbox Code Playgroud)
当它重定向到Action时,我看到它Application_PostAuthenticateRequest再次击中,这非常有意义.
但是,尽管先前设置了主体,但现在看起来这是一个空主体(没有名称,IsAuthenticated设置为false).
一些想法:
经过大量研究(并通过Dominick Baier的优秀Pluralsight课程),解决方案如下:
一步一步(再次,大部分内容归功于Dominick的视频):
System.IdentityModel.Services(下面的完整大纲,在web.config中插入该大纲中的两个部分):
<configuration>
<configSections>
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
</configSections>
</configuration>
Run Code Online (Sandbox Code Playgroud)
(这取决于配置设置)
在system.webServerweb.config 的部分中,添加以下行:
<remove name="RoleManager"/> <!--Not needed anymore in my case -->
<add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
Run Code Online (Sandbox Code Playgroud)
(不再需要因为SAM,它会检测到cookie;为什么在每次请求时运行它,如果你不需要,对吧?)
在ClaimsAuthenticationManager中添加这些行(我的名为ClaimsTransformer).我把它放在一个名为"EstablishSession"的单独方法中,它在已经转换后接收了我的主体:
private void EstablishSession(ClaimsPrincipal transformedPrincipal)
{
var sessionToken = new SessionSecurityToken(transformedPrincipal, TimeSpan.FromHours(8));
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken);
}
Run Code Online (Sandbox Code Playgroud)
因此,现在每当您转换声明时都会设置Cookie,这是有道理的,因为如果用户成功通过身份验证,您只会转换声明.
...想知道为什么SessionAuthenticationManager总是为空.
说真的,一切似乎都有效,而且你的配置是正确的,但如果它不是每个都是空的,那就是它.单.时间.
啊,看起来Cassini(VS Debugger中的内置版)不能与SessionAuthenticationManager一起使用.
但是,IIS Express可以.将其切换到项目设置中的那个.
现在我有一个有效的页面.
| 归档时间: |
|
| 查看次数: |
6373 次 |
| 最近记录: |