简体   繁体   English

401 未授权使用 IdentityServer3.AccessTokenValidation

[英]401 Unauthorized using IdentityServer3.AccessTokenValidation

When using IdentityServer3.AccessTokenValidation in my .Net 4.8 (not core) WebAPI to secure the endpoints, the WebAPI always returns a 401 Not Authorized to the client app.在我的 .Net 4.8(非核心)WebAPI 中使用 IdentityServer3.AccessTokenValidation 来保护端点时,WebAPI 始终向客户端应用程序返回 401 Not Authorized。 The token is supplied by IDS4.令牌由 IDS4 提供。 When the client is calling my Asp.Net Core API, Authorization is successful.当客户端调用我的 Asp.Net Core API 时,授权成功。 But when calling the .Net 4.8 AspNet WebApi, it is not.但是在调用 .Net 4.8 AspNet WebApi 时,它不是。

Client MVC App Startup.ConfigureServices:客户端 MVC 应用程序 Startup.ConfigureServices:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();

            JwtSecurityTokenHandler.DefaultMapInboundClaims = false;

            services.AddAuthentication(options =>
            {
                options.DefaultScheme = "Cookies";
                options.DefaultChallengeScheme = "oidc";
            })
                .AddCookie("Cookies")
                .AddOpenIdConnect("oidc", options =>
                {
                    options.Authority = "http://localhost:5000";
                    options.RequireHttpsMetadata = false;
                    options.ClientId = "TestMvc";
                    options.ClientSecret = "secret";
                    options.ResponseType = "code"; 
                    options.GetClaimsFromUserInfoEndpoint = true;
                    options.SaveTokens = true;
                    options.Scope.Add("testApi");
                    options.CallbackPath = "/auth";
                    options.SignedOutRedirectUri = "~/home";
                });
        } 

The .Net Core API Startup that works:有效的 .Net Core API 启动:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
                .AddIdentityServerAuthentication(options =>
            {
                options.Authority = "http://localhost:5000";
                options.ApiName = "testApi";
                options.RequireHttpsMetadata = false;
                options.RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role";
            });
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseRouting();

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

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

Startup.cs of the .Net 4.8 WebApi that always returns 401:始终返回 401 的 .Net 4.8 WebApi 的 Startup.cs:

public void Configuration(IAppBuilder app)
        {
            var config = new HttpConfiguration();
            config.MapHttpAttributeRoutes();
            config.EnableSystemDiagnosticsTracing();

            var cors = new EnableCorsAttribute("*", "*", "*");
            config.EnableCors(cors);

            var idsOptions = new IdentityServerBearerTokenAuthenticationOptions
            {
                Authority = "http://localhost:5000",
                RequiredScopes = new string[] { "testApi" },
                RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role
            };
            app.UseIdentityServerBearerTokenAuthentication(idsOptions);

            app.UseWebApi(config);
        }

The Asp.Net Core Controller Endpoint that executes successfully成功执行的 Asp.Net Core Controller Endpoint

[Route("test")]
[Authorize(Roles = "[A role claim that is definitely present in access token]")]
public class TestController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        return Ok("Success");
    }
}

The Asp.Net 4.8 Controller Endpoint that returns 401返回 401 的 Asp.Net 4.8 控制器端点

[Route("test")]
[Authorize(Roles = "[A role claim that is definitely present in access token]")]
public class TestController : ApiController
{
    [HttpGet]
    public IHttpActionResult Get()
    {
        return Ok("Success");
    }
}

MVC Client App Calling API: MVC 客户端应用调用 API:

public async Task<IActionResult> AccessApi()
        {
            var accessToken = await HttpContext.GetTokenAsync("access_token");

            var client = new HttpClient();
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
            var content = await client.GetStringAsync("http://localhost:5001/test");

            ViewBag.Json = content;
            return View("json");
        }

The last lines of the IDS server log: IDS 服务器日志的最后几行:

