2017-02-14 22 views
1

Я работаю над проектомASP.Net, который должен быть развернут после завершения на PaaS, который должен быть BlueMix (Это WASN Мой выбор, это был приказ).
Кроме того, я должен использовать:
Интеграция кода ASP.NET в Active Directory или LDAP после развертывания на Bluemix

Active Directory или LDAP для аутентификации и авторизации пользователей, интегрированный с проектом ASP.Net.

проблемы касаются:
1. Я нашел интеграцию в Active Directory или SSO услуги с использованием только Java или Node.js, но в моем случае я использую ASP. Net
2. Я хочу решить, как интеграция может быть выполнена поверх PaaS между Active Directory и ASP.Net-приложением.

ответ

3

В зависимости от того, какую версию ADFS вы используете, вы должны использовать либо OAuth, либо промежуточное ПО OIDC для подключения из приложения ASP.NET Core (при условии, что вы используете ASP.NET Core, потому что вы используя Bluemix). Если вы используете, по крайней мере, ADFS 3.0 (Windows Server 2012+), вы можете использовать стандартное промежуточное программное обеспечение OAuth для ASP.NET для подключения.

Сначала создайте файл конфигурации для хранения настроек сервера 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(); 
} 

В вашем Configure метода Startup.cs создать OAuthOptions объект:

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

Укажите ClientId, созданные при настройке этого приложения на вашем сервере ADFS, читая его из Configuration объекта. Обычное промежуточное ПО 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 в приложение.

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

Теперь настройте OAuthEvents. OnRedirectToAuthorizationEndpoint определяет параметры, которые передаются в конечную точку авторизации ADFS, когда приложение определяет, что пользователь должен быть авторизован. Для этого потребуется по крайней мере параметр resource, который указывает на URL-адрес вашего приложения. OnCreatingTicket запускается, когда сервер ADFS завершил авторизацию клиента и возвращает токен JWT, содержащий данные претензий, в ваше приложение. В этом методе вам необходимо обработать добавление ролей и претензий к объекту 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 в URL ADFS и установите SignInScheme в CookieAuthenticationDefaults.AuthenticationScheme и настроить AuthorizationEndpoint и TokenEndpoint в соответствующих конечных точек на вашем ADFS сервере.

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)); ' –