Я пробую веб-API в ядре .net.Я добавил контроллер API в свое существующее веб-приложение MVC .net core.
Я использую токены JWT для авторизации.Я делаю это через класс запуска.
API работает просто отлично.
Но, как и ожидалось, авторизация применяется ко всему приложению MVC.
Есть лиКак я могу включить аутентификацию через токены-носители только для контроллеров API, а не для контроллеров веб-приложений?
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 Token включена в классе запуска;Я получаю неавторизованный код 401 при попытке получить доступ к действиям контроллера не API.
Я пытаюсь:
- Добавить APIконтроллер для существующего веб-приложения .net core mvc.
Использовать аутентификацию токена JWT только для методов API, но не для методов веб-приложения.
- Возможно ли вышеизложенное?Это хорошая практика?Как это может быть достигнуто?
Нужно направление.Спасибо:)