Auth0,授权扩展 & ASP.NET 授权
Auth0, with Authorization Extension & ASP.NET Authorization
我在一个使用 Auth0 的项目中工作。我们希望使用Authorization Extension中的权限系统来设置它。
例如
角色管理员:
users:viewAll
users:edit
users:xyz
角色用户:
users:edit拥有
users:viewOwn
users:ect
然后在项目中使用 [Authorize(Policy = "users:kvm")]
标签。
但是,我找不到任何关于如何实际使用 Auth0 的授权扩展的资源。我完全不知所措,所以如果有人能指导我在哪里寻找这些,我会很高兴。
您可以使用授权 Extension
创建表示对每个应用程序的访问权限。
注意:创建权限时“名称”应反映应用程序的客户端ID
下面的示例图片
然后创建代表每个应用程序的角色,并确保选择了相关权限。
在这个例子中:角色名称是“SampleClientAccess”
- 然后创建组和 link 您创建的角色。将相关用户加入群组
- 最后一步。转到仪表板 > 规则 > 创建自定义规则和以下代码。
function (user, context, callback) {
// Assume that permission for an application is the client_id of the permission then
if (user.permissions.indexOf(context.clientID) === -1 ){
callback(new UnauthorizedError('You are not allowed to access ' + context.clientName + JSON.stringify(user)));
}
callback(null, user, context);
}
希望这对您有所帮助。
我决定放弃auth0的授权,自己做一个系统。
无法理解文档。
授权扩展可通过API
访问
您必须启用 API 访问并设置机器到机器的通信,以便您可以访问端点。 (如 link 中所述)
然后使用 this 文档来管理权限、角色、组等
每个请求都必须包含一个令牌 (JWT),您必须事先通过 POST 请求从 https://yourdomain.auth0.com/oauth/token 获得该令牌。
您必须提供四个参数:
grant_type = client_credentials
client_id = {from your auth0 application}
client_secret = {from your auth0 application}
audience=urn:auth0-authz-api
将token放入每个请求的header中作为"Authorization" : "Bearer #YOURTOKEN#"
您可以使用任何 REST 客户端访问端点。首先,我建议 Postman to test the endpoints and check which calls you need. There is a handy collection 您可以使用一些调整。
我想补充一下我是如何在旧版 .NET MVC 应用程序和 .NET Core 2.0 API 中使用它的,因为我希望它能为人们节省很多我花在解决这个问题上的时间.
如果您只想获取组、权限、角色和更新 auth0 中的用户帐户,请按照@StV 的答案中的步骤进行操作。
但如果您想在 .NET 中检查 permissions/roles 等,那么我就是这样做的:
将组、角色和权限添加到访问或 Id 令牌(或两者)。为此,请按照说明 here
从上述配置步骤发布规则后,您必须在 Auth0 中自己创建另一个规则,以将信息复制到令牌中(这让我有一段时间了)。这必须在 Auth0 的规则 published/created 之后 运行。我的看起来像这样:
function (user, context, callback) {
if(user.app_metadata) {
var namespace = 'https://visionplatform.com/';
context.accessToken[namespace + 'roles'] = user.roles;
context.accessToken[namespace + 'permissions'] = user.permissions;
context.idToken[namespace + 'roles'] = user.roles;
context.idToken[namespace + 'permissions'] = user.permissions;
}
callback(null, user, context);
}
现在,如果您的用户登录,他们将在他们的令牌中拥有他们的组、角色和权限。但是请记住,ONLY 您验证的特定客户端的组、角色和权限将显示(我为此浪费了时间)。
所以现在您可以 get/check 代码中的权限来解码 JWT。这是我如何在库方法中完成此操作的一些代码片段(即不是授权属性):
首先获取您的 TokenValidationPrams
public TokenValidationParameters GetTokenValidationParameter(string domain, string audience)
{
IConfigurationManager<OpenIdConnectConfiguration> configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>($"{domain}.well-known/openid-configuration", new OpenIdConnectConfigurationRetriever());
var openIdConfig = AsyncHelper.RunSync(async () => await configurationManager.GetConfigurationAsync(CancellationToken.None));
return new TokenValidationParameters
{
ValidIssuer = $"{domain}",
ValidAudiences = new[] { audience },
IssuerSigningKeys = openIdConfig.SigningKeys
};
}
然后解码您的 JWT 以获得声明
private ClaimsPrincipal GetValidatedToken(string token, TokenValidationParameters validationParameters)
{
var handler = new JwtSecurityTokenHandler();
return handler.ValidateToken(token, validationParameters, out var _);
}
现在您可以检查声明原则,看看它是否包括您的组、权限或其他内容(请注意,我只是检查权限)。
public bool ValidateTokenClaimsPermissionExists(string token, string domain, string audience, string permission)
{
var claimsPrincipal = GetValidatedToken(token, _tokenValidationParameters);
var scopePermission = claimsPrincipal.FindFirst(c => c.Type == Constants.PermissionsClaimTypeName && c.Value == permission);
return scopePermission != null;
}
我使用上面的方法进行单独调用以检查权限,但您可以(并且可能应该)编写自己的授权属性,或者如果您使用的是 .NET Core,则可以编写一个 AuthorizationHandler 中间件来检查您想要的任何声明根据文档 here。下面的代码检查范围,但您可以根据上面的代码调整它以检查权限:
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasScopeRequirement requirement)
{
// If user does not have the scope claim, get out of here
if (!context.User.HasClaim(c => c.Type == "scope" && c.Issuer == requirement.Issuer))
{
return Task.CompletedTask;
}
// Split the scopes string into an array
var scopes = context.User.FindFirst(c => c.Type == "scope" && c.Issuer == requirement.Issuer).Value.Split(' ');
// Succeed if the scope array contains the required scope
if (scopes.Any(s => s == requirement.Scope))
context.Succeed(requirement);
return Task.CompletedTask;
}
我也将使用上述所有内容为我的 .NET MVC 应用程序编写授权属性。
对于简单的设置,您可以通过 Auth0 GUI 设置角色并使用规则将其应用于用户:
function (user, context, callback) {
// Roles should only be set to verified users.
if (!user.email || !user.email_verified) {
return callback(null, user, context);
}
user.app_metadata = user.app_metadata || {};
const assignedRoles = (context.authorization || {}).roles;
const addRolesToUser = function(user) {
return assignedRoles;
};
const roles = addRolesToUser(user);
user.app_metadata.roles = roles;
auth0.users.updateAppMetadata(user.user_id, user.app_metadata)
.then(function() {
context.idToken['https://schemas.<yourdomain>.com'] = user.app_metadata.roles;
callback(null, user, context);
})
.catch(function (err) {
callback(err);
});
}
你的 startup.cs 应该是这样的:
services.AddAuthorization(options =>
{
options.AddPolicy("Administrator", authBuilder => { authBuilder.RequireRole("Administrator"); });
options.AddPolicy("User", authBuilder => { authBuilder.RequireRole("Administrator", "User"); });
}
例如在控制器中:
[Authorize(Roles = "Administrator, User")]
<<your code>>
我在一个使用 Auth0 的项目中工作。我们希望使用Authorization Extension中的权限系统来设置它。
例如 角色管理员: users:viewAll users:edit users:xyz
角色用户: users:edit拥有 users:viewOwn users:ect
然后在项目中使用 [Authorize(Policy = "users:kvm")]
标签。
但是,我找不到任何关于如何实际使用 Auth0 的授权扩展的资源。我完全不知所措,所以如果有人能指导我在哪里寻找这些,我会很高兴。
您可以使用授权 Extension
创建表示对每个应用程序的访问权限。
注意:创建权限时“名称”应反映应用程序的客户端ID
下面的示例图片
然后创建代表每个应用程序的角色,并确保选择了相关权限。
在这个例子中:角色名称是“SampleClientAccess”
- 然后创建组和 link 您创建的角色。将相关用户加入群组
- 最后一步。转到仪表板 > 规则 > 创建自定义规则和以下代码。
function (user, context, callback) {
// Assume that permission for an application is the client_id of the permission then
if (user.permissions.indexOf(context.clientID) === -1 ){
callback(new UnauthorizedError('You are not allowed to access ' + context.clientName + JSON.stringify(user)));
}
callback(null, user, context);
}
希望这对您有所帮助。
我决定放弃auth0的授权,自己做一个系统。
无法理解文档。
授权扩展可通过API
访问您必须启用 API 访问并设置机器到机器的通信,以便您可以访问端点。 (如 link 中所述)
然后使用 this 文档来管理权限、角色、组等
每个请求都必须包含一个令牌 (JWT),您必须事先通过 POST 请求从 https://yourdomain.auth0.com/oauth/token 获得该令牌。
您必须提供四个参数:
grant_type = client_credentials
client_id = {from your auth0 application}
client_secret = {from your auth0 application}
audience=urn:auth0-authz-api
将token放入每个请求的header中作为"Authorization" : "Bearer #YOURTOKEN#"
您可以使用任何 REST 客户端访问端点。首先,我建议 Postman to test the endpoints and check which calls you need. There is a handy collection 您可以使用一些调整。
我想补充一下我是如何在旧版 .NET MVC 应用程序和 .NET Core 2.0 API 中使用它的,因为我希望它能为人们节省很多我花在解决这个问题上的时间.
如果您只想获取组、权限、角色和更新 auth0 中的用户帐户,请按照@StV 的答案中的步骤进行操作。
但如果您想在 .NET 中检查 permissions/roles 等,那么我就是这样做的:
将组、角色和权限添加到访问或 Id 令牌(或两者)。为此,请按照说明 here
从上述配置步骤发布规则后,您必须在 Auth0 中自己创建另一个规则,以将信息复制到令牌中(这让我有一段时间了)。这必须在 Auth0 的规则 published/created 之后 运行。我的看起来像这样:
function (user, context, callback) {
if(user.app_metadata) {
var namespace = 'https://visionplatform.com/';
context.accessToken[namespace + 'roles'] = user.roles;
context.accessToken[namespace + 'permissions'] = user.permissions;
context.idToken[namespace + 'roles'] = user.roles;
context.idToken[namespace + 'permissions'] = user.permissions;
}
callback(null, user, context);
}
现在,如果您的用户登录,他们将在他们的令牌中拥有他们的组、角色和权限。但是请记住,ONLY 您验证的特定客户端的组、角色和权限将显示(我为此浪费了时间)。
所以现在您可以 get/check 代码中的权限来解码 JWT。这是我如何在库方法中完成此操作的一些代码片段(即不是授权属性):
首先获取您的 TokenValidationPrams
public TokenValidationParameters GetTokenValidationParameter(string domain, string audience)
{
IConfigurationManager<OpenIdConnectConfiguration> configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>($"{domain}.well-known/openid-configuration", new OpenIdConnectConfigurationRetriever());
var openIdConfig = AsyncHelper.RunSync(async () => await configurationManager.GetConfigurationAsync(CancellationToken.None));
return new TokenValidationParameters
{
ValidIssuer = $"{domain}",
ValidAudiences = new[] { audience },
IssuerSigningKeys = openIdConfig.SigningKeys
};
}
然后解码您的 JWT 以获得声明
private ClaimsPrincipal GetValidatedToken(string token, TokenValidationParameters validationParameters)
{
var handler = new JwtSecurityTokenHandler();
return handler.ValidateToken(token, validationParameters, out var _);
}
现在您可以检查声明原则,看看它是否包括您的组、权限或其他内容(请注意,我只是检查权限)。
public bool ValidateTokenClaimsPermissionExists(string token, string domain, string audience, string permission)
{
var claimsPrincipal = GetValidatedToken(token, _tokenValidationParameters);
var scopePermission = claimsPrincipal.FindFirst(c => c.Type == Constants.PermissionsClaimTypeName && c.Value == permission);
return scopePermission != null;
}
我使用上面的方法进行单独调用以检查权限,但您可以(并且可能应该)编写自己的授权属性,或者如果您使用的是 .NET Core,则可以编写一个 AuthorizationHandler 中间件来检查您想要的任何声明根据文档 here。下面的代码检查范围,但您可以根据上面的代码调整它以检查权限:
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasScopeRequirement requirement)
{
// If user does not have the scope claim, get out of here
if (!context.User.HasClaim(c => c.Type == "scope" && c.Issuer == requirement.Issuer))
{
return Task.CompletedTask;
}
// Split the scopes string into an array
var scopes = context.User.FindFirst(c => c.Type == "scope" && c.Issuer == requirement.Issuer).Value.Split(' ');
// Succeed if the scope array contains the required scope
if (scopes.Any(s => s == requirement.Scope))
context.Succeed(requirement);
return Task.CompletedTask;
}
我也将使用上述所有内容为我的 .NET MVC 应用程序编写授权属性。
对于简单的设置,您可以通过 Auth0 GUI 设置角色并使用规则将其应用于用户:
function (user, context, callback) {
// Roles should only be set to verified users.
if (!user.email || !user.email_verified) {
return callback(null, user, context);
}
user.app_metadata = user.app_metadata || {};
const assignedRoles = (context.authorization || {}).roles;
const addRolesToUser = function(user) {
return assignedRoles;
};
const roles = addRolesToUser(user);
user.app_metadata.roles = roles;
auth0.users.updateAppMetadata(user.user_id, user.app_metadata)
.then(function() {
context.idToken['https://schemas.<yourdomain>.com'] = user.app_metadata.roles;
callback(null, user, context);
})
.catch(function (err) {
callback(err);
});
}
你的 startup.cs 应该是这样的:
services.AddAuthorization(options =>
{
options.AddPolicy("Administrator", authBuilder => { authBuilder.RequireRole("Administrator"); });
options.AddPolicy("User", authBuilder => { authBuilder.RequireRole("Administrator", "User"); });
}
例如在控制器中:
[Authorize(Roles = "Administrator, User")]
<<your code>>