В настоящее время я использую активный каталог Windows Azure в качестве единого входа в мое приложение MVC.NET, и эта часть отлично работает. Я могу пройти аутентификацию в WAAD и без проблем загрузить свой ClaimsPrinicipal.
Следующим шагом было преобразование заявок, полученных из WAAD, путем добавления новых заявок из другого источника данных. Для этого я создал класс, наследующий ClaimsAuthenticationManager (ниже). Утверждения добавляются к субъекту и сохраняются в файле cookie сеанса в методе CreateSession.
Моя проблема сейчас заключается в том, что ClaimsPrincipal.Current не содержит никаких дополнительных утверждений, которые я добавил. Когда я устанавливаю точку останова в событии SessionAuthenticationModule_SessionSecurityTokenReceived, я вижу, что существует несоответствие между ClaimsPrincipal.Current
ClaimsPrincipal.Current.FindAll(ClaimTypes.Email)
Count = 0
и e.SessionToken.ClaimsPrincipal.
e.SessionToken.ClaimsPrincipal.FindAll(ClaimTypes.Email)
Count = 1
[0]: {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress: [email protected]}
Что мне здесь не хватает? Во всех образцах, связанных с преобразованием утверждений, которые мне удалось найти, нет упоминания о ручной перезагрузке ClaimsPrinicipal из файла cookie. Будет ли событие маркера безопасности сеанса подходящим местом для перезагрузки ClaimsPrincipal, или я нарушаю модель безопасности?
Спасибо.
public class MyAuthenticationManager : ClaimsAuthenticationManager
{
public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
{
if (!incomingPrincipal.Identity.IsAuthenticated)
{
return base.Authenticate(resourceName, incomingPrincipal);
}
var transformedPrincipal = this.CreateUserPrincipal(incomingPrincipal.Identity.Name);
this.CreateSession(transformedPrincipal);
return transformedPrincipal;
}
private ClaimsPrincipal CreateUserPrincipal(String userName)
{
List<Claim> claims = new List<Claim>();
var user = SecurityController.GetUserIdentity(userName);
claims.Add(new Claim(ClaimTypes.Name, userName));
claims.Add(new Claim(ClaimTypes.Email, user.Email));
claims.Add(new Claim(ClaimTypes.GivenName, user.FirstName));
claims.Add(new Claim(ClaimTypes.Surname, user.LastName));
return new ClaimsPrincipal(new ClaimsIdentity(claims, "MyCustom"));
}
private void CreateSession(ClaimsPrincipal transformedPrincipal)
{
var sessionSecurityToken = new SessionSecurityToken(transformedPrincipal, TimeSpan.FromHours(8));
if (FederatedAuthentication.SessionAuthenticationModule != null &&
FederatedAuthentication.SessionAuthenticationModule.ContainsSessionTokenCookie(HttpContext.Current.Request.Cookies))
{
return;
}
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionSecurityToken);
//Added line below as per suggestion in one of the posts
//Doesn't seem to have any effect
Thread.CurrentPrincipal = transformedPrincipal;
FederatedAuthentication.SessionAuthenticationModule.SessionSecurityTokenReceived += SessionAuthenticationModule_SessionSecurityTokenReceived;
}
void SessionAuthenticationModule_SessionSecurityTokenReceived(object sender, SessionSecurityTokenReceivedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("SessionAuthenticationModule_SessionSecurityTokenReceived");
}