Microsoft.AspNetCore.Authorization
is used to validate token while is there any attribute that checks httpOnlyCookie
present in browser and is valid i.e like it also checks role based authentication.
I tried to create a custom attribute that handles the httponlycookie
authentication while I don't want to use custom attributes if there is any built in attribute provided by ASP.NET Core.
Here's my code:
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Text;
using System;
public class AuthorizeWithCookieAttribute : Attribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
var request = context.HttpContext.Request;
// Check if the authToken cookie exists
if (!request.Cookies.TryGetValue("authToken", out var token) || string.IsNullOrEmpty(token))
{
context.Result = new JsonResult(new { message = "Unauthorized: No auth token found in cookie." })
{ StatusCode = 401 };
return;
}
Console.WriteLine("Token from cookie: " + token); // Debugging
try
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.UTF8.GetBytes("this is my secret key more then 128 bits");
tokenHandler.ValidateToken(token, new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
ClockSkew = TimeSpan.Zero // Reduce token time discrepancy
}, out _);
Console.WriteLine("Token validation success!"); // Debugging
}
catch (Exception ex)
{
Console.WriteLine("Token validation failed: " + ex.Message); // Debugging
context.Result = new JsonResult(new { message = "Unauthorized: Invalid token.", error = ex.Message })
{ StatusCode = 401 };
}
}
}
[HttpGet("GetFruits")]
[AuthorizeWithCookie]
public IActionResult GetFruits()
{ }
Now custom attribute AuthorizeWithCookie
works
If you want to get the token from the cookie during the auth, I suggest you could consider using the JwtBearerEvents OnMessageReceived to set the token .
Then you could directly using the Authorize(Roles = "Admin")]
to check the role.
More details, you could refer to below codes:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
ClockSkew = TimeSpan.Zero
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
if (context.Request.Cookies.TryGetValue("authToken", out var token))
{
context.Token = token;
}
return Task.CompletedTask;
}
};
});