![](/img/trans.png)
[英]How to configure an ASP.Net Core 2.0 API to use Azure AD as Identity Provider
[英]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.