C# identity server应用程序中的自定义MVC控制器中的identity server 3授权
我有一个用于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配置: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管道 在线程中有一个属性片段,它通常执行我想要的操作。它对用户进行身份验证并获取他们的一些声明,但问题是缺少许多声明—例如,角
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));
}
}
这满足了我的需要,但我仍然希望有一种方法可以实现这一点,而无需手动添加声明。在这种情况下,这可能吗?