簡體   English   中英

.net 4.6 web api2 401 未經身份服務器授權 4

[英].net 4.6 web api2 401 Unauthorized with identity server 4

我已經在 .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 package 對此不起作用。 根據這個問題( 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) 相同的 package。 這是我在 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。 難道我做錯了什么? 有什么幫助嗎? 謝謝。

如果沒有日志,則無法確定您的情況是什么問題,但這是我為使其正常工作而進行的一些修復:

  1. 關於 IdentityServer 項目的Statup.cs class
    • 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 class 上,將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,
            });

在這里有示例工作實現

我強烈建議您在 API 上收集日志,這有助於找到您案例中的實際問題並找到修復程序。 是在 Api 上打開 OWIN 日志的示例。

您可以按照CrossVersionIntegrationTests中的示例進行操作。

身份服務器 4 沒有connect/accesstokenvalidation端點。 因此,在身份 server4 應用程序中,您可以修改ApiResource以添加ApiSecret

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

在您的 web api 中,配置IdentityServerBearerTokenAuthenticationOptions如下:

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

ClientIdClientSecret都來自您的 ApiResource。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM