我正在尝试Web API中的.NET核心。我已经在我现有的.NET Core MVC Web应用程序中添加了API控制器。
我正在使用JWT令牌进行授权。我正在通过启动课程进行此操作。
API工作正常。
,但正如预期的那样,授权已应用于整个MVC应用程序。
有没有一种方法可以通过API控制器而不是Web应用程序控制器来启用身份验证?
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个未经授权的代码。
我正在尝试的是:
- 将API控制器添加到现有的.NET Core MVC Web应用程序中。
仅适用于API方法而不是Web应用程序方法。
- 可以上述吗?这是一个好习惯吗?怎么能实现?
需要方向。谢谢:)
详细的文章
使用ASP.NET Core
中的多个身份验证/授权提供商是的,您可以这里有几个步骤
- 在startup.cs中设置多个身份验证方案
- 根据控制器使用方案
- 指定Web应用程序的策略,并在Web应用程序控制器中使用了该策略
[Authorize(Policy = "WebApp")
] 在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]
,而不是内置属性。当然要学习阶段。