I have an app that has an existing implementation of OAuth (sort of). We are migrating to using Identity Server for OAuth and I now need to support both authentication schemes on some Controllers/Actions.
The bearer tokens for each Auth method are clearly different. One is a guid and the other is a proper token generated by Identity Server.
All I need is some way to look at the token and say anything with string length <= 36 should be old method. Anything more use Identity Server.
The root Controller has a basic [Authorize] attribute. Also if I switch the order of the scheme's the first one listed works.
Here is my Startup.cs code
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = Constants.CompanyBearerScheme;
options.DefaultChallengeScheme = Constants.CompanyBearerScheme;
}).AddJwtBearer(options =>
{
options.Authority = "https://identityserverurl";
options.Audience = "APISCOPE";
options.RequireHttpsMetadata = true;
}).AddBearerToken(Constants.CompanyBearerScheme, o =>
{
o.ConnectionString = bearerTokenHandlerOptions.ConnectionString;
o.DefaultScopes = bearerTokenHandlerOptions.DefaultScopes;
})
Sample Action
[Authorize(AuthenticationSchemes = "CompanyBearer,Bearer")]
[HttpGet("TEST")]
public async Task<IActionResult> TestAuthentication()
{
return Ok();
}
Sample Request
GET {{Url}}/Api/TEST
Authorization: Bearer SOMETOKEN
I figured it out.
Needed to use a custom policy scheme to compare incoming request.
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = Constants.DefaultSelectorPolicy;
options.DefaultChallengeScheme = Constants.DefaultSelectorPolicy;
})
.AddPolicyScheme(Constants.DefaultSelectorPolicy, Constants.DefaultSelectorPolicy, options =>
{
options.ForwardDefaultSelector = ctx =>
{
if (!ctx.Request.Headers.ContainsKey("Authorization"))
{
return null;
}
var authorizationHeader = ctx.Request.Headers["Authorization"];
var authorization = AuthenticationHeaderValue.Parse(authorizationHeader);
if (authorization.Scheme.ToLower() != "bearer")
{
return null;
}
if (authorization.Parameter.Length > 36)
{
return "Bearer";
}
return Constants.CompanyBearerScheme;
};
})