2017-07-31 49 views
0

我正在嘗試爲我的大學的網站實現Shibboleth身份驗證。大學使用的Shibboleth認證,它是通過將在.htaccess中啓用:.NET Core 2使用頭的Shibboleth身份驗證中間件

AuthType shibboleth 
ShibRequestSetting requireSession 1 
Require shib-session 

當用戶與大學登錄驗證,該shib用戶的屬性被更新,以反映用戶的身份。我想使用這些信息來生成一個通用主體併爲其分配與該用戶關聯的角色,這些角色存儲在數據庫中。我一直沒有找到關於中間件的很多信息,我不知道如何實現這一點。謝謝!

回答

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,我創建了僞代碼。