I have tried to use the windows authentication and JWT together with .NET Core 2.1.
I have following startup settings of the authentication:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IISDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "Test",
ValidAudience = "Test",
IssuerSigningKey = JwtSecurityKey.Create("677efa87-aa4d-42d6-adc8-9f866e5f75f7")
};
options.Events = new JwtBearerEvents()
{
OnAuthenticationFailed = OnAuthenticationFailed
};
});
IIS settings:
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": true,
..
}
I have tried following code snippet to create the JWT token with windows authentication:
[Route("api/[controller]")]
[ApiController]
[Authorize(AuthenticationSchemes = "Windows")]
public class AuthController : ControllerBase
{
[HttpPost("token")]
public IActionResult Token()
{
//Setup claims
var claims = new[]
{
new Claim(ClaimTypes.Name, User.Identity.Name),
//Add additional claims
};
//Read signing symmetric key
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("677efa87-aa4d-42d6-adc8-9f866e5f75f7"));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
//Create a token
var token = new JwtSecurityToken(
issuer: "Test",
audience: "Test",
claims: claims,
expires: DateTime.Now.AddMinutes(30),
signingCredentials: creds);
//Return signed JWT token
return Ok(new
{
token = new JwtSecurityTokenHandler().WriteToken(token)
});
}
}
And in another controller I need use only JWT authentication:
[Route("api/[controller]")]
[ApiController]
[Authorize(AuthenticationSchemes = "Bearer")]
public class ProductController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
var userName = User.Identity.Name;
var claims = User.Claims.Select(x => new { x.Type, x.Value });
return Ok(new { userName, claims });
}
}
If the JWT token is expired then I correctly received the response code 401
but I still get the dialog in the browser for putting the credentials.
How can I configure the windows authentication only for a part when I want to create the JWT token and disable response which is responsible for showing the browser dialog with credentials? How to correctly combine these things?
The way I would handle this is to create two different web applications: one for Windows Authentication and one that uses JWT Token Authentication.
The Windows Authentication web application would be very small and only does one thing. Authenticate the user via Windows Authentication at an endpoint and return a JWT Token.
Then, that token can be used for the main application. As long as your signing key and audience is the same, it doesn't matter if the token is created on a different web application.
You won't need to struggle with trying to handle both at the same time.
To work with both windows and JWT bearer authentication-- windows authentication by default get applied to all pages and it over ride the functionality of JWT Bearer. For combining both into one single application :-
So, In above case we are using windows authentication for generating JWT Token and using that JWT Token we are authenticating rest of pages in application.
For Testing scenario, You can try postman with NTLM(windows authentication) for token generation controller and BearerToken for page which are having JWTAuthentication
Here is how I did it in .net 5 to use both Windows authentication and Jwt on a web api. I first let windows authentication get identity name, then check against a database table for authorization to get roles etc, then return a jwt token. the client web site uses the jwt token to access jwt protected resources.
enable both Anonymous and windows authentication in launchingsettings when debug. in iis if deployed on the server.
if you want to debug through Kestrel, at the time of this writing, in startup, DON'T use
services.AddAuthentication(IISDefaults.AuthenticationScheme);
instead, use
services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate();
standard set up in startup configureservices to add jwt authentication. in configure function, add authentication.
decorate your function that you want to use windows authentication with this:
[Authorize(AuthenticationSchemes = NegotiateDefaults.AuthenticationScheme)]
[Route("GetToken")]
[HttpGet]
public IActionResult GetToken()
{}
[Authorize(AuthenticationSchemes =JwtBearerDefaults.AuthenticationScheme)]
[ApiController]
[Route("[controller]")]
public class ReportController : ControllerBase
{
}
that's all.
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