I have a Web API based application currently set up using the amazing Thinktecture IdentityModel 4.5.
It is set up for claims-based authentication, accepting a Basic auth credential sent in on the Authorization header. The javascript client saves the returned session token and uses this for subsequent requests by including it in the Authorization header preceded by Session as the scheme.
The javascript client also saves the token to a cookie, for retrieval if the window is closed and reopened quickly, or when new windows are opened to prevent the user having to re-authenticate. The cookie is named sessionToken and it's value is the actual token.
It all works wonderfully well.
The problem is I have a link on the app page that links to a direct address (/api/controller/id/pdfdocument) and opens it in a new window (target: _blank). Therefore there is no way to include the Authorization header in this request. However, the cookie is transferred over correctly as the session is still active.
I have tried to add a mapping to the AuthenticationConfig.Mappings collection to add support for collecting the token from the cookie, however I just can't get the configuration right to get this working, and havn't been able to find any other resources online. I'm assuming there's something very simple that needs to get fixed.
My code:
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;
}
This configuration is then applied like so:
HttpConfiguration config;
var authenticationConfig = CreateAuthenticationConfiguration();
config.MessageHandlers.Add(new AuthenticationHandler(authenticationConfig));
And this is what the cookie looks like in the request header:
Cookie: sessionToken=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjEzNzM2NDA5NjgsImlzcyI6InNlc3Npb24gaXNzdWVyIiwiYXVkIjoiaHR0cDovL3Nlc3Npb24udHQvIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZSI6ImEiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL2F1dGhlbnRpY2F0aW9ubWV0aG9kIjoiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2F1dGhlbnRpY2F0aW9ubWV0aG9kL3Bhc3N3b3JkIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9hdXRoZW50aWNhdGlvbmluc3RhbnQiOiIyMDEzLTA3LTEyVDEzOjU2OjA4LjA5N1oiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbmlzdHJhdG9yIiwiSWQiOiIyIn0.UlPeD9HzduQfwHE7NuXi9eMVo40hypi_LBK-f76VYFI; username=a
Any help most appreciated!