info: Microsoft.AspNetCore.Hosting.Diagnostics[1] Request starting HTTP/1.1 GET http://localhost:5000/.well-known/openid-configuration dbug: IdentityServer4.Hosting.EndpointRouter[0] Request path /.well-known/openid-configuration matched to endpoint type Discovery dbug: IdentityServer4.Hosting.EndpointRouter[0] Endpoint enabled: Discovery, successfully created handler: IdentityServer4.Endpoints.DiscoveryEndpoint info: IdentityServer4.Hosting.IdentityServerMiddleware[0] Invoking IdentityServer endpoint: IdentityServer4.Endpoints.DiscoveryEndpoint for /.well-known/openid-configuration dbug: IdentityServer4.Endpoints.DiscoveryEndpoint[0] Start discovery request info: Microsoft.AspNetCore.Hosting.Diagnostics[2] Request finished in 17.3987ms 200 application/json;信息:Microsoft.AspNetCore.Hosting.Diagnostics[1] 请求开始 HTTP/1.1 GET http://localhost:5000/.well-known/openid-configuration dbug:IdentityServer4.Hosting.EndpointRouter[0] 请求路径 /.well-已知/openid-configuration 匹配端点类型发现 dbug:IdentityServer4.Hosting.EndpointRouter[0] 端点已启用:发现,成功创建处理程序:IdentityServer4.Endpoints.DiscoveryEndpoint 信息:IdentityServer4.Hosting.IdentityServerMiddleware[0] 调用 IdentityServer 端点:IdentityServer4。 Endpoints.DiscoveryEndpoint for /.well-known/openid-configuration dbug:IdentityServer4.Endpoints.DiscoveryEndpoint[0] 开始发现请求信息:Microsoft.AspNetCore.Hosting.Diagnostics[2] 请求在 17.3987ms 200 application/json 中完成; charset=UTF-8 info: Microsoft.AspNetCore.Hosting.Diagnostics[1] Request starting HTTP/1.1 GET http://localhost:5000/.well-known/openid-configuration/jwks dbug: IdentityServer4.Hosting.EndpointRouter[0] Request path /.well-known/openid-configuration/jwks matched to endpoint type Discovery dbug: IdentityServer4.Hosting.EndpointRouter[0] Endpoint enabled: Discovery, successfully created handler: IdentityServer4.Endpoints.DiscoveryKeyEndpoint info: IdentityServer4.Hosting.IdentityServerMiddleware[0] Invoking IdentityServer endpoint: IdentityServer4.Endpoints.DiscoveryKeyEndpoint for /.well-known/openid-configuration/jwks dbug: IdentityServer4.Endpoints.DiscoveryKeyEndpoint[0] Start key discovery request info: Microsoft.AspNetCore.Hosting.Diagnostics[2] Request finished in 16.6027ms 200 application/jwk-set+json; charset=UTF-8 信息:Microsoft.AspNetCore.Hosting.Diagnostics[1] 请求开始 HTTP/1.1 GET http://localhost:5000/.well-known/openid-configuration/jwks dbug: IdentityServer4.Hosting.EndpointRouter[0 ] 请求路径 /.well-known/openid-configuration/jwks 匹配端点类型 Discovery dbug:IdentityServer4.Hosting.EndpointRouter[0] 端点启用:发现,成功创建处理程序:IdentityServer4.Endpoints.DiscoveryKeyEndpoint 信息:IdentityServer4.Hosting.IdentityServerMiddleware [0] 调用 IdentityServer 端点:IdentityServer4.Endpoints.DiscoveryKeyEndpoint for /.well-known/openid-configuration/jwks dbug:IdentityServer4.Endpoints.DiscoveryKeyEndpoint[0] 启动密钥发现请求信息:Microsoft.AspNetCore.Hosting.Diagnostics[2]请求在 16.6027ms 200 application/jwk-set+json 内完成; charset=UTF-8字符集=UTF-8

The token is issued successfully and passed in the request headers to the API.令牌已成功发出并在请求标头中传递给 API。

The API seems to be calling the discover endpoint correctly, but then nothing after that. API 似乎正确地调用了发现端点,但之后就什么也没有了。 I would expect the API to validate the incoming token with the IDS server, but there is no call to the IDS server for validation.我希望 API 使用 IDS 服务器验证传入的令牌,但没有调用 IDS 服务器进行验证。 Confirmed with both the IDS log and using Fiddler to check the traffic.已通过 IDS 日志和使用 Fiddler 检查流量进行确认。

