C# identity server应用程序中的自定义MVC控制器中的identity server 3授权

C# identity server应用程序中的自定义MVC控制器中的identity server 3授权,c#,asp.net-mvc,asp.net-identity,owin,identityserver3,C#,Asp.net Mvc,Asp.net Identity,Owin,Identityserver3,我有一个用于SSO的Identity Server 3应用程序。在运行IdentityServer的同一个应用程序中,我集成了Asp.NETMVC控制器用于用户注册等。但是,我有一些没有特定角色就无法访问的方法,我想使用Authorize属性来执行角色检查 根据这个GitHub线程,我已经将所述控制器设置为使用与IdentityServer相同的基本路由,以便进入Owin管道 在线程中有一个属性片段,它通常执行我想要的操作。它对用户进行身份验证并获取他们的一些声明,但问题是缺少许多声明—例如,角

我有一个用于SSO的Identity Server 3应用程序。在运行IdentityServer的同一个应用程序中,我集成了Asp.NETMVC控制器用于用户注册等。但是,我有一些没有特定角色就无法访问的方法,我想使用Authorize属性来执行角色检查

根据这个GitHub线程,我已经将所述控制器设置为使用与IdentityServer相同的基本路由,以便进入Owin管道

在线程中有一个属性片段,它通常执行我想要的操作。它对用户进行身份验证并获取他们的一些声明,但问题是缺少许多声明—例如,角色声明,我需要它才能使Authorize属性起作用。我花了很多时间试图了解为什么会有丢失的索赔,并且真的希望避免查询数据库和自己添加索赔

在我的普通客户端应用程序中,我在ClaimsPrincipal中得到的声明是(iss、aud、exp、nbf、nonce、iat、sid、sub、身份验证时间、idp、首选用户名、电子邮件、电子邮件验证、角色、网站、amr)。正如您将看到的,除了sub和amr之外,其他声明与我在IdentityServer FullLoginAttribute(下面的代码)的帮助下在IdentityServer应用程序中得到的声明完全不同

问题是,即使是可能的,为什么只是检索这些索赔(sub、名称、amr、idp、认证时间、安全戳)

这是我的IdentityServer配置:

coreApp.UseIdentityServer(new IdentityServerOptions
            {
                Factory = factory,
                SigningCertificate = signingCertificate,
                SiteName = "Sitename",
                RequireSsl = true,
                LoggingOptions = new LoggingOptions
                {
                    EnableKatanaLogging = true
                },
                EventsOptions = new EventsOptions
                {
                    RaiseFailureEvents = true,
                    RaiseInformationEvents = true,
                    RaiseSuccessEvents = true,
                    RaiseErrorEvents = true
                },
                CspOptions = new CspOptions
                {
                    Enabled = true,
                    ScriptSrc = "'unsafe-eval' 'unsafe-inline'"
                }
            });
        });
这就是我用来允许用户进行身份验证的属性

public abstract class OwinAuthenticationAttribute : FilterAttribute, IAuthenticationFilter
{
    public string AuthenticationType { get; set; }

    protected OwinAuthenticationAttribute(string authenticationType)
    {
        if (String.IsNullOrWhiteSpace(authenticationType)) throw new ArgumentNullException("authenticationType");

        AuthenticationType = authenticationType;
    }

    public virtual void OnAuthentication(AuthenticationContext filterContext)
    {
        var ctx = filterContext.HttpContext.Request.GetOwinContext();
        var result = AsyncHelper.RunSync(() => ctx.Authentication.AuthenticateAsync(AuthenticationType));
        if (result != null &&
            result.Identity != null &&
            result.Identity.IsAuthenticated)
        {
            filterContext.Principal = new ClaimsPrincipal(result.Identity);
        }
    }

    public abstract void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext);
}

public class IdentityServerFullLoginAttribute : OwinAuthenticationAttribute
{
    public IdentityServerFullLoginAttribute()
        : base(Constants.PrimaryAuthenticationType)
    {
        this.Order = 1;
    }

    public override void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
    {
        var statusCodeResult = filterContext.Result as HttpStatusCodeResult;
        if (statusCodeResult != null && statusCodeResult.StatusCode == 401)
        {
            var ctx = filterContext.HttpContext.Request.GetOwinContext();
            var url = ctx.Environment.CreateSignInRequest(new SignInMessage
            {
                ReturnUrl = filterContext.HttpContext.Request.Url.AbsoluteUri
            });
            filterContext.Result = new RedirectResult(url);
        }
    }
}
这是控制器的动作:

    [HttpGet]
    [Route("core/test/test")]
    [IdentityServerFullLogin]
    [Authorize(Roles = "Administrator")]
    public EmptyResult Test(string signin)
    {
        //return Redirect("~/core/" + IdentityServer3.Core.Constants.RoutePaths.Login + "?signin=" + signin);

        return new EmptyResult();
    }

好的,经过一番努力,我终于找到了一个合适的方法。 我正在OwnAuthenticationAttribute中的OnAuthentication()中检索所需声明,如下所示:

            var userManager = ctx.GetUserManager<ApplicationUserManager>();
            string sub = result.Identity.FindFirst("sub")?.Value;

            if (userManager.SupportsUserClaim)
            {
                result.Identity.AddClaims(await userManager.GetClaimsAsync(sub));
            }

            if (userManager.SupportsUserRole)
            {
                IList<string> roles = await userManager.GetRolesAsync(sub);

                foreach (string roleName in roles)
                {
                    result.Identity.AddClaim(new Claim(IdentityServer3.Core.Constants.ClaimTypes.Role, roleName, ClaimValueTypes.String));
                }
            }
var userManager=ctx.GetUserManager();
string sub=result.Identity.FindFirst(“sub”)?.Value;
if(userManager.SupportsUserClaim)
{
result.Identity.AddClaims(wait userManager.GetClaimsAsync(sub));
}
if(userManager.SupportsUserRole)
{
IList roles=await userManager.GetRolesAsync(sub);
foreach(角色中的字符串roleName)
{
result.Identity.AddClaim(新的声明(IdentityServer3.Core.Constants.ClaimTypes.Role、roleName、ClaimValueTypes.String));
}
}

这满足了我的需要,但我仍然希望有一种方法可以实现这一点,而无需手动添加声明。在这种情况下,这可能吗?