I have an IdentityServer4 app based on the IS4 Identity sample, and an API using bearer tokens for it's Authorization via IS4.AccessTokenValidation. This is working fine on localhost via VisualStudio, and when I deploy to a Windows 2012 VM and hosted via IIS. When I deploy the Identity server to Azure as an App Service website, all is fine too. However when the API is deployed as an App Service using same domain and certificate as the VM, any method with an Authorize attribute (with a policy or none it doesn't matter) always returns a 401 with the header message:
Www-Authenticate: Bearer error="invalid_token", error_description="The signature key was not found"
We're using .NET 4.5.2, with the latest releases of IdentityServer4, and IdentityServer4.AccessTokenValidation packages. I've also pulled the latest of these packages from GitHub from 30/08/16 with no change. I don't think it's a bug is IS4 Validator anyway, but I don't know what might cause this. Any suggestions? Is it an Azure host bug?
I'd love to be able to debug this, but I can't get Remote Debug working to this app even when I rebuilt from scratch, and app logs tell me nothing. I've had a rummage in the ASP.NET Security repo, but without more logging or debug access, I'm pretty clueless how to fix this problem.
API Configure is very basic:
var jwtBearerOptions = new JwtBearerOptions()
{
Authority = Configuration["Authentication:IdentityServer:Server"],
Audience = Configuration["Authentication:IdentityServer:Server"]+"/resources",
RequireHttpsMetadata = false,
AutomaticAuthenticate = true,
AutomaticChallenge = true,
};
app.UseJwtBearerAuthentication(jwtBearerOptions);
and the Identity Server is straight out of the samples, and using a purchased certificate for signing.
Has anyone else got this configuration fully working as 2 Azure App Services? Or what might possibly cause this error given the same bearer token sent to the VM hosted API is acceptable.
It turned out you need to explicitly set the IssuerSigningKey
in TokenValidationParameters
. So I get the certificate from the App Service store, and add it via JwtBearerOptions.TokenValidationParameters
. So Startup config looks like this:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap = new Dictionary<string, string>();
var tokenValidationParameters = new TokenValidationParameters
{
// The signing key must match!
ValidateIssuerSigningKey = true,
IssuerSigningKey = new X509SecurityKey(GetSigningCertificate()),
// Validate the JWT Issuer (iss) claim
ValidateIssuer = false,
//ValidIssuer = "local",
// Validate the JWT Audience (aud) claim
ValidateAudience = false,
//ValidAudience = "ExampleAudience",
// Validate the token expiry
ValidateLifetime = true,
// If you want to allow a certain amount of clock drift, set that here:
ClockSkew = TimeSpan.Zero
};
var jwtBearerOptions = new JwtBearerOptions()
{
Authority = Configuration["Authentication:IdentityServer:Server"],
Audience = Configuration["Authentication:IdentityServer:Server"]+"/resources",
RequireHttpsMetadata = false,
AutomaticAuthenticate = true,
AutomaticChallenge = true,
TokenValidationParameters = tokenValidationParameters
};
app.UseJwtBearerAuthentication(jwtBearerOptions);
app.UseMvc();
...
}
No idea why this is only needed on the Azure App Service and not on a server or development machine. Can anyone else explain it? It would suggest ValidateIssuerSigningKey default to true for App Service and false anywhere else.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With