简体   繁体   English

身份服务器 4 - API 在部署到服务器时返回 401 Unauthorized

[英]Identity Server 4 - API returns 401 Unauthorised when deployed to servers

I am using a Blazor Server app authenticating through Identity Server 4 with access to an asp.net core 3.1 API.我正在使用 Blazor Server 应用程序通过 Identity Server 4 进行身份验证,并可以访问 asp.net core 3.1 API。 Locally, I have a set up working using Identity Server on port 5000, API on 5001, and my Blazor App on 5002.在本地,我在端口 5000 上使用 Identity Server、在 5001 上使用 API 以及在 5002 上使用我的 Blazor 应用程序进行设置。

On our test servers we have hosted all three in IIS(Blazor on one server, API and Identity Server on another).在我们的测试服务器上,我们在 IIS 中托管了所有三个(Blazor 在一台服务器上,API 和身份服务器在另一台服务器上)。 I get 401 Unauthorized when accessing an Authorize tagged controller.访问 Authorize 标记的控制器时,我得到 401 Unauthorized。 I am able to login and I know the API is reachable still as not all controllers need authorize and that data comes through.我能够登录并且我知道 API 仍然可以访问,因为并非所有控制器都需要授权并且数据可以通过。 Also, I know there's a token as I have at one point printed it to the page.另外,我知道有一个令牌,因为我曾经将它打印到页面上。

What perhaps may be the cause for the API no longer accepting the token generated by Identity Server when in our test environment?在我们的测试环境中,API 不再接受 Identity Server 生成的令牌的可能原因是什么?

Here is my code examples, will happily add more if needed:这是我的代码示例,如果需要,将很乐意添加更多:

Authorized Controller授权控制人

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Route("api/[controller]")]
[ApiController]
public class Controller : ControllerBase

API Resources API资源

public static IEnumerable<ApiResource> Apis =>
  new ApiResource[]
  {
    new ApiResource("Api", "MyApi")

  };

Client Set-up客户端设置

 public static IEnumerable<Client> Clients =>
        new List<Client>
         {
             //Client
             new Client
            {
                ClientId = "Client",
                ClientSecrets = { new Secret("secret".Sha256()) },

                AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,

                // where to redirect to after login
                RedirectUris = { "http://location:5002/signin-oidc" },

                // where to redirect to after logout
                PostLogoutRedirectUris = { "http://location:5002/signout-callback-oidc" },

                AllowedScopes = new List<string>
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    IdentityServerConstants.StandardScopes.OfflineAccess,
                    "Api"
                },
                AllowOfflineAccess = true


            }
         };

Api Configuration接口配置

services.AddAuthentication("Bearer")
 .AddJwtBearer("Bearer", options =>
 {
     options.Authority = AuthUrl; // IS loc

     options.Audience = "Api"; 
 });

Client Configuration客户端配置

services.AddSingleton<IDiscoveryCache>(sp =>
            {
                var factory = sp.GetRequiredService<IHttpClientFactory>();
                return new DiscoveryCache(
                    AuthUrl,
                    () => factory.CreateClient());
            });
            services.AddAuthentication(options =>
            {
                options.DefaultScheme = "Cookies";
                options.DefaultChallengeScheme = "oidc";
            })
            .AddCookie("Cookies")
            .AddOpenIdConnect("oidc", options =>
            {
                options.Authority = AuthUrl;
                options.ClientId = ClientID;
                options.ClientSecret = ClientSecret;
                options.ResponseType = "code id_token";
                options.SaveTokens = true;
                options.GetClaimsFromUserInfoEndpoint = true;

                // part 3
                options.Scope.Add("openid");
                options.Scope.Add("offline_access");
                options.Scope.Add("Api");
                options.RequireHttpsMetadata = false;
            });

Here is how I have used Signing Credentials这是我如何使用签名凭证

// not recommended for production - you need to store your key material somewhere secure
        if (Environment.IsDevelopment())
        {
            builder.AddDeveloperSigningCredential();
        }
        else
        {
            X509Certificate2 cert = null;
            using (var certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine))
            {
                certStore.Open(OpenFlags.ReadOnly);
                var certCollection = certStore.Certificates.Find(
                    X509FindType.FindByThumbprint,
                    "76588d12094bc26991faf9e3eaaa241d973fe72f", // Change this with the thumbprint of your certificate
                    false);

                if (certCollection.Count > 0)
                {
                    cert = certCollection[0];
                }
            }
            builder.AddSigningCredential(cert);
        }

I have used a self signed certificate generated through openssl and I have tested this works in developers environment too by not using the .developerssigningcredentials.我使用了通过 openssl 生成的自签名证书,并且我也通过不使用 .developerssigningcredentials 在开发人员环境中测试了它的工作原理。

Make sure that your IIS pool of your website has access to your private certificate key.确保您网站的 IIS 池可以访问您的私有证书密钥。

you can try using LocalSystem您可以尝试使用 LocalSystem 在此处输入图片说明

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM