我有一个 FubuMvc 网站,它使用来自 WIF 单点登录服务器的基于声明的授权。身份验证发生在 SSO 上,包括角色和一组自定义声明在内的声明被传递到网站进行授权。
SSO 和网站与基于角色的授权一样工作正常,但我想要做的是拒绝访问整个站点,并根据缺少自定义声明保存错误页面。目前,我正在使用一种习惯ClaimsAuthenticationManager
来检查索赔并检查是否存在所需的索赔。如果缺少声明,则会引发异常。这会导致 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 错误。也因为用户本质上是登录的,但他们没有访问权限,他们无法注销。我暴露了一个未经授权的错误页面,它提供对匿名用户的访问,但我还没有办法重定向用户。