我从哪里获得有关当前连接用户的信息?也就是说,shibboleth 是如何传递信息的?
我可以根据从 shibboleth 获取的数据使用 [Authorize] 属性对操作设置一些限制吗?
我从哪里获得有关当前连接用户的信息?也就是说,shibboleth 是如何传递信息的?
我可以根据从 shibboleth 获取的数据使用 [Authorize] 属性对操作设置一些限制吗?
Shibboleth 根据属性接受策略 (1.3.x) 或属性映射 (2.x) 文件中定义的标头名称,将与会话关联的用户属性发布到 HTTP 请求标头中。这些标头根据 CGI 规范定义的映射规则转换为 CGI 变量。
您应该了解此安全公告: http ://shibboleth.net/community/advisories/secadv_20090615.txt
我从来没有使用过 shibboleth,但是您可以从 Controller.User 属性中获取有关用户的信息。它将返回当前线程的通用主体。使用此主体,您可以检查用户是否已通过身份验证并获取用户的登录名。这是因为登录后会设置一个身份验证 cookie,而该 cookie 包含的信息量有限。并且在登录后的每个请求中,仅检查此 cookie(如果它存在且有效 - 用户已通过身份验证)。
因此,如果您需要一些特定信息,您可以手动加载用户(最好在此处使用缓存)并检查您想要的任何内容。
您还可以在请求开始时创建自己的主体并将必要的信息附加到线程(例如,在请求开始时,使用来自基本主体的用户名从 db/cache 加载用户,创建并将您自己的主体设置为线程) . 在此之后,您可以检查您需要的用户的所有属性。
你会把你自己的校长放在哪里?您在请求开始时说,但如果您不希望每个请求都授权怎么办?
您需要在 Global.asax.cs 中创建一个具有以下签名的方法
protected void Application_PostAuthenticateRequest()
{
//Your code here.
}
这将在几乎所有其他操作完成之前自动调用(如果存在,MVC 将调用此方法,您不必在任何地方“打开”它),这就是您需要设置 Principal 的地方。例如,假设您有一个名为的标头,该标头RolesHeader
具有逗号分隔的角色值,另一个标头UserId
具有(duh)用户 ID。
您的代码,没有任何错误处理,可能看起来像:
protected void Application_PostAuthenticateRequest()
{
var rolesheader = Context.Request.Headers["RolesHeader"];
var userId = Context.Request.Headers["UserId"];
var roles = rolesheader.Split(',');
var principal = new GenericPrincipal(new GenericIdentity(userId), roles);
Context.User = principal;
}
它是该[Authorize]
属性使用的 Principal/Identity,因此在请求生命周期开始时将其设置在此处意味着该[Authorize]
属性将正常工作。
其余的都是可选的,但我推荐它:
我喜欢创建自己的自定义类来实现 IPrincipal 和 IIdentity,而不是使用 GenericPrincipal 和 GenericIdentity,因此我可以在其中填充更多用户信息。然后,我的自定义 Principal 和 Identity 对象具有更丰富的信息,例如分支编号或电子邮件地址或其他任何内容。
然后,我创建了一个名为的控制器BaseController
,它具有以下内容
protected new CustomPrincipal User
{
get
{
return (base.User as CustomPrincipal) ?? CustomPrincipal.GetUnauthorizedPrincipal();
}
}
这使我能够访问我所有丰富的自定义 Principal 数据,而不仅仅是 IPrincipal 中定义的数据。然后,我所有的真实控制器都继承自BaseController
而不是直接继承自Controller
.
显然,当使用这样的自定义 Principal 时,在 Application_PostAuthenticateRequest() 方法中,您将 Context.User 设置为 yourCustomPrincipal
而不是GenericPrincipal
.