В зависимости от того, какую версию 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.
Большое спасибо, это было очень полезно для общего ADFSv3/OAuth. Одна вещь, которая отсутствует, - это почему 'signInManager.GetExternalLoginInfoAsync' возвращает значение null. –
Для записи: в моем случае 'signInManager.GetExternalLoginInfoAsync' возвращен из-за отсутствия претензий. Тип претензий ADFSv3, похоже, не соответствует стандартным (следовательно, мы должны преобразовать), но даже это может смешать вещи. Итак, вместо следующего: 'context.Identity.AddClaim (new Claim (context.Identity.NameClaimType, Claim.Value));' Мне пришлось использовать: 'context.Identity.AddClaim (new Claim (ClaimTypes) .NameIdentifier, Claim.Value)); ' –