【问题标题】:ASP.NET Core authenticating with Identity Server JWT and Auth CookieASP.NET Core 使用 Identity Server JWT 和 Auth Cookie 进行身份验证
【发布时间】: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


    【解决方案1】:

    我看到的第一个问题是AddIdentityServerAuthentication(...)的使用

    查看内容here,上面写着“此库已弃用,不再维护”

    所以它指向这个blog post,我建议你只使用 AddJwtBearer() 代替。

    【讨论】:

    • 对不起,原谅我的天真。您是说 IdentityServer 是一个已弃用的库吗?我不知道这是如何阻止 Cookie 身份验证发生的?
    • 不,只有那个方法被弃用了。 IdentityServer 非常活跃。
    • 一般来说,最好将 API 作为自己的服务,这样推理和故障排除会更清晰、更简单。
    • 为什么需要一个同时接受 cookie 和令牌的 API?通常你只想使用令牌?
    • 这是我很困惑的事情。我有一些不需要用户登录才能访问的 API,例如“GetAllProducts”,然后是其他需要登录的 API,例如“GetMyOrderDetails”。这就是为什么我想我想用 IdentityServer 保护所有 API,然后在用户登录后发出一个 cookie,以便 Cookie Auth 访问一些 API。这是正确的方法吗?
    猜你喜欢
    • 2015-10-01
    • 2018-09-02
    • 1970-01-01
    • 2018-12-30
    • 1970-01-01
    • 1970-01-01
    • 2017-10-29
    • 2020-12-19
    • 2021-03-28
    相关资源
    最近更新 更多