【问题标题】:Can't protect internal api using IdentityServer 4 (500 error)无法使用 IdentityServer 4 保护内部 api(500 错误)
【发布时间】:2019-08-01 19:53:39
【问题描述】:

一点背景知识,我有一个 IdenityServer 4 项目,用于保护对我拥有的 mvc 项目的访问(使用 ASP.NET Identity)。

现在我还想要一个通过返回一些信息的客户端凭据保护的 api。

我所做的是创建一个新的核心 api 项目,这在客户端保护方面运行良好,但是,我想移动 api,使其位于 IdenityServer 中。

例如本地主机:5000/api/info/getinfo

现在我已经移动了代码,当我使用属性 [Authorize(AuthenticationSchemes = "Bearer")] 时出现 500 错误

我可以使用 DiscoveryClient 使用凭据获取成功的令牌,但不能使用任何请求,除非它们未经授权。

所以在 ID 中我这样设置我的启动:

        services.AddMvc();

        services.AddMvcCore()
            .AddAuthorization()
            .AddJsonFormatters();

        // Configure identity server with in-memory stores, keys, clients and scopes
        services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddInMemoryPersistedGrants()
            .AddInMemoryIdentityResources(Config.GetIdentityResources())
            .AddInMemoryClients(Config.GetClients(Configuration))
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddAspNetIdentity<ApplicationUser>();

        services.AddAuthentication("Bearer")
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority = Configuration.GetSection("Authority").Value;
                options.RequireHttpsMetadata = false;

                options.ApiName = "IdentityInfoApi";
            });

然后对于受保护的 api 调用,我将其标记为:[Authorize(AuthenticationSchemes = "Bearer")]

但这会返回一个 500 错误,现在当我使用标签时:[Authorize] 它可以工作,但那是因为用户已登录到 mvc 应用程序并且响应是一个 html 页面而不是我想要的 json 对象。

目前我正在使用单元测试来访问 api,代码如下所示:

var client = new HttpClient();

        var disco = DiscoveryClient.GetAsync("https://localhost:5000").Result;

        var tokenClient = new TokenClient(disco.TokenEndpoint, "client", "secret");
        var tokenResponse = tokenClient.RequestClientCredentialsAsync("IdentityInfoApi").Result;
        client.SetBearerToken(tokenResponse.AccessToken);

        var response = client.GetAsync("https://localhost:5000/api/info/getinfo").Result;
        if (!response.IsSuccessStatusCode)
        {
            var userResult = response.Content.ReadAsStringAsync().Result;

            var result = JsonConvert.DeserializeObject<PagedUserList>(userResult);

            Assert.NotNull(result);
        }

是我设置的ID、客户端代码有问题还是不能这样使用ID?

感谢您的帮助

【问题讨论】:

    标签: c# asp.net identityserver4


    【解决方案1】:

    在玩了很多之后,我相信我找到了解决办法。

    你必须在 AddIdentity() 之前定义 AddAuthentication() 或者换句话说你必须在 Identity Server 之前配置 api

    如果您的 api 是外部的,那么无论如何都可以这样做,但如果它在 Identity Server 应用程序本身内则不行。

    我的新代码如下所示:

      //Configure api
            services.AddMvcCore()
                .AddAuthorization()
                .AddJsonFormatters();
    
            services.AddAuthentication("Bearer")
                .AddIdentityServerAuthentication(options =>
                {
                    options.Authority = "https://localhost:5000";
                    options.RequireHttpsMetadata = false;
    
                    options.ApiName = "IdentityInfoApi";
                });
            //end
    
            services.AddIdentity<ApplicationUser, IdentityRole>(config =>
            {
                config.SignIn.RequireConfirmedEmail = true;
            })
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();
    
            // Add application services.
            services.AddTransient<IEmailSender, EmailSender>();
            services.Configure<AuthMessageSenderOptions>(Configuration.GetSection("SMTP"));
    
            services.AddMvc();
    
            // Configure identity server with in-memory stores, keys, clients and scopes
            services.AddIdentityServer()
                .AddDeveloperSigningCredential()
                .AddInMemoryPersistedGrants()
                .AddInMemoryIdentityResources(Config.GetIdentityResources())
                .AddInMemoryClients(Config.GetClients(Configuration))
                .AddInMemoryApiResources(Config.GetApiResources())
                .AddAspNetIdentity<ApplicationUser>();
    

    希望这对其他人有帮助

    【讨论】:

    • 为我工作,谢谢。你能修正'localhost'中的错字吗?我复制了代码,过了 10 分钟才发现它给了 500!
    猜你喜欢
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多