ASP.NET 通过 JWT 令牌授权和自定义角色的问题

问题描述 投票:0回答:1

我正在开发一个项目,在该项目中我需要通过角色限制对某些 API 端点的访问。在将 Authorize 标头添加到我想要测试的端点后,我遇到了问题。
enter image description here

我不确定 Login?ReturnUrl 的用途或它的含义。不过,我可以看出 cookie 似乎包含发送请求的角色(以及正确的角色)。

我尝试更改 jwt 和 csrf 令牌,但它们都设置为 SameSiteMode.None 并且安全为 true。出于安全目的,JWT 令牌是 HttpOnly。

AddVoertuig(我正在尝试使用的端点)

        [HttpPost("AddVoertuig")]
        [Authorize(Roles = "Particulier,Zakelijk,Wagenparkbeheerder")]
        public async Task<IActionResult> AddVoertuig([FromBody] Voertuig voertuig)
        {
            if (voertuig == null)
            {
                return BadRequest("Er is iets fout gegaan tijdens het toevoegen. Probeer het opnieuw!");
            }

            _context.Voertuigen.Add(voertuig);
            await _context.SaveChangesAsync();
            return CreatedAtAction(nameof(GetVoertuig), new { Id = voertuig.VoertuigID }, voertuig);
        }

这是我发送请求的地方

        try {
            const resultaat = await fetchCsrf("http://localhost:5202/api/VoertuigBeheer/AddVoertuig", {
                method: "POST",
                headers: {
                    "Content-Type": "application/json"
                },
                credentials: "include",
                body: JSON.stringify(voertuigData)
            });
            if (resultaat.ok) {
                alert("Voertuig toegevoegd!");
                formulier.reset();
            } else {
                alert("Er is iets fout gegaan tijdens het toevoegen van het voertuig. Probeer het opnieuw!");
            }
        } catch (error) {
            console.error("Fout: ", error);
        }

我认为我还添加了正确的配置

builder.Services.AddAuthentication(options =>
                {
                    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(options =>
                {
                    options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                    {
                        ValidateIssuer = true,
                        ValidateAudience = true,
                        ValidateLifetime = true,
                        ValidateIssuerSigningKey = true,
                        ValidIssuer = builder.Configuration["Jwt:Issuer"],
                        ValidAudience = builder.Configuration["Jwt:Audience"],
                        IssuerSigningKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(
                            System.Text.Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])
                        ),
                    };

                    options.Events = new JwtBearerEvents
                    {
                        OnMessageReceived = context =>
                        {
                            var token = context.Request.Cookies["jwtToken"];
                            if (!string.IsNullOrEmpty(token))
                            {
                                context.Token = token;
                            }
                            return Task.CompletedTask;
                        }
                    };
                });

这应该读取 cookie 并从中检索角色,以便用户得到正确的身份验证。我错过了什么?

c# asp.net-core jwt
1个回答
0
投票

就您而言,如果您使用

[Authorize]
而不是
[Authorize(Roles = "Particulier,Zakelijk,Wagenparkbeheerder")]
,恐怕您的代码可能会起作用。

这是因为您正在尝试基于 JWT 身份验证自定义角色验证,它需要您按照 ASP.NET Core 中基于策略的授权 创建自定义策略,在策略中,您需要编写验证逻辑jwt 令牌中包含的角色声明。

这听起来很奇怪,因为 ASP.NET Core 内置了基于角色的授权,对吗?我们看一下这个文档,你会发现角色并不是jwt auth中包含的声明,而是由asp.net core默认身份实现的绑定到用户的角色。就像你知道的,当我们创建一个用户时,我们总是给这个用户分配角色,角色信息将存储在数据库中,每当用户登录时,也会查询用户角色信息,你的

[Authorize(Roles = "Particulier,Zakelijk,Wagenparkbeheerder")]
就是为了这个默认情况下,这样当您的应用发现没有用户登录时,它会重定向到“登录”页面,但不会返回 401/403 错误。

您可以按照我分享的链接创建基于策略的授权,它需要创建AuthorizationHandler来检查角色。我在这里进行了测试,您可以参考它以了解更多详细信息。

© www.soinside.com 2019 - 2024. All rights reserved.