JWT承载令牌授权已应用于.NET Core中存在的MVC Web应用程序 [英] JWT bearer token authorization being applied on exisitng MVC web appication in .NET Core

查看:73
本文介绍了JWT承载令牌授权已应用于.NET Core中存在的MVC Web应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试.net核心中的Web API.我已经在现有的.net核心MVC Web应用程序中添加了API控制器.

I am trying out Web API's in .net core. I have added an API controller to my existing .net core MVC web application.

我正在使用JWT令牌进行授权.我正在通过启动类来做到这一点.

I am using JWT Tokens for authorization. I am doing this through the startup class.

API可以正常工作.

The API works just fine.

但是,正如预期的那样,授权已应用于整个MVC应用程序.

But as expected the authorization is being applied on the entire MVC application.

是否有一种方法可以仅通过API控制器而不是Web应用程序控制器通过承载令牌启用身份验证?

Is there a way I can enable authentication through bearer tokens only for the API controllers and not the web application controllers?

Startup.cs:

using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Project.Data;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;

namespace Project
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }
        public bool ValidateAudience { get; private set; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));

            services.AddIdentity<IdentityUser,IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

            services.Configure<CookiePolicyOptions>(options =>
            {
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;

            });

            services.ConfigureApplicationCookie(options =>
            {
                options.Cookie.HttpOnly = true;
                options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
                options.LoginPath = "/Identity/Account/Login"; 
                options.LogoutPath = "/Identity/Account/Logout"; 
                options.AccessDeniedPath = "/Identity/Account/AccessDenied"; 
                options.SlidingExpiration = true;
            });

            services.AddCors();

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            services.AddAuthentication(option =>
            {
                option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                option.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(options =>
            {
                options.SaveToken = true;
                options.RequireHttpsMetadata = true;
                options.TokenValidationParameters = new TokenValidationParameters()
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidAudience = Configuration["Jwt:Site"],
                    ValidIssuer = Configuration["Jwt:Site"],
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SigningKey"]))
                };
            });

        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseAuthentication();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{Controller=Startup}/{action=Login}/{id?}");
            });
        }
    }
}

appsettings.json:

{
  "ConnectionStrings": {
    "DefaultConnection": " Data Source=Server; Database = db;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
  "Jwt": {
    "Site": "www.signinkey.com",
    "SigningKey": "ConstantSigningKey",
    "ExpiryInMinutes": "30"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

API控制器:

namespace Project.Controllers
{
    [Route("api/[controller]/[action]")]
    public class AuthController : BaseController
    {
        protected IConfiguration _configuration;

        public AuthController(UserManager<IdentityUser> userManager, IConfiguration configuration)
        {
            _userManager = userManager;
            _configuration = configuration;
        }

        public string GenerateToken(int size = 32)
        {
            var randomNumber = new byte[size];
            using (var rng = RandomNumberGenerator.Create())
            {
                rng.GetBytes(randomNumber);
                return Convert.ToBase64String(randomNumber);
            }
        }

        [HttpGet("")]
        [Route("modelList")]
        [Authorize]
        public IEnumerable<ModelList> SupervisorList(string username)
        {
             return db.modelList.Select(x => x).ToList();
        }

        [Route("register")]
        [HttpPost]
        public async Task<ActionResult> Register([FromBody] InputModel reg)
        {
            var user = new IdentityUser { UserName = reg.Email, Email = reg.Email, SecurityStamp = Guid.NewGuid().ToString() };
            var result = await _userManager.CreateAsync(user, reg.Password);
            if (result.Succeeded)
            {
                await _userManager.AddToRoleAsync(user, "Admin");
            }
            return Ok(new { Username = user.UserName });

        }

        [Route("login")]
        [HttpPost]
        public async Task<ActionResult> Login([FromBody] InputModel login)
        {
            var user = await _userManager.FindByNameAsync(login.Email);
            if (user != null && await _userManager.CheckPasswordAsync(user, login.Password))
            {

                var claim = new[]
                {
                    new Claim(JwtRegisteredClaimNames.Sub, user.UserName)
                };
                var signinKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SigningKey"]));

                int expiryInMinutes = Convert.ToInt32(_configuration["Jwt:ExpiryInMinutes"]);

                var token = new JwtSecurityToken(
                    issuer: _configuration["Jwt:Site"],
                    audience: _configuration["Jwt:Site"],
                    expires: DateTime.UtcNow.AddMinutes(expiryInMinutes),
                    signingCredentials: new SigningCredentials(signinKey, SecurityAlgorithms.HmacSha256)
                    );


                return Ok(
                    new
                    {
                        token = new JwtSecurityTokenHandler().WriteToken(token),
                        expiration = token.ValidTo
                    });


            }
            return Unauthorized();
        }
    }
}

由于在启动类中启用了JWT令牌认证;尝试访问非api控制器操作时,我也收到401未经授权的代码.

As the JWT Token authentication is enabled in the startup class; I am getting an 401 unauthorized code when I try to access the non api controller actions as well.

我正在尝试的是:

  1. 将API控制器添加到现有的.net核心mvc Web应用程序中.
  2. 仅对API方法而不是Web应用程序方法使用JWT令牌身份验证.

  1. Add an API controller to an existing .net core mvc web application.
  2. Use JWT token authentication only for the API methods and not the web application methods.

  • 以上可能吗?这是一个好习惯吗?如何实现?

需要方向.谢谢:)

推荐答案

详细文章

使用多重身份验证ASP.NET Core中的/授权提供者

是的,您只需几个步骤

  1. 在Startup.cs中设置多种身份验证方案
  2. 根据控制器使用方案
  3. 指定Web应用程序的策略,并在Web应用程序控制器中使用该策略 [Authorize(Policy = "WebApp")]
  4. 在Web API控制器中,只需使用JWT身份验证方案

  1. Setup multiple authentication schemes in Startup.cs
  2. Use scheme as per controller
  3. Specify the Policy for web application and used that in Web app controllers [Authorize(Policy = "WebApp")]
  4. In Web API controllers just use the JWT authentication scheme

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

启动代码

        .AddCookie(options =>
        {
            // You cookie auth setup 
        })
        .AddJwtBearer(options =>
        {
          // Your JWt setup
        })

政策设置

services.AddAuthorization(options =>
        {
            options.AddPolicy("WebApp",
                              policy => policy.Requirements.Add(new WebAppRequirement()));
        });

这篇关于JWT承载令牌授权已应用于.NET Core中存在的MVC Web应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