簡體   English   中英

JWT 不記名令牌授權應用於 .NET Core 中的現有 MVC Web 應用程序

[英]JWT bearer token authorization being applied on exisitng MVC web appication in .NET Core

我正在 .net 核心中嘗試 Web API。 我在現有的 .net 核心 MVC Web 應用程序中添加了一個 API 控制器。

我正在使用 JWT 令牌進行授權。 我是通過啟動類來做到這一點的。

API 工作得很好。

但正如預期的那樣,授權正在應用於整個 MVC 應用程序。

有沒有一種方法可以通過承載令牌僅對 API 控制器而不是 Web 應用程序控制器啟用身份驗證?

啟動.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 Token認證; 當我嘗試訪問非 api 控制器操作時,我也收到了 401 未經授權的代碼。

我正在嘗試的是:

  1. 將 API 控制器添加到現有的 .net core mvc Web 應用程序。
  2. 僅將 JWT 令牌身份驗證用於 API 方法,而不是 Web 應用程序方法。

    • 以上可能嗎? 這是一個好習慣嗎? 如何實現?

需要方向。 謝謝:)

詳細文章

在 ASP.NET Core 中使用多個身份驗證/授權提供程序

是的,你可以在這里幾步

  1. 在 Startup.cs 中設置多個身份驗證方案
  2. 根據控制器使用方案
  3. 指定 Web 應用程序的策略並在 Web 應用程序控制器中使用該[Authorize(Policy = "WebApp") ]
  4. 在 Web API 控制器中只使用 JWT 身份驗證方案

    [授權(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()));
        });

您可以在 .NET 中編寫自己的授權屬性。 [CustomAuthorization]而不是內置屬性。 當然是學習階段。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM