简体   繁体   中英

Identity in MVC and JWT + Identity for API part of the application

I got the .NET 5 web app (MVC = Model View Controller), here I have added DefaultIdentity with roles. I add a user to the role, I make an attribute for authorization at controller and methods for a specific role and it works, this part is working ok, eg [Authorize(Roles = Admin)]

Now I have added the API Controllers. I want to use the same attributes on API controllers, but this time user would log to the system via API, and get the JWT, and that JWT contains a specific role, and this is not the problem it also works!

But the problem is putting those two together to work!

After I added logic to the ConfigureServices method, I'm not able to access MVC controllers anymore, and API ones are working. What I'm saying is that 401 is returned, it is obvious that I overwrite the rules, but I want to keep both, any tips or solution is welcome!

services.AddAuthentication(x => { x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; })
                .AddJwtBearer(x => { x.RequireHttpsMetadata = false; x.SaveToken = true; x.TokenValidationParameters = new TokenValidationParameters
                    {
                        ClockSkew = TimeSpan.Zero,
                        ValidateIssuerSigningKey = true,
                        IssuerSigningKey = new SymmetricSecurityKey(key),
                        ValidateIssuer = true,
                        ValidIssuer = appSettings.Issuer,
                        ValidateAudience = true,
                        ValidAudience = appSettings.Issuer,
                        ValidateLifetime = true
                    };
                });

i had similar problem, dont remember exactly what it was but im sure it was something with the order of added auths in startup.cs I have it set like below:

app.UseHttpsRedirection();
app.UseRouting();
app.UseStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
app.UseCookiePolicy();
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
                .AddRoles<ApplicationRole>()
                .AddEntityFrameworkStores<IdentityContext>();

services.AddAuthentication()
              .AddCookie(cfg => cfg.SlidingExpiration = true)
              .AddJwtBearer(cfg =>
              {
                  cfg.RequireHttpsMetadata = false;
                  cfg.SaveToken = true;
                  cfg.TokenValidationParameters = new TokenValidationParameters()
                  {
                      ValidIssuer = Configuration["Tokens:Issuer"],
                      ValidAudience = Configuration["Tokens:Issuer"],
                      IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"]))
                  };
              });
        

I think you have authentication working, but need to add authorization to your startup services and your api controllers. In.Net Core 5 (or I'm using 3.1), add something like this to your startup services:

// can save "UserCredentials" as a public constant, to re-use in api
services.AddAuthorization(options =>
{
    options.AddPolicy("UserCredentials", policy =>
    {
        policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
        // add additional policies
    });
});

Then in your api controller, reference the new "UserCredentials" policy:

[HttpPost("Post")]
[Authorize(Policy = "UserCredentials")]
public async Task<ActionResult> Post()
{ 

}

After I added logic to the ConfigureServices method, I'm not able to access MVC controllers anymore, and API ones are working.

In your code, we can find that you configured JwtBearerDefaults.AuthenticationScheme as default authenticate scheme, which cause the issue.

To make both your MVC and API work well, you can try to remove x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; from AddAuthentication method. And then specify the authentication scheme or schemes to use by applying the [Authorize] attribute on your API action(s), like below.

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[HttpGet]
public IActionResult GetAll()
{

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM