簡體   English   中英

如何使用 IIdentityServerBuilder's.AddApiAuthorization() 使用 NSwag API 配置 Identity Server?

[英]How to configure Identity Server with NSwag API using IIdentityServerBuilder's .AddApiAuthorization()?

我想使用 Identity Server 創建各種身份驗證/授權流程,讓用戶在我的 Swagger API 中授權自己,以便他們可以訪問標有 [Authorize] 屬性的端點。 這是我的電流:

我用 NSwag 中間件和 OAuth2 安全方案設置了 Swagger:

services.AddMvcCore().AddApiExplorer();

            services.AddOpenApiDocument(settings =>
            {
                settings.Title = "MyProject Services";
                settings.Version = "1.0";
                settings.AddSecurity("oauth2", new NSwag.OpenApiSecurityScheme
                {
                    Type = NSwag.OpenApiSecuritySchemeType.OAuth2,
                    Flow = NSwag.OpenApiOAuth2Flow.AccessCode,
                    AuthorizationUrl = "/connect/authorize",
                    TokenUrl = "/connect/token",
                    Scopes = new Dictionary<string, string>
                    {
                        {  "MyProjectServicesAPI", "API Access" }
                    }
                });
                settings.OperationProcessors.Add(new AspNetCoreOperationSecurityScopeProcessor("oauth2"));
            });

以及 Configure() 中的 OAuth2 客戶端設置:

app.UseOpenApi();
app.UseSwaggerUi3(options =>
{
   options.OAuth2Client = new NSwag.AspNetCore.OAuth2ClientSettings
   {
       ClientId = "MyProjectAPI",
       ClientSecret = "mysecret",
       UsePkceWithAuthorizationCodeGrant = true
    };
});

用戶選擇 scope 並授權后,他們會被重定向到我搭建的身份服務器登錄頁面,然后他們可以從那里登錄。 一旦他們輸入憑據並按“登錄”,他們就會被重定向回 Swagger API。 到目前為止,一切都很好。 現在這是我開始遇到麻煩的地方,因為我想稍后添加策略,因此用戶必須具有特定的聲明才能訪問端點,但是現在,我無法在 JWT Bearer 中看到我的用戶的任何聲明當我訪問和端點時,請求 header 中的令牌。 我得到的關於我的用戶的唯一信息是在他們的 GUID 的“sub”中。 我希望能夠獲得他們的用戶名 email 和角色。

到目前為止,這是我為 Identity Server 設置的內容(以及我目前遇到的問題):在 ConfigureServices() 下:

services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options =>
  {
     options.IdentityResources = new IdentityResourceCollection
        {
            new IdentityResources.OpenId(),
            new IdentityResources.Profile(),
            new IdentityResources.Email(),
            new IdentityResource
            {
                 Name = "roles",
                 DisplayName = "roles",
                 UserClaims = new List<string> { JwtClaimTypes.Role }
            },
            new IdentityResource
            {
                Name = "basicInfo",
                DisplayName = "basic info",
                UserClaims = new List<string> {
                    JwtClaimTypes.PreferredUserName
                }
            }
       };
       options.Clients = new ClientCollection
       {
           new Client
           {
               ClientId = "MyProjectAPI",
               ClientName = "My Project Services API",
               ClientSecrets = { new Secret("mysecret".Sha256()) },
               AllowedGrantTypes = GrantTypes.Code,
               AllowAccessTokensViaBrowser = true,
               RedirectUris = { "https://localhost:44319/swagger/oauth2-redirect.html" },
               PostLogoutRedirectUris = { "https://localhost:44319/Identity/Account/Logout" },
               AllowedScopes = {
                    "basicInfo",
                    "roles",
                    "MyProjectServicesAPI",
                     IdentityServerConstants.StandardScopes.OpenId,
                     IdentityServerConstants.StandardScopes.Profile,
                     IdentityServerConstants.StandardScopes.Email,
              RequirePkce = true,
              RequireConsent = false
          }
     };                 
});


services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddIdentityServerJwt()
    .AddJwtBearer(options =>
       {
            options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
            {
                ValidateIssuer = true
            };
});

然后在管道中:

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

我最近收到了從 Identity Server 的 OidcConfigurationController 拋出的這個錯誤:

'Can't determine the type for the client 'MyProject''

我將 AllowedGrantTypes 的授權代碼類型放在我的客戶端中,所以我不太確定它為什么會拋出該錯誤。

我是否需要自己將聲明添加到不記名令牌? 如果我包括范圍,為什么沒有出現這些聲明? 提前感謝您的任何幫助。

編輯#1:我確實解決了從 OidcConfigurationController 收到的錯誤。 我將添加 JWT Bearer 令牌僅顯示“MyProjectServicesAPI”scope,僅此而已。但是,我的 oidc 發現文檔顯示了所有這些?

我想我能夠部分解決我的問題。 所以我沒有設置 Identity Server 的 Profile Service 來獲取我的用戶 ID,因此它可以獲取身份聲明。

ProfileService.cs:

private readonly UserManager<ApplicationUser> _userManager;

        public ProfileService(UserManager<ApplicationUser> userManager)
        {
            _userManager = userManager;
        }

        // Add custom claims to access token.
        public async Task GetProfileDataAsync(ProfileDataRequestContext context)
        {
            context.IssuedClaims.AddRange(context.Subject.Claims);

            var user = await _userManager.GetUserAsync(context.Subject);

            var roles = await _userManager.GetRolesAsync(user);

            var claims = new List<Claim>
            {
                new Claim(JwtClaimTypes.Email, user.Email),
                new Claim(JwtClaimTypes.PreferredUserName, user.UserName),
            };

            foreach (var claim in claims)
            {
                context.IssuedClaims.Add(claim);
            }

            foreach (var role in roles)
            {
                context.IssuedClaims.Add(new Claim(JwtClaimTypes.Role, role));
            }
        }

        public async Task IsActiveAsync(IsActiveContext context)
        {
            var user = await _userManager.GetUserAsync(context.Subject);
            context.IsActive = (user != null) && user.LockoutEnabled;
        }

然后回到 Startup.cs:

services.AddIdentityServer()
    .AddDeveloperSigningCredential()
    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options =>
    {
     ....
    })
    .AddProfileService<ProfileService>();

就是這樣。 訂單確實很重要,因為我在 AddApiAuthorization() 之前確實有 AddProfileService() 並且沒有工作,我的所有范圍仍然沒有顯示在我的 JWT 令牌中,所以我需要重新審視它。 即使從這些身份資源中提取了正確的聲明

暫無
暫無

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

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