Thinktecture IdentityModel AuthenticationConfiguration Mapping для Cookie — как?

У меня есть приложение на основе веб-API, которое в настоящее время настроено с использованием потрясающей Thinktecture IdentityModel 4.5.

Он настроен для проверки подлинности на основе утверждений, принимая базовые учетные данные проверки подлинности, отправленные в заголовке авторизации. Клиент javascript сохраняет возвращенный маркер сеанса и использует его для последующих запросов, включая его в заголовок авторизации, которому предшествует Session, в качестве схемы.

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

Все это прекрасно работает.

Проблема в том, что у меня есть ссылка на странице приложения, которая указывает на прямой адрес (/api/controller/id/pdfdocument) и открывает его в новом окне (цель: _blank). Поэтому нет возможности включить заголовок Authorization в этот запрос. Однако файл cookie передается правильно, поскольку сеанс все еще активен.

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

Мой код:

    private static AuthenticationConfiguration CreateAuthenticationConfiguration()
    {
        var sessionTokenConfiguration = new SessionTokenConfiguration();
        sessionTokenConfiguration.EndpointAddress = "/Authenticate";
        sessionTokenConfiguration.DefaultTokenLifetime = new TimeSpan(1, 0, 0);

        var authenticationConfig = new AuthenticationConfiguration
        {
            ClaimsAuthenticationManager = _authenticationManager,
            RequireSsl = false,
            EnableSessionToken = true,
            SessionToken = sessionTokenConfiguration,
            SendWwwAuthenticateResponseHeaders = false
        };

        var securityTokenHandler = new Thinktecture.IdentityModel.Tokens.Http.BasicAuthenticationWithRoleSecurityTokenHandler(_userService.ValidateUser, _userService.GetRolesForUser);
        securityTokenHandler.RetainPassword = false;
        var realm = "localhost";

        var authorizationMapping = new AuthenticationOptionMapping
        {
            Options = AuthenticationOptions.ForAuthorizationHeader(scheme: "Basic"),
            TokenHandler = new System.IdentityModel.Tokens.SecurityTokenHandlerCollection { securityTokenHandler },
            Scheme = AuthenticationScheme.SchemeAndRealm("Basic", realm)
        };
        authenticationConfig.AddMapping(authorizationMapping);

        var cookieMapping = new AuthenticationOptionMapping
        {
            Options = AuthenticationOptions.ForCookie("sessionToken"),
            TokenHandler = new System.IdentityModel.Tokens.SecurityTokenHandlerCollection { securityTokenHandler },
            Scheme = AuthenticationScheme.SchemeOnly(scheme: "Session")
        };
        authenticationConfig.AddMapping(cookieMapping);

        //authenticationConfig.AddBasicAuthentication(_userService.ValidateUser, _userService.GetRolesForUser);

        return authenticationConfig;
    }

Затем эта конфигурация применяется следующим образом:

HttpConfiguration config;
var authenticationConfig = CreateAuthenticationConfiguration();
config.MessageHandlers.Add(new AuthenticationHandler(authenticationConfig));

А вот так выглядит cookie в заголовке запроса:

Cookie: sessionToken=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjEzNzM2NDA5NjgsImlzcyI6InNlc3Npb24gaXNzdWVyIiwiYXVkIjoiaHR0cDovL3Nlc3Npb24udHQvIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZSI6ImEiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL2F1dGhlbnRpY2F0aW9ubWV0aG9kIjoiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2F1dGhlbnRpY2F0aW9ubWV0aG9kL3Bhc3N3b3JkIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9hdXRoZW50aWNhdGlvbmluc3RhbnQiOiIyMDEzLTA3LTEyVDEzOjU2OjA4LjA5N1oiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbmlzdHJhdG9yIiwiSWQiOiIyIn0.UlPeD9HzduQfwHE7NuXi9eMVo40hypi_LBK-f76VYFI; username=a

Любая помощь наиболее ценится!


person Ibraheem    schedule 12.07.2013    source источник
comment
Ибрагим, если вы читаете этот комментарий, я думаю, вы можете помочь мне с этим вопросом stackoverflow.com/questions/27731539   -  person Peter Wone    schedule 01.01.2015


Ответы (1)


Поэтому, подождав несколько минут, не получив ответов и отчаянно нуждаясь в этой функции, я погрузился в исходный код Thinktecture IdentityModel 4.5, чтобы посмотреть, что происходит, и, похоже, эта функция на самом деле не поддерживается. Он не только не поддерживается, но, судя по всему, сопоставление файлов cookie на самом деле не реализовано.

Я разветвил репозиторий и внес несколько небольших изменений, чтобы включить эту функцию: /ibraheemhlayil/Thinktecture.IdentityModel.45

и отправил Доминику Байеру из Thinktecture это в запросе на включение: https://github.com/thinktecture/Thinktecture.IdentityModel.45/pull/95

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

Если вы хотите использовать эту функцию, вы просто устанавливаете новое свойство CookieName для объекта SessionTokenConfiguration. IdentityModel использует свойство HeaderName, чтобы определить, в каком заголовке искать данные проверки подлинности. Точно так же, если установлено свойство CookieName, это определяет, какое имя файла cookie ищется для данных аутентификации, если данные аутентификации не были найдены в заголовке.

В приведенном ниже примере данные аутентификации ищутся в файле cookie с именем sessionToken, если данные аутентификации не найдены в заголовке Authorization.

    private static AuthenticationConfiguration CreateAuthenticationConfiguration()
    {

        var authenticationConfig = new AuthenticationConfiguration
        {
            ClaimsAuthenticationManager = _authenticationManager,
            RequireSsl = false,
            SendWwwAuthenticateResponseHeaders = false,
            EnableSessionToken = true,
            SessionToken = new SessionTokenConfiguration
            {
                EndpointAddress = "/Authenticate",
                DefaultTokenLifetime = new TimeSpan(1, 0, 0),
                HeaderName = "Authorization",
                CookieName = "sessionToken",
                SigningKey = CryptoRandom.CreateRandomKey(32)
            }
        };

        authenticationConfig.AddBasicAuthentication(_userService.ValidateUser, _userService.GetRolesForUser);

        return authenticationConfig;
    }

Как и прежде, эта конфигурация применяется во время запуска вашего приложения:

HttpConfiguration config;
var authenticationConfig = CreateAuthenticationConfiguration();
config.MessageHandlers.Add(new AuthenticationHandler(authenticationConfig));

Данные аутентификации cookie имеют ту же форму, что и данные, отправленные в заголовке Authorization, поэтому, если они отправлены, cookie должен выглядеть так:

Cookie: sessionToken=Session eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjEzNzM2NDA5NjgsImlzcyI6InNlc3Npb24gaXNzdWVyIiwiYXVkIjoiaHR0cDovL3Nlc3Npb24udHQvIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZSI6ImEiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL2F1dGhlbnRpY2F0aW9ubWV0aG9kIjoiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2F1dGhlbnRpY2F0aW9ubWV0aG9kL3Bhc3N3b3JkIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9hdXRoZW50aWNhdGlvbmluc3RhbnQiOiIyMDEzLTA3LTEyVDEzOjU2OjA4LjA5N1oiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbmlzdHJhdG9yIiwiSWQiOiIyIn0.UlPeD9HzduQfwHE7NuXi9eMVo40hypi_LBK-f76VYFI

Надеюсь, кто-то найдет это полезным!

person Ibraheem    schedule 02.08.2013