'Include custom WWW-Authenticate header in 401 Unauthorised response when using Microsoft.Identity.Web
Following instructions on making MS Office connect to my Asp.NET Core Web API, I am attempting to present a login redirect to MS Office for failed authentications. Following questions and answers I am attempting to include the login redirect information in the WWW-Authenticate
header property. My Web API is protected with Azure AD and the Microsoft.Identity.Web
library. When the authentication fails and the middleware returns the 401 Unauthorized response, the header does include the WWW-Authenticate
property but it's value is only Bearer
.
Q: How can update the header information to include the necessary additional redirect information?
I have tried to implement an attribute on the API, derived from IAsyncAuthorizationFilter
and access the response header in that. However the middleware already returns a 401 before this attribute is called.
Solution 1:[1]
I have made progress by customizing the JwtBearerOptions
configuration. However this approach creates an additional header item, instead of overwriting the standard value. As a result I have now 2 KeyValuePairs for the same key in the response header, which will likely have unexpected outcomes.
In my Startup.cs:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration)
services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
var existingOnChallengeHandler = options.Events.OnChallenge;
options.Events.OnChallenge = async context =>
{
await existingOnChallengeHandler(context);
string headerInfo = context.Options.Challenge;
headerInfo += " resource=\"https://management.azure.com/\"";
context.Response.Headers.Append(HeaderNames.WWWAuthenticate, headerInfo);
};
});
Solution 2:[2]
The original answer put me on the right track. It turned out to be actually quite simple to do this once I knew to configure the JwtBearerOptions.Challenge
property:
services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.Challenge = $"Bearer authorization_uri=\"{authorizationUri}\"";
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Lars Kemmann |