Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Identity Server 4无法验证我的访问令牌_C#_Asp.net Core_Asp.net Web Api_Identityserver4 - Fatal编程技术网

C# Identity Server 4无法验证我的访问令牌

C# Identity Server 4无法验证我的访问令牌,c#,asp.net-core,asp.net-web-api,identityserver4,C#,Asp.net Core,Asp.net Web Api,Identityserver4,我正在使用Asp.net Core 3.1 Web Api生成Api,并在同一个项目(都在一个项目中)中使用Identity Server 4(3.1.2)和Asp.net Identity Core对用户进行身份验证。 Identity Server 4生成访问令牌,但当使用Postman调用Api时,每次都返回401。 这是我的Identity Server 4配置: "IdentityServerSetting": { "IdentityServer

我正在使用Asp.net Core 3.1 Web Api生成Api,并在同一个项目(都在一个项目中)中使用Identity Server 4(3.1.2)和Asp.net Identity Core对用户进行身份验证。 Identity Server 4生成访问令牌,但当使用Postman调用Api时,每次都返回401。 这是我的Identity Server 4配置:

 "IdentityServerSetting": {
    "IdentityServerAuthority": "https://localhost:5000",
    "IdentityResources": [
      "openID"
    ],
    "ApiResources": [
      {
        "Name": "MadPay",
        "DisplayName": "MadPay Api",
        "UserClaims": [
          "name",
          "Email"
        ]
      }
    ],
    "Client": [
      {
        "AccessTokenLifeTime": 3600,
        "AllowedGrantTypes": "password",
        "ClientId": "angular",
        "AlwaysIncludeUserClaimsInIdToken": "true",
        "AlwaysSendClientClaims": "true",
        "AllowCorsOrigins": [ "https://localhost:5000" ],
        "RequireClientSecret": "false",
        "AllowedScopes": [ "OpenId", "MadPay" ],
        "AllowOfflineAccess": "true"
      }
    ]
  }
这是我的配置服务

public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<JwtConfig>(_configuration.GetSection(nameof(JwtConfig)));
            services.Configure<IdentityServerSetting>(_configuration.GetSection(nameof(IdentityServerSetting)));

            services.AddScoped<IUnitOfWork, UnitOfWork<ApplicationDBContext>>();

            services.AddMapperConfigurations();
            services.AddServices();

            services.AddDbContext<ApplicationDBContext>(opt =>
            {
                opt.UseSqlServer(_configuration.GetConnectionString("ApplicationConnection"));
            });

            services.AddMvcCore(opt => opt.EnableEndpointRouting = false)
             .SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
             .AddAuthorization()
             .AddNewtonsoftJson(options =>
                    options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);

            services.AddResponseCaching();
            services.AddIdentityServerConfig(_identityServerSetting);
            services.AddApiAuthorization();

            services.AddCors();
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            services.Configure<ApiBehaviorOptions>(options =>
            {
                options.SuppressModelStateInvalidFilter = true;
            });
        }
