无法使用IdentityServer 4保护内部api(500错误)

时间:2018-10-25 10:09:09

标签: c# asp.net identityserver4

有一点背景知识,我有一个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错误,现在当我使用标记时:[授权]它起作用了,但这是因为用户已登录到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?

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

经过大量的尝试,我相信我找到了解决方法。

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

如果您的api是外部的,则可以进行任何处理,但如果它本身在Identity Server应用程序中,则可以这样做。

我的新代码如下:

  //Configure api
        services.AddMvcCore()
            .AddAuthorization()
            .AddJsonFormatters();

        services.AddAuthentication("Bearer")
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority = "https://locahhost: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>();

希望这对其他人有帮助