C# JWT承载令牌授权应用于.NET Core中现有的MVC web应用程序
我正在试用.net内核中的Web API。我已经在现有的.net核心MVC web应用程序中添加了一个API控制器 我使用JWT令牌进行授权。我是通过创业课程来做这件事的 API工作得很好 但正如预期的那样,授权将应用于整个MVC应用程序 是否有一种方法可以仅为API控制器而不是web应用程序控制器启用通过承载令牌的身份验证 Startup.cs:C# JWT承载令牌授权应用于.NET Core中现有的MVC web应用程序,c#,asp.net-web-api,asp.net-core,jwt,asp.net-core-webapi,C#,Asp.net Web Api,Asp.net Core,Jwt,Asp.net Core Webapi,我正在试用.net内核中的Web API。我已经在现有的.net核心MVC web应用程序中添加了一个API控制器 我使用JWT令牌进行授权。我是通过创业课程来做这件事的 API工作得很好 但正如预期的那样,授权将应用于整个MVC应用程序 是否有一种方法可以仅为API控制器而不是web应用程序控制器启用通过承载令牌的身份验证 Startup.cs: using System; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCo
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?}");
});
}
}
}
{
"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": "*"
}
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();
}
}
}
API控制器:
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?}");
});
}
}
}
{
"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": "*"
}
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();
}
}
}
命名空间项目.控制器
{
[路由(“api/[controller]/[action]”)
公共类AuthController:BaseController
{
受保护的IConfiguration\u配置;
公共AuthController(UserManager UserManager,IConfiguration配置)
{
_userManager=userManager;
_配置=配置;
}
公共字符串GenerateToken(int size=32)
{
var randomNumber=新字节[大小];
使用(var rng=RandomNumberGenerator.Create())
{
rng.GetBytes(随机数);
返回Convert.tobase64字符串(随机数);
}
}
[HttpGet(“”)
[路线(“模型列表”)]
[授权]
公共IEnumerable SupervisorList(字符串用户名)
{
返回db.modelList.Select(x=>x.ToList();
}
[路线(“登记”)]
[HttpPost]
公共异步任务寄存器([FromBody]InputModel reg)
{
var user=new IdentityUser{UserName=reg.Email,Email=reg.Email,SecurityStamp=Guid.NewGuid().ToString()};
var result=await\u userManager.CreateAsync(用户,注册密码);
if(result.successed)
{
wait_userManager.AddToRoleAsync(用户,“Admin”);
}
返回Ok(新的{Username=user.Username});
}
[路线(“登录”)]
[HttpPost]
公共异步任务登录([FromBody]InputModel登录)
{
var user=await\u userManager.FindByNameAsync(login.Email);
if(user!=null&&wait\u userManager.CheckPasswordAsync(user,login.Password))
{
var索赔=新[]
{
新索赔(JwtRegisteredClaimNames.Sub,user.UserName)
};
var-signinKey=new-SymmetricSecurityKey(Encoding.UTF8.GetBytes(_-configuration[“Jwt:SigningKey”]);
int expiryInMinutes=Convert.ToInt32(_配置[“Jwt:expiryInMinutes]”);
var token=新的JwtSecurityToken(
发卡机构:_配置[“Jwt:站点”],
受众:_配置[“Jwt:站点”],
expires:DateTime.UtcNow.AddMinutes(expireyMinutes),
signingCredentials:新的signingCredentials(signinKey,SecurityAlgorithms.HmacSha256)
);
返回Ok(
新的
{
token=new JwtSecurityTokenHandler().WriteToken(令牌),
expiration=token.ValidTo
});
}
未经授权返回();
}
}
}
由于启动类中启用了JWT令牌身份验证;当我尝试访问非api控制器操作时,也会收到401未经授权的代码
我正在尝试的是:
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?}");
});
}
}
}
{
"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": "*"
}
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();
}
}
}
- 上述情况是否可能?这是一种好的做法吗?如何实现这一目标
[授权(Policy=“WebApp”)
] .AddCookie(options =>
{
// You cookie auth setup
})
.AddJwtBearer(options =>
{
// Your JWt setup
})
策略设置
services.AddAuthorization(options =>
{
options.AddPolicy("WebApp",
policy => policy.Requirements.Add(new WebAppRequirement()));
});
详细文章
是的,你可以。这里有几个步骤
[授权(Policy=“WebApp”)
] .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]
而不是内置的attributer。用于学习阶段。您可以在.NET中编写自己的授权属性。类似于[CustomAuthorization]
而不是内置的attributer。课程的学习阶段