【问题标题】:Identityserver4 with resource owner password returning 401 in resource server资源所有者密码在资源服务器中返回 401 的 Identityserver4
【发布时间】:2018-06-15 00:48:24
【问题描述】:

带有自定义用户存储库的 IDENTITYSERVER4 资源所有者密码流

按照这个创建了一个身份服务器 link 但在资源服务器端,我无法授权 API。

成功获取访问令牌。

Start up.cs文件中

 public void ConfigureServices(IServiceCollection services)
        {

        services.AddIdentityServer(options =>
            {
                options.Events.RaiseSuccessEvents = true;
                options.Events.RaiseFailureEvents = true;
                options.Events.RaiseErrorEvents = true;
            })
         .AddDeveloperSigningCredential()
        .AddInMemoryIdentityResources(QuickstartIdentityServer.Config.GetIdentityResources())
        .AddInMemoryApiResources(QuickstartIdentityServer.Config.GetApiResources())
        .AddInMemoryClients(QuickstartIdentityServer.Config.GetClients())
        .AddCustomUserStore();


    }

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

        app.UseIdentityServer();
    }

来到 Config.cs 文件

  public static IEnumerable<Client> GetClients()
    {
        // client credentials client
        return new List<Client>
        {
            new Client
            {
                ClientId = "client",
                AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
                AccessTokenType = AccessTokenType.Jwt,
                AccessTokenLifetime = 3600, //86400,
                IdentityTokenLifetime = 3600, //86400,
                UpdateAccessTokenClaimsOnRefresh = false,
                SlidingRefreshTokenLifetime = 30,
                AllowOfflineAccess = true,
                RefreshTokenExpiration = TokenExpiration.Absolute,
                RefreshTokenUsage = TokenUsage.OneTimeOnly,
                AlwaysSendClientClaims = true,
                Enabled = true,
                ClientSecrets = 
                {
                    new Secret("secret".Sha256())
                },
                AllowedScopes = { "api1", "openid"}
            }
        };
    }

现在在资源服务器的 startup.cs 文件中

  public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvcCore().AddAuthorization().AddJsonFormatters();
        services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
       .AddIdentityServerAuthentication(options =>
       {
           options.Authority = "http://localhost:5001"; //This is the identity server url where we are getting accesstoken.
           options.RequireHttpsMetadata = false;
           options.ApiName = "openid";

       });

    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseAuthentication();

        app.UseMvc();

    }

在API中提到

[Route("api/")]
[Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme)]
public class TestController : Controller


    // GET: api/v1/users/5
    [HttpGet("Hello")]
    public async Task<IActionResult> getMessage()
    {

        return Ok("Hello");
    }

}

当我将相同的访问令牌传递给上面的 API 时,得到 401。我需要传递什么吗?或者我缺少任何验证。

请帮帮我。

谢谢。

【问题讨论】:

  • 您需要展示如何将请求发送到您的 api。它是否包含来自 IdentityServer 的访问令牌?
  • @sttl06 - 是的,正如您在最后一个屏幕截图(API 响应)中看到的那样。我在标头中传递“Bearer ”。但是服务器如何知道这个访问令牌是有效的。我错过了什么吗?

标签: c# .net-core identityserver4


【解决方案1】:

我认为你应该更新资源服务器startup.cs文件的ConfigureServices方法,如下所示:

 // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvcCore()
            .AddAuthorization()
            .AddJsonFormatters();

        services.AddAuthentication("Bearer")
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority = "http://localhost:5001";
                options.RequireHttpsMetadata = false;
                options.ApiName = "openid";
            });


        // services.AddMvc();
    }

【讨论】:

  • 是的,那是一回事。
  • 我们是否必须在示例 API 中传递任何其他标头以及 Authorization (accesstoken) 标头
【解决方案2】:

显然,由于问题的性质,我无法重现您的问题,但由于您可以获得访问令牌,但仍然得到 401;我认为这意味着您获得的访问令牌对于您发送请求的 api 无效。 我的猜测是 .AddInMemoryApiResources(QuickstartIdentityServer.Config.GetApiResources()) 配置不正确,例如GetApiResources() 需要返回一个ApiResource,其Scopes 包含openid,这是您用于请求访问令牌的范围。 希望这是有道理的。

【讨论】:

  • 是的,我错误地指的是 GetIdentityResource 中的相同范围,而不是 API 资源。非常感谢:)
猜你喜欢
  • 1970-01-01
  • 2015-09-08
  • 2013-10-17
  • 1970-01-01
  • 2017-06-17
  • 2017-11-14
  • 1970-01-01
  • 2018-01-04
  • 2015-01-06
相关资源
最近更新 更多