【问题标题】:IdentityServer4 IdentityServer3.AccessTokenValidationIdentityServer4 IdentityServer3.AccessTokenValidation
【发布时间】:2017-05-16 11:05:39
【问题描述】:

祝大家新年快乐……

我配置了一个 IdentityServer4,我可以成功地进行 ASP.net Core web api 调用。 但是对于 asp.net framework 4.5.2 web apis, 我收到来自 .NET 框架 Web api 的 {“响应状态代码不表示成功:401(未授权)。”} 错误。我想请教您的帮助和意见。

我用IS4搜索了主题,发现了一些关于IdentityServer3.AccessTokenValidation兼容性的条目。根据回复,我加载了一个签名证书并调用了 AddSigningCredential 而不是 AddTemporarySigninCredential。 x509certificate 是本地创建的证书。我将 IdentityServer3.AccessTokenValidation 版本更新为 v2.13.0。

我还是得到了错误。 任何帮助表示赞赏。

感谢您的努力。

IdentityServer 4 端: 启动.cs

public void ConfigureServices(IServiceCollection services)
        {
                services
                .AddIdentityServer()                
                //.AddTemporarySigningCredential()
                .AddSigningCredential(x509Certificate)
                .AddInMemoryIdentityResources(Config.GetIdentityResources())
                .AddInMemoryApiResources(Config.GetApiResources())
                .AddInMemoryClients(Config.GetClients())
                .AddAspNetIdentity<ApplicationUser>();
}

Config.cs

    public static IEnumerable<ApiResource> GetApiResources()
            {
                return new List<ApiResource>
                {
                    new ApiResource("AuthorizationWebApi","Authorization Web API .NET Core"),
                    new ApiResource("AuthorizationWebApiNetFramework","Authorization Web API NET Framework"),
                new ApiResource("api1", "Empty Test Api")
                };

            }

        public static IEnumerable<Client> GetClients()
        {
            return new List<Client> {
new Client {
                    ClientId = "silicon",
                    ClientName = "console app",
                    AllowedGrantTypes = GrantTypes.ClientCredentials,
                    ClientSecrets = { new Secret("abcdef".Sha256())},
                    AllowedScopes = new List<string>{
                    "AuthorizationWebApiNetFramework"
                    }

                },
                new Client
                {
                    ClientId = "MYUX",
                    ClientName = "MYUX MVC Client",
                    AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
                    RequireConsent = false,
                    ClientSecrets= {new Secret("abcdef".Sha256()) },
                    RedirectUris = { "http://localhost:5002/signin-oidc" },
                    PostLogoutRedirectUris = {"http://localhost:5002"},

                    AllowedScopes = {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,                        
                        "custom.profile",
                        "AuthorizationWebApi",
                        "AuthorizationWebApiNetFramework"
                    },
                    AllowOfflineAccess = true
                }
            };
        }

.NET Framework API 端

public void Configuration(IAppBuilder app)
        {
            //ConfigureAuth(app);
            app.UseCookieAuthentication(new CookieAuthenticationOptions());
            app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
            {
                Authority = "http://www.abcdefgh.com:5000",
                ValidationMode = ValidationMode.ValidationEndpoint,
                RequiredScopes = new[] { "AuthorizationWebApiNETFramework" }

            });
            //configure web api
            var config = new HttpConfiguration();
            config.MapHttpAttributeRoutes();

            //require authentication for all controllers

            config.Filters.Add(new AuthorizeAttribute());

            app.UseWebApi(config);
        }

调用方:

try
            {
                ViewData["Message"] = "Authorization Test.";
                var accessToken = await HttpContext.Authentication.GetTokenAsync("access_token");
                var authorizationApiClient = new HttpClient();
                authorizationApiClient.SetBearerToken(accessToken);
                var content = await authorizationApiClient.GetStringAsync("http://localhost:13243/values");
                return View();
            }
            catch (Exception ex)
            {
                throw;
            }

或通过控制台应用程序...

