[英]asp.net MVC authentication with Shibboleth
Shibboleth是一种SSO身份验证,作为“插件”添加到IIS中。 在用户完成登录后,会出现显示Shibboleth会话的标题:ShibSessionID ShibIdentityProvider eppn从属关系权利unscopedaffiliation ...更多
所以我可以从标题中提取用户名和角色。 到目前为止一切都很好
问题:如何实现读取标头并设置用户授权状态的处理程序? 想法是使用[Authorize]属性和Method Roles.IsUserInRole。 全部来自Headers,没有数据库,没有用户管理。
在这个更新中没有什么新东西,只是帮助副本和过去的朋友。 当然,您必须根据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)用户标识。
您的代码没有任何错误处理,可能看起来像:
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,它具有以下功能
protected new CustomPrincipal User
{
get
{
return (base.User as CustomPrincipal) ?? CustomPrincipal.GetUnauthorizedPrincipal();
}
}
这允许我访问所有丰富的自定义Principal数据,而不仅仅是IPrincipal中定义的数据。 然后我的所有真实控制器都从BaseController
继承,而不是直接从Controller
继承。
显然,在使用像这样的自定义Principal时,在Application_PostAuthenticateRequest()方法中,您将Context.User设置为CustomPrincipal
而不是GenericPrincipal
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.