【问题标题】:.net 4.6 web api2 401 Unauthorized with identity server 4.net 4.6 web api2 401 未经授权使用身份服务器 4
【发布时间】:2020-08-11 01:13:29
【问题描述】:

我已经在 .net 核心应用程序中有一个工作身份服务器 4。

namespace IdentityServer
{
    public class Config
    {
        public static IEnumerable<ApiResource> GetApiResources()
        {
            return new List<ApiResource>
            {
                new ApiResource("myresourceapi", "My Resource API")
                {
                    Scopes = {new Scope("apiscope")}
                }
            };
        }

        public static IEnumerable<Client> GetClients()
        {
            return new[]
            {
                // for public api
                new Client
                {
                    ClientId = "secret_client_id",
                    AllowedGrantTypes = GrantTypes.ClientCredentials,
                    ClientSecrets =
                    {
                        new Secret("secret".Sha256())
                    },
                    AllowedScopes = { "apiscope" }
                }
            };
        }
    }
}

namespace IdentityServer
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddOperationalStore(options =>
            {
                options.EnableTokenCleanup = true;
                options.TokenCleanupInterval = 30; // interval in seconds
             })
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddInMemoryClients(Config.GetClients());
        }

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

            app.UseIdentityServer();
            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
        }
    }
}

问题是现在我需要向 .net 4.6 web api2(不是核心)发出经过身份验证的请求。而 IdentityServer4.AccessTokenValidation 包对此不起作用。 根据这个问题(https://stackoverflow.com/questions/41992272/is-it-possible-to-use-identity-server-4-running-on-net-core-with-a-webapi-app-r),我所要做的就是使用与身份服务器 3(IdentityServer3.AccessTokenValidation)相同的包。 这是我在 webapi 2 中实现的代码

using IdentityServer3.AccessTokenValidation;
using Microsoft.Owin;
using Owin;
using Microsoft.Owin.Host.SystemWeb;
using IdentityModel.Extensions;
using System.Web.Http;

[assembly: OwinStartup(typeof(WebApplication10.Startup))]

namespace WebApplication10
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
            {
                Authority = "https://localhost:44357",

                // For access to the introspection endpoint
                ClientId = "secret_client_id",
                ClientSecret = "secret".ToSha256(),
                RequiredScopes = new[] { "apiscope" }
            });

        }
    }
}

namespace WebApplication10.Controllers
{
    public class ValuesController : ApiController
    {
        [Authorize]
        // GET api/values
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }
    }
}

我一直得到的状态是 401 Unauthorized。 难道我做错了什么? 有什么帮助吗? 谢谢。

【问题讨论】:

标签: asp.net-core asp.net-web-api2 identityserver4 identityserver3


【解决方案1】:

如果没有日志,无法确定您的情况是什么问题,但我做了一些修复以使其正常工作:

  1. 在 IdentityServer 项目的 Statup.cs 类上
    • AccessTokenJwtType 更改为JWT,IdentityServer4 上的默认值为at+jwt,但.Net Framework Api (OWIN/Katana) 需要JWT
    • 通过将EmitLegacyResourceAudienceClaim 设置为true 添加/resources aud,这在IdentityServer4 上被删除。

您可以通过检查"typ""aud" 来验证https://jwt.ms/ 上的access_token。

var builder = services.AddIdentityServer(                
                options =>
                {
                    options.AccessTokenJwtType = "JWT"; 
                    options.EmitLegacyResourceAudienceClaim = true;
                });
  1. 在.Net Framework Api 项目的Statup.cs 类上,将ValidationMode 设置为ValidationMode.Local,此方法使用的自定义访问令牌验证端点已在IdentityServer4 上移除。
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
            {
                Authority = "https://localhost:44357",

                // For access to the introspection endpoint
                ClientId = "secret_client_id",
                ClientSecret = "secret".ToSha256(),
                RequiredScopes = new[] { "apiscope" },
                ValidationMode = ValidationMode.Local,
            });

我有示例工作实现here

我强烈建议您收集有关 API 的日志,这有助于在您的案例中找到实际问题并找到解决方法。 here是开启OWIN登录Api的样例。

【讨论】:

    【解决方案2】:

    您可以关注CrossVersionIntegrationTests 的示例。

    身份服务器 4 没有 connect/accesstokenvalidation 端点。所以在身份 server4 应用程序中,您可以修改您的 ApiResource 以添加 ApiSecret

    new ApiResource("api1", "My API"){  ApiSecrets = new List<Secret> {new Secret("scopeSecret".Sha256())}}
    

    然后在您的网络 api 中,配置 IdentityServerBearerTokenAuthenticationOptions 之类的:

    app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
    {
        Authority = "http://localhost:5000",
        ValidationMode = ValidationMode.ValidationEndpoint,
        ClientId = "api1",
        ClientSecret = "scopeSecret",
        RequiredScopes = new[] { "api1" }
    });
    

    ClientId & ClientSecret 都来自您的 ApiResource 。

    【讨论】:

    • 您好,感谢您的回复,对我有用的方法是编辑 Identity server 4 配置,正如您所说,在 config.cs IEnumerable GetClients() 中添加一个更改新的 api 资源 (api1) 作为 AllowedScopes = { "apiscope","api1" }
    • 我只是使用api1作为代码示例,你使用myresourceapi然后使用它
    猜你喜欢
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-26
    • 2012-06-29
    • 2017-01-10
    • 2017-02-07
    • 2018-07-09
    相关资源
    最近更新 更多