try
{
    // discover endpoints from metadata
    var disco = await DiscoveryClient.GetAsync("http://www.abcdefgh.com:5000");

    var tokenClient = new TokenClient(disco.TokenEndpoint, "silicon", "abcdef");
    var tokenResponse = await tokenClient.RequestClientCredentialsAsync("AuthorizationWebApiNetFramework");

    if (tokenResponse.IsError)
    {
        Console.WriteLine(tokenResponse.Error);
        return;
    }

    Console.WriteLine(tokenResponse.Json);

    var client = new HttpClient();
    client.SetBearerToken(tokenResponse.AccessToken);

    var response = await client.GetAsync("http://localhost:13243/values");
    if (!response.IsSuccessStatusCode)
    {
        Console.WriteLine(response.StatusCode);
    }
    else
    {
        var content = await response.Content.ReadAsStringAsync();
        Console.WriteLine(JArray.Parse(content));
    }
}
catch (Exception)
{
   throw;
}     

编辑: 在 4.5.2 Api 方面:我注释掉了这一行 ValidationMode = ValidationMode.ValidationEndpoint。我按照 IS3 文档添加了这一行。谢谢大家。

【问题讨论】:

  • 我建议从示例开始并确认它们有效。然后从示例开始比较你自定义项目中的差异。
  • idsrv4 日志在您收到 401 错误时显示了什么。
  • 谢谢大家,@BrockAllen 正如我所说的,我可以使用 open id connect 对 ASP.Net Core MVC 进行身份验证,并使用我的 ASP.Net Core IS4 使用客户端凭据对 ASP.Net Core WebApi 进行身份验证。但我对 4.5.2 ApiResource 有问题。 Jonas Axelsson 我看到令牌生成成功,但我记得当我调用 WebApi 的 GetAsync 时没有任何反应。我今天会检查它:)。问候
  • @JonasAxelsson 我创建了一个新项目,将其压缩并上传到 googledrive,如果您觉得方便,我想与您分享。这次我保持非常简单:D。我不知道关于它的 SO 政策,所以我没有在这里复制。我们可以在这里分享驱动器链接或电子邮件吗?顺便说一句,我在 IS4 控制台上看到了 4.5.2 web api accesstoken 验证调用。
  • @JonasAxelsson 我在 IS4 控制台上看到了 4.5.2 web api accesstoken 验证调用,但我认为它被 api 拒绝了,我会检查 IS4 端的额外日志记录。

标签: identityserver3 identityserver4


【解决方案1】:

在 WebAPI 访问令牌验证中间件中删除以下行。

ValidationMode = ValidationMode.ValidationEndpoint

结果应该是这样的:

app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions 
{
     Authority = "http://www.abcdefgh.com:5000",
     RequiredScopes = new[] { "AuthorizationWebApiNETFramework" }
});

【讨论】:

    【解决方案2】:

    就我而言,我启用了以下日志:https://identityserver.github.io/Documentation/docsv2/consuming/diagnostics.html

    默认情况下,Katana 使用 .NET 中的 TraceSource 机制进行日志记录。将以下 sn-p 添加到您的配置文件以启用对文件的日志记录:

    <system.diagnostics>
      <trace autoflush="true" />
    
      <sources>
        <source name="Microsoft.Owin">
          <listeners>
            <add name="KatanaListener" />
          </listeners>
        </source>
      </sources>
    
      <sharedListeners>
        <add name="KatanaListener"
              type="System.Diagnostics.TextWriterTraceListener"
              initializeData="katana.trace.log"
              traceOutputOptions="ProcessId, DateTime" />
      </sharedListeners>
    
      <switches>
        <add name="Microsoft.Owin"
              value="Verbose" />
      </switches>
    </system.diagnostics>
    

    然后我在WebAPI文件夹日志文件“katana.trace.log”中看到了根本原因:

        Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationMiddleware Error: 0 : Authentication failed
    System.IO.FileLoadException: Could not load file or assembly 'Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
    File name: 'Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'
       at IdentityServer3.AccessTokenValidation.ValidationEndpointTokenProvider.<ReceiveAsync>d__1.MoveNext()
       at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[TStateMachine](TStateMachine& stateMachine)
       at IdentityServer3.AccessTokenValidation.ValidationEndpointTokenProvider.ReceiveAsync(AuthenticationTokenReceiveContext context)
       at Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationHandler.<AuthenticateCoreAsync>d__0.MoveNext()
    

    在我将 Newtonsoft.Json 从 6.0 升级到 9.01 后,它可以工作了。

    【讨论】:

    • 将日志记录配置添加到 web.config 会使错误在尝试使其输出数小时后立即出现。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 2021-07-21
    • 2019-04-27
    • 2018-05-17
    • 2018-11-10
    • 2015-07-12
    相关资源
    最近更新 更多