2017-02-14 42 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));' –