Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.Net Core JWT Token validation

I need to validate multiple token that I receive in request, I followed below code flow

services.AddAuthentication()
    .AddJwtBearer("Token1", options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters()
        {
            ValidateIssuer = true,
            ValidIssuer = Issuer,
            ValidateAudience = true,
            ValidAudience = Audience,
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Key)),
        };
        options.Events = new JwtBearerEvents()
        {
            OnMessageReceived = context =>
            {
                var Token = context.Request.Headers["UserCred1"].ToString();
                context.Token = Token;
                return Task.CompletedTask;
            },
        };
    })
    .AddJwtBearer("Token2", options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters()
        {
            ValidateIssuer = true,
            ValidIssuer = Issuer,
            ValidateAudience = true,
            ValidAudience = Audience,
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Key)),
        };
        options.Events = new JwtBearerEvents()
        {
            OnMessageReceived = context =>
            {
                var Token = context.Request.Headers["UserCred2"].ToString();
                context.Token = Token;
                return Task.CompletedTask;
            },
        };
    });
services.AddAuthorization(options =>
{
    options.DefaultPolicy = new AuthorizationPolicyBuilder()
    .RequireAuthenticatedUser()
    .AddAuthenticationSchemes("Token1", "Token2")
    .Build();
});

Above code works as OR condition, like either Token1 or Token 2 authentication is valid then returns as Success. But for me I need to consider success only when both "Token1" AND, "Token2" are valid.

Kindly let me know your thoughts.

like image 626
DotNetCoder Avatar asked Sep 14 '26 03:09

DotNetCoder


2 Answers

But for me I need to consider success only when both "Token1" AND, "Token2" are valid.

For validating both the token, you could write a custom middleware which would check the authentication in your Startup.cs.

Change like below:

ConfigureServices:

services.AddAuthentication()
    .AddJwtBearer("Token1", options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters()
        {
            ValidateIssuer = true,
            ValidIssuer = "YourValidIssuser",
            ValidateAudience = true,
            ValidAudience = "YourValidAudience",
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("YourIssuerSiningKey")),
        };
        options.Events = new JwtBearerEvents()
        {
            OnMessageReceived = context =>
            {
                var Token = context.Request.Headers["UserCred1"].ToString();
                context.Token = Token;
                return Task.CompletedTask;
            },
        };
    })
    .AddJwtBearer("Token2", options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters()
        {
            ValidateIssuer = true,
            ValidIssuer = "YourValidIssuer",
            ValidateAudience = true,
            ValidAudience = "YourValidAudience",
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("YourIssuerSiningKey")),
        };
        options.Events = new JwtBearerEvents()
        {
            OnMessageReceived = context =>
            {
                var Token = context.Request.Headers["UserCred2"].ToString();
                context.Token = Token;
                return Task.CompletedTask;
            },
        };
    });

Configure:

app.Use(async (context, next) =>
{
            var principal = new ClaimsPrincipal();

            var result1 = await context.AuthenticateAsync("Token1");
            if (!result1.Succeeded)
            {
                context.Response.StatusCode = 401;
                return;
            }

            if (result1?.Principal != null)
            {
                principal.AddIdentities(result1.Principal.Identities);
            }

            var result2 = await context.AuthenticateAsync("Token2");
            if (!result2.Succeeded)
            {
                context.Response.StatusCode = 401;
                return;
            }
            if (result2?.Principal != null)
            {
                principal.AddIdentities(result2.Principal.Identities);
            }

            context.User = principal;
            await next();
});
like image 132
Rena Avatar answered Sep 16 '26 18:09

Rena


services.AddAuthorization(options =>
        {
            options.AddPolicy("RequireAllSchemes", policy =>
            {
                policy.AddAuthenticationSchemes("Token1");
                policy.AddAuthenticationSchemes("Token2");
                policy.RequireAuthenticatedUser();
                policy.RequireAssertion(context =>
                {
                    return context.User.Identities.Count() == 2;
                });
            });
        });

Specify authorization policy for controller

[Authorize(Policy = "RequireAllSchemes")] public class TestController : Controller

like image 34
Vinaykumar Avatar answered Sep 16 '26 16:09

Vinaykumar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!