Сеансовый cookie Не удается прочитать MachineKeySessionSecurityTokenHandler SessionSecurityToken в приложении ASP.NET MVC

В моей настройке проекта у меня нет провайдера идентификации, вместо этого я использую одно из значений cookie, установленных нашей внутренней системой для аутентификации, и преобразую эти значения в идентификатор утверждений.

После создания идентификатора утверждений я планирую записать идентификатор в файл cookie сеанса приложения, используя SessionAuthenticationModule и MachineKeySessionSecurityTokenHandler, как показано ниже.

                SessionSecurityToken token = new SessionSecurityToken(principal);
                        var handler = new MachineKeySessionSecurityTokenHandler(new TimeSpan(3, 30, 30));
                        var securityToken = handler.WriteToken(token);
                        SessionAuthenticationModule sam = new SessionAuthenticationModule();
                        sam.CookieHandler.RequireSsl = false; // This is required only for localhost to work
                        sam.CookieHandler.Write(securityToken, "Token", DateTime.Today.AddDays(1));

Однако при чтении настроек cookie я не могу разобрать их обратно в SessionSecurityToken или Claims Identity. Любая помощь в чтении этого файла cookie и преобразовании его в утверждения будет очень полезной.

Я использовал следующий фрагмент кода для чтения файла cookie, но я получаю сообщение об ошибке в методе handler.ReadToken, в котором говорится " ID4008:" SecurityTokenHandler "не обеспечивает реализацию" ReadToken "". сообщение об ошибке.

                //Check if the CGX session cookie is available
                SessionAuthenticationModule sam = new SessionAuthenticationModule();
                sam.CookieHandler.Name = "Token";
                sam.CookieHandler.RequireSsl = false;
                var securityToken = sam.CookieHandler.Read(filterContext?.HttpContext.ApplicationInstance.Context);

                if (securityToken != null)
                {
                    var handler = new MachineKeySessionSecurityTokenHandler(new TimeSpan(3, 30, 30));
                    var tokenString = Convert.ToBase64String(securityToken);
                    var token = handler.ReadToken(tokenString) as SessionSecurityToken;
                    if (token != null) sam.AuthenticateSessionSecurityToken(token, true);
                }

Какой будет правильный подход для чтения и проверки значения cookie, установленного в приложении. Как я уже говорил, приложение MVC отвечает за создание файла cookie и его проверку при последующих запросах.

1 ответ

Решение

Наконец, я нашел решение, позволяющее идентифицировать утверждения для моего сценария.

Это делается для настройки WIF 4.5 для смешивания вашей пользовательской аутентификации или аутентификации на основе форм, без необходимости настройки провайдеров идентификации (STS), RP-приложение вашего ASP.NET MVC установит аутентификацию и будет использовать ее при последующих запросах в сценарии WebFarm.

Хотелось бы добавить ответ, чтобы любой, кто нуждался в этом, мог использовать это. Прежде чем перейти к части кода, я добавлю конфигурации, которые имеют решающее значение для достижения ожидаемых результатов.

Добавьте следующие конфиги в web.config.

Это для настройки конфигураций, связанных с идентификацией, для использования,

<configSections>
<!--WIF 4.5 sections -->
<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>

Ниже приведены определения обработчиков маркеров безопасности и cookie-файлов,

<system.identityModel>
<identityConfiguration>
  <securityTokenHandlers>
    <remove type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <add type="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  </securityTokenHandlers>
</identityConfiguration>
</system.identityModel>

<system.identityModel.services>
<federationConfiguration>
  <cookieHandler name ="YourTokenName" mode="Default" requireSsl ="false">
    <chunkedCookieHandler chunkSize="3000"/>
  </cookieHandler>
</federationConfiguration>
</system.identityModel.services>

Добавьте следующие конфиги для настройки машинного ключа, поскольку я использую MachineKeySessionSecurityTokenHandler для сценария WebFarm, и включите SessionAuthenticationModule в раздел system.web, чтобы он работал на локальном хосте IIS Express VS2015 на момент написания этого ответа.

<system.web>
     <machineKey decryptionKey="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" validationKey="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" />
     <httpModules>
         <add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
     </httpModules>
</system.web>

Следующие конфиги для IIS 7.0 или выше для серверов веб-фермы,

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
       <add name="WSFederationAuthenticationModule" type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
       <add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
    </modules>
</system.webServer>

После того, как настройки настроены, теперь просто получить доступ к настройке Идентификация претензий, Принцип претензий, Аутентификация, Токен безопасности и Cookie. Следующее,

Если вы используете токен защиты от подделки для CORS в своем веб-приложении, вам нужно определить набор UniqueClaimTypeIdentifier, который сообщает генератору токенов защиты от подделки использовать часть уникального идентификатора шифрования ключа компьютера, иначе защита от подделки не будет работать с идентификацией утверждений.

В Global.asax

// Set Unique identifier for Antiforgery Token Generator
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;

Поместите приведенный ниже фрагмент в метод Login или любой путь к коду, где вы запускаете аутентификацию,

// Step 1: Setup Identity
var appClaims = new List<Claim>{
         new Claim(ClaimTypes.Name, "Your name claim"),
         new Claim("UserId", "User ID claim"),
         new Claim(ClaimTypes.NameIdentifier, "Name Identifier Claim Must"),
  }
ClaimsIdentity identity = new ClaimsIdentity(appClaims,"Name Of Identity");
// Step 2: Setup Principal
ClaimsPrincipal principal = new ClaimsPrincipal(claimsIdentity);

//Step 3: The below code path sets the claims principal, using SessionAuthenticationModule, authenticates the principal and sets to httpcontext and current thread, sets the cookie in browser.
var authedCp = FederatedAuthentication.FederationConfiguration.IdentityConfiguration.ClaimsAuthenticationManager.Authenticate("Name", principal);
var token = FederatedAuthentication.SessionAuthenticationModule.CreateSessionSecurityToken(authedCp, "Issuer Name", DateTime.UtcNow, DateTime.UtcNow.AddHours(1), false);
// This is only for debug mode in localhost, to make cookie written for local http or for https set it true
FederatedAuthentication.SessionAuthenticationModule.CookieHandler.RequireSsl = false;    
FederatedAuthentication.SessionAuthenticationModule.AuthenticateSessionSecurityToken(token, true);

Поместите этот фрагмент, где вам необходимо проверить, содержит ли cookie сведения о претензиях, и повторно выполнить аутентификацию при последующих запросах (возможно, фильтр действий),

//Check if the session cookie is available
SessionAuthenticationModule sam = FederatedAuthentication.SessionAuthenticationModule;
sam.CookieHandler.Name = "Token Name";
sam.CookieHandler.RequireSsl = false; //for local host, https make it true
var securityToken = sam.CookieHandler.Read(filterContext?.HttpContext.ApplicationInstance.Context);

if (securityToken != null)
{
    SessionSecurityToken sessionToken = null;
    var readStatus = sam.TryReadSessionTokenFromCookie(out sessionToken);
    if (sessionToken != null)
    {
        sam.AuthenticateSessionSecurityToken(sessionToken, true);
    }
}

Теперь у вас есть настройки Claims Principal и Claims Identity в HttpContext и Thread из файла cookie, сохраненного при последующих запросах. Вы можете получить к нему доступ в любое время в конвейере запросов, следите за размером файлов cookie, когда добавляете больше утверждений в Identity.

Я хотел бы поблагодарить Сандера за его пост в блоге https://itq.nl/mixing-forms-authentication-with-claims-based-authorisation-in-asp-net/ который помог мне настроить более поздние части доступа к токенам.

Другие вопросы по тегам