[英]API Authorization with Identity Server 4 keeps returning 401 Unauthorized
我正在使用 Identity Server 4.Net Core 3,如果我在啟動時使用標准配置,我的 API 端點不會驗證訪問令牌,我一直收到 401 Unauthorized,但是當我在具有授權屬性的控制器中設置身份驗證方案時,我可以使用相同的令牌成功訪問我的端點...
[Route("api/[controller]")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[ApiController]
public class MyWebAPiControllerController : ControllerBase
{
.......
這是我的身份服務器配置:
//API resource
public IEnumerable<ApiResource> Apis()
{
var resources = new List<ApiResource>();
resources.Add(new ApiResource("identity", "My API", new[] { JwtClaimTypes.Subject, JwtClaimTypes.Email, JwtClaimTypes.Role, JwtClaimTypes.Profile }));
return resources;
}
我的客戶端配置:
public IEnumerable<Client> Clients()
{
var Clients = new List<Client>();
Clients.Add(new Client
{
ClientId = "client",
ClientSecrets = { new Secret(_securityConfig.Secret.Sha256()) },
AllowedGrantTypes = GrantTypes.ClientCredentials,
// scopes that client has access to
AllowedScopes = { "identity" }
});
Clients.Add(new Client
{
ClientId = "mvc",
ClientName = "MVC Client",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
//RequirePkce = true,
ClientSecrets = { new Secret(_securityConfig.Secret.Sha256()) },
RequireConsent = false,
RedirectUris = _securityConfig.RedirectURIs,
FrontChannelLogoutUri = _securityConfig.SignoutUris,
PostLogoutRedirectUris = _securityConfig.PostLogoutUris,
AllowOfflineAccess = true,
AllowAccessTokensViaBrowser = true,
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
IdentityServerConstants.StandardScopes.OfflineAccess,
"identity"
}
});
return Clients;
}
我的 API 配置
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = _securityConfig.Authority;
options.RequireHttpsMetadata = false;
options.Audience = "identity";
});
最后是我的網絡應用程序、OIDC 配置以及我如何獲取訪問令牌:
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "oidc";
}).AddCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
options.Cookie.Name = "identity_cookie";
})
.AddOpenIdConnect("oidc", options =>
{
options.Events = new OpenIdConnectEvents
{
OnUserInformationReceived = async ctx =>
{
//Get Token here and assign to Cookie for use in Jquery
ctx.HttpContext.Response.Cookies.Append("bearer_config", ctx.ProtocolMessage.AccessToken);
}
};
options.Authority = _securityConfig.Authority;
options.RequireHttpsMetadata = false;
options.ClientId = "mvc";
options.ClientSecret = _securityConfig.Secret;
options.ResponseType = "code id_token";
options.SaveTokens = true;
options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("email");
options.Scope.Add("identity");
options.Scope.Add("offline_access");
options.ClaimActions.MapAllExcept("iss", "nbf", "exp", "aud", "nonce", "iat", "c_hash");
options.GetClaimsFromUserInfoEndpoint = true;
//options.SaveTokens = true;
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = JwtClaimTypes.Name,
RoleClaimType = JwtClaimTypes.Role,
};
});
關於為什么我不斷收到 401 Unauthorized 的任何想法?
根據所描述的行為,我認為這可能與中間件配置有關,更具體地說是中間件的順序。 但我不能確定,因為 Startup.Configure 在問題中不可用。
幸運的是,雅克可以確認問題確實出在訂單上。 如評論中所述:
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication();
這里的問題是用戶首先被授權( UseAuthorization
)然后被認證( UseAuthentication
)。 因此,用戶永遠無法獲得授權,因為此時它是未知的(匿名的)。 但稍后,當屬性被驗證時,用戶是已知的。 所以這就解釋了為什么會這樣。
為了解決這個問題,必須切換語句。 先對用戶進行身份驗證(識別用戶,用戶是誰?),然后對用戶進行授權:
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
該順序在文檔中進行了描述。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.