【发布时间】:2022-01-23 17:59:14
【问题描述】:
我在这里看不到 JWT 的木材。
背景:
我正在编写一个 API 服务,并计划在它前面添加一个 React SPA。我想使用 IdentityServer 4 保护 API。用户需要提供用户名和密码才能访问一些 API - GetOrderDetails 等...
设置:
MyService.API Startup.cs (.net 5.0)
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
});
// Identity Server Configuration
services.AddAuthentication()
.AddIdentityServerAuthentication("Bearer", options =>
{
options.ApiName = "myservice.api";
options.Authority = "https://localhost:5011"; // the address IDS is listening on
});
services.AddAuthorization(options =>
{
options.AddPolicy(CookieAuthenticationDefaults.AuthenticationScheme, new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme)
.Build());
options.DefaultPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes("Bearer")
.Build();
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseAuthentication();
app.UseCookiePolicy(new CookiePolicyOptions
{
MinimumSameSitePolicy = Microsoft.AspNetCore.Http.SameSiteMode.Strict
});
app.UseAuthorization();
}
MyService.API.Controllers OrdersController.cs
[Authorize]
public class MyServiceController : ControllerBase
{
[HttpGet]
[Route("orders/basicOrderDetails/orderId")]
public async Task<IActionResult> GetBasicOrderDetails([FromRoute] int orderId)
{
// this method returns back the some simple information to show on the
// login screen
var basicOrderDetails = service.GetBasicOrderDetails(orderId);
return Ok(basicOrderDetails);
}
[AllowAnonymous]
[HttpPost]
[Route("orders/authenticate")]
public async Task<IActionResult> Authenticate(FromBody] AuthenticateOrderCredentials creds)
{
var authenticated = _authenticationManager.Authenticate(creds.Email, creds.Password);
if(!authenticated)
{
return Unauthorized();
}
var claims = new List<Claim> { new Claim(ClaimTypes.Email, orderCredentials.UserEmail) };
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties
{
AllowRefresh = true,
ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10),
IssuedUtc = DateTimeOffset.UtcNow,
};
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
return Ok();
}
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
[HttpGet]
[Route("orders/orderId")]
public async Task<IActionResult> GetOrder(FromRoute] int orderId)
{
var orderDetails = service.GetOrderDetails(orderId);
return Ok(orderDetails);
}
}
测试:
没有 JWT 也没有 Auth Cookie:我不能调用任何方法 - 有道理。
JWT 令牌和没有 Auth Cookie:我可以调用 GetBasicOrderDetails api 方法 - 有意义。
JWT 令牌并且没有 Auth Cookie:我仍然可以调用 GetOrder api 方法 - 没有意义,因为我认为它会检查 [Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)] - 我希望 401。
JWT 令牌和 Auth Cookie(在调用 Authenticate 之后):我可以调用 GetOrder api 方法 - 这是因为 JWT 还是 Cookie?
没有 JWT 和 Auth Cookie:我可以调用 GetOrder api 方法 - 有意义。
问题:
我有没有过分强调这一点?不确定我明白我应该做什么?我的想法是我需要使用 Identity Server 保护 所有 API 并且我需要另外提供一个身份验证 Cookie 才能访问 GetOrder api 方法 - 我的想法是否正确?仅向 GetOrder 提供身份验证 Cookie 是否足够,因此该方法不需要受 Identity Server 的保护?如果是这样,为什么GetOrder 会返回 200 而没有 Cookie 并且两者都有?
非常感谢您的帮助。
【问题讨论】:
标签: c# asp.net-core cookies jwt identityserver4