使用Shibboleth进行asp.net MVC身份validation
Shibboleth是一种SSO身份validation,它作为“插件”添加到IIS中。 在用户完成登录后,会出现显示Shibboleth会话的标题:ShibSessionID ShibIdentityProvider eppn从属关系权利unscopedaffiliation …更多
所以我可以从标题中提取用户名和角色。 到目前为止一切都很好
问题:如何实现读取标头并设置用户授权状态的处理程序? 想法是使用[Authorize]属性和Method Roles.IsUserInRole。 全部来自Headers,没有数据库,没有用户管理。
更新
实施根据@Pharylon的回答
在这个更新中没有什么新东西,只是副本和过去的朋友的帮助。 当然,您必须根据Shibboleth设置调整属性和标题字段名称。
文件: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")) {
您将要在Global.asax.cs中创建具有以下签名的方法
protected void Application_PostAuthenticateRequest() { //Your code here. }
这将在几乎所有其他事情完成之前自动调用(MVC将调用此方法,如果它存在,您不必在任何地方“打开”),这是您需要设置Principal的地方。 例如,假设您有一个名为RolesHeader
的标头,该标头具有逗号分隔的角色值,另一个名为UserId
标头具有(duh)用户标识。
您的代码没有任何error handling,可能看起来像:
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
的Controller,它具有以下function
protected new CustomPrincipal User { get { return (base.User as CustomPrincipal) ?? CustomPrincipal.GetUnauthorizedPrincipal(); } }
这允许我访问所有丰富的自定义Principal数据,而不仅仅是IPrincipal中定义的数据。 然后我的所有真实控制器都从BaseController
inheritance,而不是直接从Controller
inheritance。
显然,在使用这样的自定义Principal时,在Application_PostAuthenticateRequest()方法中,您将Context.User设置为CustomPrincipal
而不是GenericPrincipal
。
- Asp.Net Web API中带字典参数的方法
- ASP.NET MVC消息处理程序与Web API消息处理程序
- 使用Instagram API在.NET中使用OAuth 2.0
- Intranet – Web到远程wcf CredentialCache.DefaultNetworkCredentials无法正常工作
- Service Stack / MVC:“AppHostBase.Instance已设置”错误 – 但无法理解为什么/如何防止
- 我可以遍历Collection.Request.Form吗?
- 在自定义AuthorizeAttribute中访问QueryString
- 不完全日期的策略
- ASP.NET MVC +填充下拉列表