我正在尝试为我的大学的网站实施Shibboleth身份验证。大学使用Shibboleth身份验证,并通过在.htaccess文件中添加以下内容来启用它:
AuthType shibboleth
ShibRequestSetting requireSession 1
Require shib-session
当用户使用大学登录进行身份验证时,会更新shib-user属性以反映用户身份。我想使用此信息生成通用主体,并为其分配与该用户关联的存储在数据库中的角色。我还没有找到关于中间件的大量信息,而且我不知道如何实现这一目标。谢谢!
答案 0 :(得分:0)
您必须编写AuthenticationHandler并添加辅助方法来连接中间件。
这是相同
的伪代码public static class ShibbolethDefaults
{
public const string AuthenticationType = "Shibboleth";
}
public class ShibbolethAuthenticationOptions : AuthenticationOptions
{
/// <summary>
/// Creates an instance of API Key authentication options with default values.
/// </summary>
public ShibbolethAuthenticationOptions()
: base(ShibbolethDefaults.AuthenticationType)
{
}
}
public class ShibbolethAuthenticationHandler : AuthenticationHandler<ShibbolethAuthenticationOptions>
{
private readonly ILogger logger;
public ShibbolethAuthenticationHandler(ILogger logger)
{
this.logger = logger;
}
protected override async Task<Microsoft.Owin.Security.AuthenticationTicket> AuthenticateCoreAsync()
{
var properties = new AuthenticationProperties();
// Find Shibboleth in default location
string Shibboleth = null;
//am not sure what header is to be checked for Shibboleth
string authorization = Request.Headers.Get("Authorization");
if (!string.IsNullOrEmpty(authorization))
{
if (authorization.StartsWith("Shibboleth ", StringComparison.OrdinalIgnoreCase))
{
Shibboleth = authorization.Substring("Shibboleth ".Length).Trim();
}
else
{
this.logger.WriteInformation("Authorization skipped.");
return new AuthenticationTicket(null, properties);
}
}
else
{
this.logger.WriteWarning("Authorization header not found");
return new AuthenticationTicket(null, properties);
}
//here you can read from the headers and add each claims
var nameClaim = new Claim(ClaimTypes.Name, HttpContext.Current.Request.Headers["principalName"]);
var givenClaim = new Claim(ClaimTypes.GivenName, HttpContext.Current.Request.Headers["givenName"]);
var surnameClaim = new Claim(ClaimTypes.SurName, HttpContext.Current.Request.Headers["surname"]);
var emailClaim = new Claim(ClaimTypes.Email, HttpContext.Current.Request.Headers["email"]);
var allClaims = Enumerable.Concat(new Claim[] { nameClaim,givenClaim,surnameClaim,emailClaim }, Enumerable.Empty<Claim>());
var identity = new ClaimsIdentity(allClaims, ShibbolethDefaults.AuthenticationType);
var principal = new ClaimsPrincipal(new ClaimsIdentity[] { identity });
// resulting identity values go back to caller
return new AuthenticationTicket(identity, properties);
}
}
public class ShibbolethAuthenticationMiddleware : AuthenticationMiddleware<ShibbolethAuthenticationOptions>
{
private readonly ILogger logger;
public ShibbolethAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, ShibbolethAuthenticationOptions options)
: base(next, options)
{
this.logger = app.CreateLogger<AuthenticationHandler>();
}
protected override AuthenticationHandler<ShibbolethAuthenticationOptions> CreateHandler()
{
return new ShibbolethAuthenticationHandler(logger);
}
}
public static class ShibbolethAuthenticationExtensions
{
public static IAppBuilder UseShibbolethAuthentication(this IAppBuilder app, ShibbolethAuthenticationOptions options = null)
{
if (app == null)
{
throw new ArgumentNullException("app");
}
app.Use(typeof(ShibbolethAuthenticationMiddleware), app, options != null ? options : new ShibbolethAuthenticationOptions());
app.UseStageMarker(PipelineStage.Authenticate);
return app;
}
}
请参考我创建伪代码的SO post。