问题
I have set up my Resource Server (Web Api 2) to validate JWT token for incoming requests. The JWT token is issued by Auth0 and my client pass it to my web api. This all works fine and raises 401 response if Issuer, Audience or Expiry date is not valid. When I add my custom middleware derived from OwinMiddleware it suppresses token validation logic and I get 200 response for invalid requests.
public class Startup
{
public void Configuration(IAppBuilder app)
{
var issuer = "my issuer";
var audience= "my audience";
var clientId= "my client id";
app.UseActiveDirectoryFederationServicesBearerAuthentication(
new ActiveDirectoryFederationServicesBearerAuthenticationOptions
{
TokenValidationParameters = new TokenValidationParameters
{
ValidAudience = audience,
ValidIssuer = issuer,
IssuerSigningKeyResolver = (token, securityToken, identifier, parameters) => parameters.IssuerSigningTokens.FirstOrDefault()?.SecurityKeys?.FirstOrDefault()
},
// Setting the MetadataEndpoint so the middleware can download the RS256 certificate
MetadataEndpoint = $"{issuer.TrimEnd('/')}/wsfed/{clientId}/FederationMetadata/2007-06/FederationMetadata.xml"
});
HttpConfiguration config = new HttpConfiguration();
app.Use<HttpUsernameInjector>();
// Web API routes
config.MapHttpAttributeRoutes();
app.UseWebApi(config);
}
}
and my custom OwinMiddleWare:
public class HttpUsernameInjector : OwinMiddleware
{
public HttpUsernameInjector(OwinMiddleware next)
: base(next)
{
}
public override async Task Invoke(IOwinContext context)
{
const string usernameClaimKey = "my username claim key";
var bearerString = context.Request.Headers["Authorization"];
if (bearerString != null && bearerString.StartsWith("Bearer ", StringComparison.InvariantCultureIgnoreCase))
{
var tokenString = bearerString.Substring(7);
var token = new JwtSecurityToken(tokenString);
var claims = token.Claims.ToList();
var username = claims.FirstOrDefault(x => x.Type == usernameClaimKey);
if (username == null) throw new Exception("Token should have username");
// Add to HttpContext
var genericPrincipal = new GenericPrincipal(new GenericIdentity(username.Value), new string[] { });
IPrincipal principal = genericPrincipal;
context.Request.User = principal;
}
await Next.Invoke(context);
}
}
How should I configure my custom middleware to avoid conflict/suppressing OWIN token authentication logic?
回答1:
Nothing's wrong with OWINMiddleware but assigning context.Request.User
causes problem. GenericIdentity
created here has a Readonly IsAuthenticated
equal to true and not possible to set to false
. When assigning context.Request.User = genericPrincipal;
it overrides IsAuthenticated
inside context.Request.User
with IsAuthenticated
from genericPrincipal
. Need to check for Authentication result at the beginning of Invoke method and skip the logic if user is not authenticated. So it wouldn't change IsAuthenticated
in context.Request.User
.
public override async Task Invoke(IOwinContext context)
{
if (context.Authentication.User.Identity.IsAuthenticated)
{
//my username injection logic
}
await Next.Invoke(context);
}
来源:https://stackoverflow.com/questions/45473348/owinmiddleware-implementation-in-resource-server-suppresses-token-validation