附加授权功能

 public static void AddApiAuthorization(this IServiceCollection services)
        {
            services.AddAuthentication(options =>
            {
                options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
                .AddJwtBearer(opt =>
                 {
                     opt.Authority = "https://localhost:5000";
                     opt.RequireHttpsMetadata = false;
                     //opt.Audience = "MadPay";
                     opt.TokenValidationParameters = new TokenValidationParameters
                     {
                         ValidateAudience = false
                     };
                 });

 services.AddScoped<IAuthorizationHandler, PermissionAuthorizationHandler>();

            services.AddAuthorization(option =>
                option.AddPolicy("Permission", builder =>
                    builder.AddRequirements(new PermissionRequirement()).RequireAuthenticatedUser()
                )
            );
}
对于调用Api,请使用以下url:https://localhost:5000/... 并在授权头中发送令牌:承载者

我认为颁发的访问令牌不是问题。 我花了几天时间,不明白为什么不工作,很困惑到底是怎么回事


谢谢您可以将所有令牌验证参数设置为false,然后逐个启用它们,以查看是什么触发了错误

            options.TokenValidationParameters.ValidateAudience = false;
            options.TokenValidationParameters.ValidateIssuer = false;
            options.TokenValidationParameters.ValidateIssuerSigningKey = false;
            options.TokenValidationParameters.ValidateLifetime = false;
            options.TokenValidationParameters.ValidateTokenReplay = false;
您还可以尝试启用以下功能,并检查postman或Fiddler中API的响应

            //True if token validation errors should be returned to the caller.
            options.IncludeErrorDetails = true;
如何保护API控制器?您是否使用任何授权策略

在API启动时,不应使用IdentityServer,而应使用AddMyJWTBearrer方法。在配置方法中,您应该使用:

        app.UseAuthentication();
        app.UseAuthorization();
下面是一个典型API的示例startup.cs类:

public class Startup
{
    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();

        
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddMyJwtBearer(options =>
        {

            options.Audience = "payment";
            options.Authority = "https://localhost:6001/";

            //True if token validation errors should be returned to the caller.
            options.IncludeErrorDetails = true;

            //If the signing key is not found, do a refresh from the JWKS endpoint
            //This allows for automatic recovery in the event of a  key rollover
            options.RefreshOnIssuerKeyNotFound = true;

            //Gets or sets if HTTPS is required for the metadata address or authority.
            //Should always be true in production!
            options.RequireHttpsMetadata = true;

            //True if the token should be stored in the AuthenticationProperties
            //after a successful authorization.
            options.SaveToken = true;

            //Parameters
            options.TokenValidationParameters.ClockSkew = TimeSpan.FromMinutes(5);
            options.TokenValidationParameters.NameClaimType = "name";
            options.TokenValidationParameters.RoleClaimType = "role";

        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHttpsRedirection();

        app.UseRouting();

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


        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

您可以将所有令牌验证参数设置为false,然后逐个启用它们,以查看是什么触发了错误

            options.TokenValidationParameters.ValidateAudience = false;
            options.TokenValidationParameters.ValidateIssuer = false;
            options.TokenValidationParameters.ValidateIssuerSigningKey = false;
            options.TokenValidationParameters.ValidateLifetime = false;
            options.TokenValidationParameters.ValidateTokenReplay = false;
您还可以尝试启用以下功能,并检查postman或Fiddler中API的响应

            //True if token validation errors should be returned to the caller.
            options.IncludeErrorDetails = true;
如何保护API控制器?您是否使用任何授权策略

在API启动时,不应使用IdentityServer,而应使用AddMyJWTBearrer方法。在配置方法中,您应该使用:

        app.UseAuthentication();
        app.UseAuthorization();
下面是一个典型API的示例startup.cs类:

public class Startup
{
    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();

        
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddMyJwtBearer(options =>
        {

            options.Audience = "payment";
            options.Authority = "https://localhost:6001/";

            //True if token validation errors should be returned to the caller.
            options.IncludeErrorDetails = true;

            //If the signing key is not found, do a refresh from the JWKS endpoint
            //This allows for automatic recovery in the event of a  key rollover
            options.RefreshOnIssuerKeyNotFound = true;

            //Gets or sets if HTTPS is required for the metadata address or authority.
            //Should always be true in production!
            options.RequireHttpsMetadata = true;

            //True if the token should be stored in the AuthenticationProperties
            //after a successful authorization.
            options.SaveToken = true;

            //Parameters
            options.TokenValidationParameters.ClockSkew = TimeSpan.FromMinutes(5);
            options.TokenValidationParameters.NameClaimType = "name";
            options.TokenValidationParameters.RoleClaimType = "role";

        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHttpsRedirection();

        app.UseRouting();

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


        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

您缺少以下信息:-

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

您可以在api中的startup.cs配置方法中添加上述内容并尝试一下吗?

您缺少以下内容:-

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


您可以在api中的startup.csConfigure方法中添加上述内容并尝试一下吗?

您可以发布令牌的副本吗?您的邮递员请求是什么样子的?您是否在API中使用任何授权策略?或者API控制器是如何保护的?我编辑了我的问题并添加了更多细节。我在下面更新了我的答案,这有帮助吗?你能发布令牌的副本吗?你的邮递员请求是什么样子的?您是否在API中使用任何授权策略?或者API控制器是如何保护的?我编辑了我的问题并添加了更多详细信息。我在下面更新了我的答案,这有帮助吗?这不起作用,我将项目添加到Gitlab,以查看所有代码。感谢您在API项目中同时使用IdentityServer4和Asp.net Core Identity,如果不使用IdentityServer,则无法访问和生成令牌此错误不完整?trce:IdentityServer 4.Hosting.EndpointRouter[0]未找到请求路径的端点条目:/api/WeatherForecasting在我的示例中,请尝试从URL中删除/api/部分。这有用吗?或者将我的模式更改为模板:“api/{controller}/{action}/{id?}”);我看到您在GitLab中的代码使用了旧的ASP.NET核心编码风格。使用app.UseRouting()更为现代;和app.UseEndpoints()。未修复!我的Api Url和Identity Server Url是相同的:并且都使用https,这不对吗?这不起作用,我将项目添加到Gitlab,以查看所有代码。感谢您在Api项目中同时使用Identity Server 4和Asp.net Core Identity,如果不使用IdentityServer,则无法访问和生成令牌此错误不完整?trce:IdentityServer 4.Hosting.EndpointRouter[0]未找到请求路径的端点条目:/api/WeatherForecasting在我的示例中,请尝试从URL中删除/api/部分。这有用吗?或者将我的模式更改为模板:“api/{controller}/{action}/{id?}”);我看到您在GitLab中的代码使用了旧的ASP.NET核心编码风格。使用app.UseRouting()更为现代;和app.UseEndpoints()。未修复!我的Api Url和Identity Server Url是相同的:并且都使用https,这是错误的吗???@AliBelyani-您正在调用哪个Api端点?如果是weatherForecast get终结点,您可能需要检查permission属性,以获得所需的结果。@AliBelyani-您正在调用哪个api终结点?如果是weatherForecast get端点,您可能需要检查permission属性,如果这给了您所需的结果。