【发布时间】:2015-04-27 09:17:49
【问题描述】:
Shibboleth 是作为“插件”添加到 IIS 的 SSO 身份验证。 用户完成登录后,会出现显示 Shibboleth 会话的标题: ShibSessionID ShibIdentityProvider eppn 联系 权利 无范围的从属关系 ...更多
所以我可以从标题中提取用户名和角色。 到目前为止一切顺利。
问题: 如何实现一个处理程序来读取标头并设置用户被授权的状态? 想法是使用 [授权] 属性和方法 角色.IsUserInRole。 全部来自标头,没有数据库,没有用户管理。
更新
根据@Pharylon 的回答实现
在本次更新中没有什么新内容,只是对副本和过去朋友的帮助。 当然,您必须根据您的 Shibboleth 设置调整属性和 Header 字段名。
文件:ShibbolethPrincipal.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security.Principal; //GenericPrincipal
namespace Shibboleth
{
public class ShibbolethPrincipal : GenericPrincipal
{
public string username
{
get { return this.Identity.Name.Replace("@ksz.ch", ""); }
}
public string firstname
{
get { return HttpContext.Current.Request.Headers["givenName"]; }
}
public string lastname
{
get { return HttpContext.Current.Request.Headers["surname"]; }
}
public string phone
{
get { return HttpContext.Current.Request.Headers["telephoneNumber"]; }
}
public string mobile
{
get { return HttpContext.Current.Request.Headers["mobile"]; }
}
public string entitlement
{
get { return HttpContext.Current.Request.Headers["eduzgEntitlement"]; }
}
public string homeOrganization
{
get { return HttpContext.Current.Request.Headers["homeOrganization"]; }
}
public DateTime birthday
{
get
{
DateTime dtHappy = DateTime.MinValue;
try
{
dtHappy = DateTime.Parse(HttpContext.Current.Request.Headers["dateOfBirth"]);
}
finally
{
}
return dtHappy;
}
set {}
}
public ShibbolethPrincipal()
: base(new GenericIdentity(GetUserIdentityFromHeaders()), GetRolesFromHeader())
{
}
public static string GetUserIdentityFromHeaders()
{
//return HttpContext.Current.Request.Headers["eppn"];
return HttpContext.Current.Request.Headers["principalName"];
}
public static string[] GetRolesFromHeader()
{
string[] roles = null;
//string rolesheader = HttpContext.Current.Request.Headers["affiliation"];
string rolesheader = HttpContext.Current.Request.Headers["eduzgEntitlement"];
if (rolesheader != null)
{
roles = rolesheader.Split(';');
}
return roles;
}
}
}
文件:ShibbolethController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Shibboleth
{
public class ShibbolethController : Controller
{
protected new ShibbolethPrincipal User
{
get
{
return (base.User as ShibbolethPrincipal) ?? null; //CustomPrincipal.GetUnauthorizedPrincipal();
}
}
}
}
文件:Global.asax
void Application_PostAuthenticateRequest(object sender, EventArgs e)
{
var ctx = HttpContext.Current;
var principal = new ShibbolethPrincipal();
HttpContext.Current.User = principal;
}
使用例子:
namespace itservices.Controllers
{
[Authorize] //examples : [Authorize(Roles="Administrators")], [Authorize(Users="Alice,Bob")]
public class PasswordMailController : ShibbolethController
{
if(User.IsInRole("staff"))
{
【问题讨论】:
-
您是否尝试创建一个动作过滤器并在 OnActionExecuting 方法中进行此处理? msdn.microsoft.com/en-us/library/dd381609%28v=vs.100%29.aspx
-
我认为最好在开始处理请求时设置主体/身份,以便正常的授权过滤器和方法工作。
-
@RazvanDumitru - ActionFilters 执行 AFTER 授权过滤器,它们没有用
-
很高兴我能帮上忙。不过,我建议 ShibbolethController 的 User 永远不要返回 null 对象。您不希望 User.Identity.IsAuthenticated 引发异常 - 它应该是检查用户是否有效的可靠方法。此外,您应该在实例化时设置 Principal 的值(我喜欢将其设为不可变对象)。否则,如果你让单元测试不断调用 HttpContext.Current,你将很难进行单元测试。
-
你好法里伦。朱普,有道理。我也在为 UnauthorizedPrincipal 进行更改。谢谢
标签: c# asp.net-mvc shibboleth