Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何避免Asp.NET Core中某些请求的声明转换_C#_Asp.net Core_Claims Based Identity_Identityserver4_Claims - Fatal编程技术网

C# 如何避免Asp.NET Core中某些请求的声明转换

C# 如何避免Asp.NET Core中某些请求的声明转换,c#,asp.net-core,claims-based-identity,identityserver4,claims,C#,Asp.net Core,Claims Based Identity,Identityserver4,Claims,在API级别,我有一些来自identity Server的身份声明用于授权当前用户,我可以使用一些用于第一级授权。但在下一步中,对于额外的权限检查,这些声明是不够的,我必须从数据库中检索更多数据 我的想法是创建一个定制的ClaimsPrincipal,在这里我附加了数据库中的所有权限,但我不想每次请求调用数据库超过一次 因此,我想拥有自己的Microsoft.AspNetCore.Authentication.iclaimsstransformer实现,我将其添加到管道中,如下所示: app.U

在API级别,我有一些来自identity Server的身份声明用于授权当前用户,我可以使用一些用于第一级授权。但在下一步中,对于额外的权限检查,这些声明是不够的,我必须从数据库中检索更多数据

我的想法是创建一个定制的
ClaimsPrincipal
,在这里我附加了数据库中的所有权限,但我不想每次请求调用数据库超过一次

因此,我想拥有自己的
Microsoft.AspNetCore.Authentication.iclaimsstransformer
实现,我将其添加到管道中,如下所示:

app.UseClaimsTransformation(new ClaimsTransformationOptions() 
{
   Transformer = new MyClaimsTransformer() 
});
我目前的转换方法是:

public Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context)
{
    if (context.Principal.Identity.IsAuthenticated)
    {
        var principal = new MyClaimsPrincipal(context.Principal);
        principal.Permissions = /* load from db */;
        return Task.FromResult<ClaimsPrincipal>(principal);
     }
     return Task.FromResult(context.Principal);
}
public Task TransformAsync(claimtransformationcontext)
{
if(context.Principal.Identity.IsAuthenticated)
{
var principal=新的MyClaimsPrincipal(context.principal);
principal.Permissions=/*从db*/加载;
返回任务.FromResult(主体);
}
返回Task.FromResult(context.Principal);
}
我已经注意到索赔转换方法在每次请求时都被调用。因此,我希望能够控制它,以避免在没有经过身份验证的用户或不需要授权(在
AllowAnonymous
属性的情况下)以及不需要额外的权限检查(理想情况下)时调用数据库

我觉得声明转换应该绑定到Identity Server的授权或其他东西,但不知道如何绑定

有什么想法吗?谢谢大家!


Edit我发现我可以从
IdentityServer 4.AccessTokenValidation
将声明转换挂接到
OnTokenValidated
JWTBeareEvents
部分。不幸的是,还有另一个未知的中间件正在覆盖
MyClaimsPrincipal
。我对它的工作原理感到困惑。

您可以在您的ClaimsTransformer中使用以下检查来测试匿名访问

using System.Security.Claims;
using System.Web;
using System.Web.Security;

private bool IsAnonymousAccessAllowed => UrlAuthorizationModule.CheckUrlAccessForPrincipal(
    HttpContext.Current.Request.Path, 
    AnonymousClaimsPrincipal, 
    HttpContext.Current.Request.RequestType
);
AnonymousClaimsPrincipal
as

ClaimsPrincipal AnonymousClaimsPrincipal => new ClaimsPrincipal(
    (IIdentity) new ClaimsIdentity(
        (IEnumerable<Claim>) new List<Claim>() {
             new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", "")
        }
    )
);

(这段代码来自一个MVC5项目,我希望它也能在.net core中工作。)

这很有用。。但我实际上找到了将声明转换挂接到的最佳位置(请参见编辑)。。虽然我无法在那里创建我自己的
ClaimsPrincipal
,但我正在考虑创建我自己的
ClaimsIdentity
来附加额外的数据to@Learner您可以轻松地将extensionmethod添加到ClaimsPrincipal或ClaimSideEntity,而不是提供您自己的标识class@Quetzalcoatl但我想附上一个完整的物体,不仅是额外的声明,所以我设法创建了自己的标识,将其添加到
标识中
,然后在授权处理程序中对该对象执行检查
if (!IsAnonymousAccessAllowed && context.Principal.Identity.IsAuthenticated) { /* ... */ }