Reputation: 71
I have a small test scenario (an authorization service hosting IdentityServer3, a Web API, and a console client) where the Controllers "Identity" is a ClaimsIdentity when the API is called from the console client (as expected), but the Identity is a WindowsIdentity when the API is called from Fiddler. The scenario exclusively uses reference tokens so all API token validation makes a call from the WebAPI to the authorization service to validate the reference token provided on the Web API header. The Web API is being hosted in IIS Express for the time being.
The Web API's Owin Startup.cs looks like the following
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
app.UseIdentityServerBearerTokenAuthentication( new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "https://localhost:5005/",
ValidationMode = ValidationMode.ValidationEndpoint,
} );
app.UseWebApi( config );
The console Client (which correctly ends up with a ClaimsIdentity in the WebAPI Controller) calls the API using the following HttpClient code:
var client = new HttpClient();
client.SetBearerToken( accessToken );
var result = client.GetStringAsync( "http://localhost:5000/Account" ).Result;
return result;
The "raw" Fiddler statement (which incorrectly (in my opinion) results in a WindowsIdentity) is as follows:
GET http://localhost:5000/account/ HTTP/1.1
User-Agent: Fiddler
Host: localhost:5000
Accept: application/json
Connection: Keep-Alive
Authorization: Bearer <reference token>
Content-Length: 0
I've verified that the Headers and other "request" parameters (message handler collections, etc.) are the same between the two scenarios. I have tried
config.SuppressHostPrincipal()
but this "breaks" the Console client behavior (results in an "empty" ClientIdentity). I also tried
JwtSecurityTokenHandler.InboundClaimTypeMap.Clear();
with no success. I've gone through the Web.config and Web API .csproj files several times but have not been able to find anything there that explains the WindowsIdentity behavior I am seeing.
My suspicion is that there is additional Web API Authentication middle-ware that is circumventing the UseIdentityServerBearerTokenAuthentication middle-ware from executing when the request is made from Fiddler but I have not been able to track this down.
I originally wrote this off as an environment issue with Fiddler but now that I am attempting to integrate the UseIdentityServerBearerTokenAuthentication mechanism into our production code base I am getting the WindowsIdentity behavior in our production Web APIs regardless of the client (Fiddler or raw HttpClient via console application). Any ideas would be greatly appreciated. Thanks!
Upvotes: 0
Views: 1514
Reputation: 71
I discovered the following error in my Output window:
Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationMiddleware Error: 0 : Authentication failed
System.IO.FileLoadException: Could not load file or assembly 'IdentityModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. A strongly-named assembly is required. (Exception from HRESULT: 0x80131044)
File name: 'IdentityModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
at IdentityServer3.AccessTokenValidation.ValidationEndpointTokenProvider.<ReceiveAsync>d__1.MoveNext()
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[TStateMachine](TStateMachine& stateMachine)
at IdentityServer3.AccessTokenValidation.ValidationEndpointTokenProvider.ReceiveAsync(AuthenticationTokenReceiveContext context)
at Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationHandler.<AuthenticateCoreAsync>d__0.MoveNext()
Our product is signed so I had previously signed both the IdentityServer3 and IdentityModel assemblies which meant the IdentityServer3 reference to IdentityModel with PublicKeyToken=null failed. After digging into the IL of IdentityServer3 and changing the reference to expect the appropriate key everything worked perfectly.
Upvotes: 0