3

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.

2
  • 2
    Do you have two tokens coming in on the same request? What constitutes an "AND"? Commented May 6, 2020 at 21:51
  • 1
    Yes, both the token comes in same request. AND - Need to validate both the token. Commented May 6, 2020 at 22:02

2 Answers 2

3

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();
});
Sign up to request clarification or add additional context in comments.

Comments

3
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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.