asp.net-web-api - Thinktecture IdentityModel AuthenticationConfiguration Mapping for Cookie - 如何?

标签 asp.net-web-api thinktecture-ident-model

我有一个基于 Web API 的应用程序,目前使用令人惊叹的 Thinktecture IdentityModel 4.5 设置。

它是为基于声明的身份验证而设置的,接受在授权 header 上发送的基本身份验证凭据。 javascript 客户端保存返回的 session token 并将其用于后续请求,方法是将其包含在以 Session 作为方案的授权 header 中。

javascript 客户端还将 token 保存到 cookie 中,以便在窗口关闭并快速重新打开时进行检索,或者在新窗口打开时进行检索,以防止用户不得不重新进行身份验证。 cookie 名为 sessionToken,其值是实际 token 。

一切都非常好。

问题是我在应用程序页面上有一个链接,链接到一个直接地址 (/api/controller/id/pdfdocument) 并在新窗口中打开它 (target: _blank)。因此,无法在此请求中包含 Authorization header 。但是,由于 session 仍处于事件状态,cookie 已正确传输。

我已尝试将映射添加到 AuthenticationConfig.Mappings 集合以添加对从 cookie 中收集 token 的支持,但是我只是无法正确配置以使其正常工作,并且无法找到任何其他在线资源。我假设有一些非常简单的问题需要修复。

我的代码:

    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 在请求 header 中的样子:

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

非常感谢任何帮助!

最佳答案

因此,在等待几分钟但没有收到回复并且迫切需要此功能后,我深入研究了 Thinktecture IdentityModel 4.5 源代码以查看发生了什么,但似乎实际上不支持此功能。它不仅不受支持,而且从表面上看,cookie 映射实际上并未实现。

我 fork 了存储库并做了一些小改动以允许此功能: https://github.com/ibraheemhlaiyil/Thinktecture.IdentityModel.45

并在拉取请求中向 Thinktecture 的 Dominick Baier 发送了这个: https://github.com/thinktecture/Thinktecture.IdentityModel.45/pull/95

Cookie 的使用有它的缺点,似乎 Thinktecture 正试图尽可能地远离它们,但是我想不出一个不同的解决方案来解决我的问题 - 一个需要打开一个新的 javascript 客户端 Web 应用程序窗口/选项卡并在新窗口/选项卡中维护经过身份验证的 session 。

如果您想使用此功能,只需在 SessionTokenConfiguration 对象上设置新的 CookieName 属性即可。 IdentityModel 使用 HeaderName 属性来确定要在哪个 header 中查找身份验证数据。以同样的方式,如果设置了 CookieName 属性,则如果在 header 中未找到身份验证数据,这将确定查找哪个 cookie 名称以获取身份验证数据。

在下面的示例中,如果在 Authorization header 上找不到身份验证数据,则会在名为 sessionToken 的 cookie 上查找身份验证数据。

    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 身份验证数据与授权 header 中发送的数据具有完全相同的格式,因此如果发送,cookie 应该如下所示:

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

希望有人发现这个有用!

关于asp.net-web-api - Thinktecture IdentityModel AuthenticationConfiguration Mapping for Cookie - 如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17616979/

相关文章:

c# - WebApi 2.0 中的 MEF 未解析

c# - 使用 Url.Link 在 Web API 中生成 HTTPS 链接

javascript - HttpDelete 和参数

asp.net-mvc - 需要使用 Web 应用程序和 Web API 进行双重身份验证吗?

asp.net-web-api - 成员(member)重新启动用 Simple Injector 替换 Ninject

c# - dotnet core IdentityModel 不会自省(introspection) token

.net - ASP.NET Identity 和 Thinktecture.IdentityModel 库如何相互关联?

asp.net-web-api - 从 Web API 2 基于声明的身份验证迁移到 ThinkTecture

angularjs - 使用Thinktecture的AngularJs ASP.NET Web Api身份验证