This can be caused by couple of things, to be sure we need the log of ASP.NET API project.这可能是由几件事情引起的,以确保我们需要 ASP.NET API 项目的日志。 Here is some suggested fixes for similar issues:以下是针对类似问题的一些建议修复:

  1. On Statup.cs class of IdentityServer project在 IdentityServer 项目的Statup.cs类上
    • Change AccessTokenJwtType to JWT , default value on IdentityServer4 is at+jwt but .Net Framework Api (OWIN/Katana) requires JWT .AccessTokenJwtType更改为JWT , IdentityServer4 上的默认值是at+jwt但 .Net Framework Api (OWIN/Katana) 需要JWT
    • Add /resources aud by setting EmitLegacyResourceAudienceClaim to true, this is removed on IdentityServer4.通过将EmitLegacyResourceAudienceClaim设置为 true 来添加/resources aud,这在 IdentityServer4 上已删除。

You can verify the access_token on https://jwt.ms/ by checking "typ" and "aud" .您可以通过检查"typ""aud"来验证https://jwt.ms/上的 access_token。

var builder = services.AddIdentityServer(                
                options =>
                {
                    options.AccessTokenJwtType = "JWT"; 
                    options.EmitLegacyResourceAudienceClaim = true;
                });
  1. On Statup.cs class of .Net Framework Api project, set ValidationMode to ValidationMode.Local , access token validation endpoint used by this method is removed on IdentityServer4.在 .Net Framework Api 项目的Statup.cs类上,将ValidationMode设置为ValidationMode.Local ,在 IdentityServer4 上删除此方法使用的访问令牌验证端点。

var idsOptions = new IdentityServerBearerTokenAuthenticationOptions
            {
                Authority = "http://localhost:5000",
                RequiredScopes = new string[] { "testApi" },
                RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
                ValidationMode = ValidationMode.Local,
            };

I have sample working implementationhere , and also a blog post contains more detailshttps://nahidfa.com/posts/identityserver4-and-asp-.net-web-api/我在这里有示例工作实现,还有一篇博客文章包含更多详细信息https://nahidfa.com/posts/identityserver4-and-asp-.net-web-api/

I strongly suggest you to gather logs on API, this helps to find the actual issue in your case and finding the fix.我强烈建议您在 API 上收集日志,这有助于在您的案例中找到实际问题并找到修复程序。 here is a sample to turn on OWIN log on Api. 是在 Api 上打开 OWIN 登录的示例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 Dot Net Framework 4.8 中使用 IdentityModel 1.9.2 和 IdentityServer3.AccessTokenValidation 的扩展授权进行委派 - Delegation using an extension grant with IdentityModel 1.9.2 and IdentityServer3.AccessTokenValidation in Dot Net Framework 4.8 在ASP.NET 5中具有IdentityServer3.AccessTokenValidation的中间件? 返回空对象异常 - owin middlware with IdentityServer3.AccessTokenValidation in ASP.NET 5? returns null object exception 具有IdentityServer3 AccessTokenValidation的Identityserver4 - Identityserver4 with IdentityServer3 AccessTokenValidation AspNet.Core、IdentityServer 4:在使用 JWT 不记名令牌与 SignalR 1.0 进行 websocket 握手期间未经授权 (401) - AspNet.Core, IdentityServer 4: Unauthorized (401) during websocket handshake with SignalR 1.0 using JWT bearer token 使用 IdentityServer4.AccessTokenValidation 包将 .NET 5 Web API 参考令牌授权给 IdentityServer3 时遇到问题 - Trouble authorizing .NET 5 Web API reference tokens to IdentityServer3 using IdentityServer4.AccessTokenValidation package IdentityServer3连接/令牌端点始终返回401:未授权 - IdentityServer3 connect/token endpoint always return 401: unauthorized IdentityServer3 + Angular4 + WebApi导致401未经授权 - IdentityServer3 + Angular4 + WebApi Causing 401 Unauthorized IdentityServer3-401调用Identity API Controller时未授权 - IdentityServer3 - 401 Unauthorized when calling Identity API Controller 401未经授权使用Yahoo OAuth - 401 Unauthorized using Yahoo OAuth 401未经授权使用Google任务 - 401 unauthorized using google task
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM