Asp.net core Identity Server 4的API授权不断返回401未经授权

Asp.net core Identity Server 4的API授权不断返回401未经授权,asp.net-core,identityserver4,openid-connect,jwt-auth,Asp.net Core,Identityserver4,Openid Connect,Jwt Auth,我使用的是Identity Server 4.Net Core 3,如果我在启动时使用标准配置,我的API端点不会验证访问令牌,我会不断获得401未授权,但是当我在控制器中使用authorize属性设置身份验证方案时,我可以使用相同的令牌成功访问我的端点 [Route("api/[controller]")] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] [ApiController] pu

我使用的是Identity Server 4.Net Core 3,如果我在启动时使用标准配置,我的API端点不会验证访问令牌,我会不断获得401未授权,但是当我在控制器中使用authorize属性设置身份验证方案时,我可以使用相同的令牌成功访问我的端点

[Route("api/[controller]")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[ApiController]
public class MyWebAPiControllerController : ControllerBase
{
.......
以下是我的Identity Server配置:

//API resource       
public IEnumerable<ApiResource> Apis()
{
        var resources = new List<ApiResource>();

        resources.Add(new ApiResource("identity", "My API", new[] { JwtClaimTypes.Subject, JwtClaimTypes.Email, JwtClaimTypes.Role, JwtClaimTypes.Profile }));

        return resources;
}
最后是我的web应用、OIDC配置以及如何获取访问令牌:

        services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = "oidc";
        }).AddCookie(options =>
            {
                options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
                options.Cookie.Name = "identity_cookie";
            })
        .AddOpenIdConnect("oidc", options =>
        {
            options.Events = new OpenIdConnectEvents
            {
                OnUserInformationReceived = async ctx =>
                {
                    //Get Token here and assign to Cookie for use in Jquery
                    ctx.HttpContext.Response.Cookies.Append("bearer_config", ctx.ProtocolMessage.AccessToken);
                }
            };

            options.Authority = _securityConfig.Authority;
            options.RequireHttpsMetadata = false;

            options.ClientId = "mvc";
            options.ClientSecret = _securityConfig.Secret;
            options.ResponseType = "code id_token";
            options.SaveTokens = true;


            options.Scope.Clear();
            options.Scope.Add("openid");
            options.Scope.Add("profile");
            options.Scope.Add("email");
            options.Scope.Add("identity");
            options.Scope.Add("offline_access");

            options.ClaimActions.MapAllExcept("iss", "nbf", "exp", "aud", "nonce", "iat", "c_hash");

            options.GetClaimsFromUserInfoEndpoint = true;
            //options.SaveTokens = true;

            options.TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = JwtClaimTypes.Name,
                RoleClaimType = JwtClaimTypes.Role,
            };


        });

关于我为什么一直得到401未经授权,有什么想法吗?

基于所描述的行为,我认为这可能与中间件配置有关,更具体地说是中间件的顺序。但我不能确定,因为启动。配置在问题中不可用

幸运的是,雅克能够确认问题确实出在订单上。如评论中所述:

app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication();
这里的问题是,用户首先经过授权(
UseAuthorization
),然后经过身份验证(
UseAuthorization
)。因此,用户永远不能被授权,因为此时它是未知的(匿名的)。但是稍后,当属性被验证时,用户是已知的。所以这就解释了为什么会这样

为了解决这个问题,必须切换语句。首先对用户进行身份验证(识别用户,用户是谁?),然后授权用户:

app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

顺序如中所述。

能否验证启动中的。配置?特别是
UseAuthorization
语句。@RuardvanElburg,我的中间件如下:
app.usehttpseredirection();app.UseRouting();app.UseAuthorization();app.UseAuthentication()反过来,使用身份验证,然后使用授权。首先识别用户,然后授权用户。这就是为什么中间件不起作用,但属性起作用。@RuardvanElburg它起作用了!只要加上它作为答案,我就接受。先生,您是一位学者和绅士!
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();