2017-02-14 90 views
1

我工作的ASP.Net項目,該項目需要在PaaS的,這就需要將BlueMix完成後要部署完成後(這WASN我的選擇,這是一個命令)。
此外,我需要使用:集成ASP.NET代碼到Active Directory或LDAP部署上Bluemix

Active Directory或LDAP的用戶認證和授權,與ASP.Net項目集成。

的問題這裏有:
1.我發現了一個集成到Active Directory或只使用Java或Node.js的SSO服務,但對我來說,我使用ASP。 Net
2.我想要一個如何在Active Directory和ASP.Net應用程序之間的PaaS之上完成集成的解決方案。

回答

3

根據您使用的ADFS版本,您應該能夠使用OAuth或OIDC中間件從ASP.NET Core應用程序進行連接(假設您使用的是ASP.NET Core,因爲您是使用Bluemix)。如果您至少使用ADFS 3.0(Windows Server 2012+),則可以使用ASP.NET Core的通用OAuth中間件進行連接。

首先,創建一個配置文件來存儲您的ADFS服務器設置或修改現有配置文件(如appsettings.json)。

樣本 「ADFS-settings.json」 文件:

{ 
    "ADFS": { 
    "ClientId": "Your ClientId as set on ADFS server", 
    "ResourceUrl": "url of this application (ex: http://mywebapp.mybluemix.net)", 
    "ServerUrl": "url of ADFS (ex: https://dc.your.domain)" 
    } 
} 

如果您創建一個新的文件,如 「ADFS-settings.json」,爲您的ADFS配置,它添加到您的Configuration對象Startup.cs文件的構造函數。

public Startup(IHostingEnvironment env) 
{ 
    var builder = new ConfigurationBuilder() 
     .SetBasePath(env.ContentRootPath) 
     .AddJsonFile("adfs-settings.json"); 
    Configuration = builder.Build(); 
} 

在你Startup.cs的Configure方法創建一個OAuthOptions對象:

var options = new OAuthOptions(); 
options.AutomaticChallenge = true; 
options.AuthenticationScheme = "ADFS"; 

指定您從您的Configuration對象中讀取它配置您的服務器ADFS這個應用程序時創建的ClientId。通用OAuth中間件也要求您在這裏提供ClientSecret,即使該值實際上並未被ADFS 3.0使用。

options.ClientId = Configuration["ADFS:ClientId"]; 
options.ClientSecret = "ADFS 3.0 does not support confidential client, but OAuth middleware requires it"; 

設置ADFS服務器將在您的應用程序中重定向到的回調url。

options.CallbackPath = new PathString("/signin-adfs"); 

現在配置OAuthEventsOnRedirectToAuthorizationEndpoint定義了當應用程序確定需要授權用戶時傳遞給ADFS授權端點的參數。這將需要至少一個resource參數指向您的應用程序的URL。當ADFS服務器完成對客戶端的授權並將包含聲明數據的JWT令牌返回給應用程序時,會觸發OnCreatingTicket。在這種方法中,您需要處理向HttpContext對象添加角色和聲明。

options.Events = new OAuthEvents { 
    OnRedirectToAuthorizationEndpoint = context => 
    { 
     var parameter = new Dictionary<string, string> 
      { 
       ["resource"] = Configuration["ADFS:ResourceUrl"] 
      }; 
     var query = QueryHelpers.AddQueryString(context.RedirectUri, parameter); 
     context.Response.Redirect(query); 
     return Task.CompletedTask; 
    }, 
    OnCreatingTicket = context => { 
     JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler(); 
     JwtSecurityToken validatedToken = tokenHandler.ReadJwtToken(context.AccessToken); 
     IEnumerable<Claim> a = validatedToken.Claims; 

     foreach (var claim in a) 
     { 
      // role claim needs to be mapped to http://schemas.microsoft.com/ws/2008/06/identity/claims/role 
      // for IsInRole() to work properly 
      if (claim.Type == "role") 
      { 
       context.Identity.AddClaim(new Claim(ClaimTypes.Role, claim.Value)); 
      } 
      else if (claim.Type == "unique_name") 
      { 
       // map name to Identity.Name 
       context.Identity.AddClaim(new Claim(context.Identity.NameClaimType, claim.Value)); 
      } 
      else 
      { 
       // this is optional, if you want any other specific claims from Active Directory 
       // this will also include some information about the jwt token such as the issue 
       // and expire times 
       context.Identity.AddClaim(new Claim(claim.Type, claim.Value)); 
      } 
     } 

     return Task.CompletedTask; 
     } 
    }; 

接下來,設置ClaimsIssuer到ADFS URL,並設置SignInSchemeCookieAuthenticationDefaults.AuthenticationScheme和您的ADFS服務器上配置AuthorizationEndpointTokenEndpoint到合適的端點。

options.ClaimsIssuer = Configuration["ADFS:ServerUrl"]; 
    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; 
    options.AuthorizationEndpoint = Configuration["ADFS:ServerUrl"] + "/adfs/oauth2/authorize/"; 
    options.TokenEndpoint = Configuration["ADFS:ServerUrl"] + "/adfs/oauth2/token/"; 

最後,使用您剛纔創建的選項添加OAuth的中間件:

app.UseCookieAuthentication(new CookieAuthenticationOptions()); 
    app.UseOAuthAuthentication(options); 

現在,你應該能夠在[Authorize]屬性適用於任何控制器或動作需要授權與ADFS。有關完整的示例應用程序,請參閱this GitHub repo

+0

非常感謝,這對通用的ADFSv3/OAuth非常有用。缺少的一件事就是爲什麼'signInManager.GetExternalLoginInfoAsync'返回null。 –

+0

對於記錄:在我的情況下,'signInManager.GetExternalLoginInfoAsync'返回,因爲缺少索賠。 ADFSv3聲明類型似乎不遵循標準聲明(因此我們必須進行轉換),但即使這樣也會混淆。所以,而不是以下內容: 'context.Identity.AddClaim(new Claim(context.Identity.NameClaimType,claim.Value));' 我必須使用: 'context.Identity.AddClaim(new Claim(ClaimTypes .NameIdentifier,claim.Value));' –