gpt4 book ai didi

asp.net - 根据 Claim 允许或拒绝访问整个站点

转载 作者:行者123 更新时间:2023-12-02 05:25:25 24 4
gpt4 key购买 nike

我有一个 FubuMvc 网站,它使用来自 WIF 单点登录服务器的基于声明的授权。身份验证发生在 SSO 上,包括角色和一组自定义声明的声明被传递到网站以进行授权。

SSO 和网站与基于角色的授权一样工作正常,但我想做的是拒绝访问整个网站,并根据缺少自定义声明保存错误页面。目前我正在使用自定义 ClaimsAuthenticationManager它检查 claim 并检查所需 claim 的存在。如果声明丢失,它会抛出异常。这会导致 500 错误,但我真正想要的是系统抛出 401 错误并重定向到网站上的“未授权”页面。

以下是自定义 ClaimsAuthenticationManager 的示例。

public class CustomAuthenticationManager : ClaimsAuthenticationManager
{
private readonly string expectedClaim;

public CustomAuthenticationManager (object config)
{
var nodes = config as XmlNodeList;
foreach (XmlNode node in nodes)
{
using (var stringReader = new StringReader(node.OuterXml))
using (var rdr = new XmlTextReader(stringReader))
{
rdr.MoveToContent();
rdr.Read();
string claimType = rdr.GetAttribute("claimType");
if (claimType.CompareTo(ClaimTypes.CustomClaim) != 0)
{
throw new NotSupportedException("Only custom claims are supported");
}
expectedSystemName = rdr.GetAttribute("customClaimValue");
}
}
}

public override IClaimsPrincipal Authenticate(
string resourceName, IClaimsPrincipal incomingPrincipal)
{
var authenticatedIdentities = incomingPrincipal.Identities.Where(x => x.IsAuthenticated);
if (authenticatedIdentities.Any() &&
authenticatedIdentities.Where(x => x.IsAuthenticated)
.SelectMany(x => x.Claims)
.Where(x => x.ClaimType == ClaimTypes.CustomClaim)
.All(x => x.Value != expectedClaim))
{
throw new HttpException(
(int)HttpStatusCode.Unauthorized,
"User does not have access to the system");
}
return base.Authenticate(resourceName, incomingPrincipal);
}
}

上面的方法有效并阻止了对系统的访问,但 ti 不是很友好,因为用户只会收到 500 错误。此外,因为用户基本上已登录,但没有访问权限,所以他们无法注销。我公开了一个未经授权的错误页面,该页面提供对匿名用户的访问权限,但我还没有办法重定向用户。

最佳答案

我想知道为什么您在身份验证管理器中实现了您的逻辑。

您是否考虑过改用 ClaimsAuthorizationManager ?为此,您需要添加 ClaimsAuthorizationModule到您的管道:

 <system.webServer>
<modules>
...
<add name="SessionAuthenticationModule" ....
<add name="ClaimsAuthorizationModule" type="Microsoft.IndentityModel.Web.ClaimsAuthorizationModule, Microsoft.IndentityModel.Web" />
</modules>
</system.webServer>

然后您创建授权角色的结构:

 <claimsAuthorizationManager type="yourtype, yourassembly">
<requiredClaim claimType="foobar" />
</claimsAuthorizationManager>

在管理器中:

public class FederatedClaimsAuthorizationManager : ClaimsAuthorizationManager
{
private List<string> _requiredClaims = new List<string>();

public FederatedClaimsAuthorizationManager( object config )
{
XmlNodeList nodes = config as XmlNodeList;
foreach ( XmlNode node in nodes )
{
XmlTextReader xtr = new XmlTextReader( new StringReader( node.OuterXml ) );
xtr.MoveToContent();

_requiredClaims.Add( xtr.GetAttribute( "claimType" ) );
}
}

public override bool CheckAccess( AuthorizationContext context )
{
IClaimsIdentity identity = context.Principal.Identities[0];

return !identity.IsAuthenticated ||
identity.Claims.Any( c => _requiredClaims.Any( rq => c.ClaimType == rq ) );
}
}

此方法与您的方法之间的区别在于,失败的授权仅通过重新调用身份验证过程来处理 - 没有异常(exception),没有 500。

例如 - 如果您使用 <wif:FederatedPassiveSignIn />在登录页面上,失败的授权只是将用户重定向到登录页面,您可以在其中检查用户是否已通过身份验证并显示消息“您被重定向到登录页面,这可能意味着您试图访问您未访问的资源有权访问”。

关于asp.net - 根据 Claim 允许或拒绝访问整个站点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13158066/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com