.net Core Api аутентификация с ADFS 2012

Мне нужно настроить мой .Net Core Web Api (.Net Framework) для использования ADFS 3.0 (2012) для проверки токенов-носителей, отправленных нашими мобильными клиентами.

Я могу сгенерировать access_token с сервера ADFS и передать его в заголовке авторизации.

Моя проблема в API: как мне настроить его для проверки и авторизации пользователя?

Я искал во многих местах и ​​не мог найти окончательного способа сделать это.

Что я пробовал до сих пор:

Используется IdentityServer4 (сбой, потому что он использует JWT, а ADFS не предлагает OpenID Tried UseOpenIdConnectAuthentication (пример найден на IdentityServer4) настраиваемое промежуточное ПО. Я не могу использовать другой метод, мне нужно поддерживать oAuth2.

Итак, как мне это сделать?

Вот моя последняя попытка:

    var connectOptions = new OpenIdConnectOptions
    {
        AuthenticationScheme = "adfs",
        SignInScheme = "idsrv.external", //IdentityServerConstants.ExternalCookieAuthenticationScheme,
        SignOutScheme = "idsrv", //IdentityServerConstants.SignoutScheme,
        AutomaticChallenge = false,
        DisplayName = "ADFS",
        Authority = $"https://{options.AdfsHostName}/adfs/oauth2",
        ClientId = options.ClientID,
        ResponseType = "id_token",
        Scope = { "openid profile" },
        CallbackPath = new PathString("/signin-adfs"),
        SignedOutCallbackPath = new PathString("/signout-callback-adfs"),
        RemoteSignOutPath = new PathString("/signout-adfs"),
        ClaimsIssuer = $"https://{options.AdfsHostName}/adfs/services/trust",
        //TokenValidationParameters = new TokenValidationParameters
        //{
        //    ValidateIssuer = true,
        //    ValidIssuer = $"https://{options.AdfsHostName}/adfs/services/trust"
        //},

    };

    app.UseOpenIdConnectAuthentication(connectOptions);

Я очень быстро получаю 401 при каждом вызове с действующим токеном. Фактически, хотя я вижу соединение в окне консоли, я не вижу другого журнала в окне консоли Roslyn, касающегося проверки безопасности.

В настоящее время я использую ASP.Net Core 1.1.X, и если смогу, я бы не стал переходить на .Net Core 2.0, так как мы опаздываем в проекте, и он содержит много критических изменений ...

Не стесняйтесь спрашивать дополнительную информацию, и я буду признателен за все хорошие советы!


person JS Petit    schedule 30.11.2017    source источник


Ответы (2)


Как оказалось, мы можем использовать JwtBearerAuthentication с ADFS 3.0.

Моя первоначальная проблема заключалась в том, что он отправлял метаданные в /.well-known/openid-configuration, но ADFS 3.0 не поддерживает OpenID, и это возвращает 404.

Я читал в другом сообщении (обновлю его, когда найду), что при правильной конфигурации не нужно будет получать конфигурацию. Но какая конфигурация?

Я обнаружил глубоко в (MS) коде, что если передать объект OpenIdConnectConfiguration в свойство Configuration JwtBearerOptions, он не получит метаданные.

Итак, вот мой код:

var rawCertData = Convert.FromBase64String(options.X509SigninCertificate);

X509Certificate2 cert = new X509Certificate2(rawCertData);

SecurityKey signingKey = new X509SecurityKey(cert);

Данные сертификата X509 поступают из поддерживаемых метаданных adfs по этому URL-адресу.

https://Your.ADFS.Site/FederationMetadata/2007-06/FederationMetadata.xml 

Он содержит это:

<KeyDescriptor use="signing">
    <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
        <X509Data>
            <X509Certificate>SOMEUUENCDODEDSTRING=</X509Certificate>
        </X509Data>
    </KeyInfo>
</KeyDescriptor>

Я просто скопировал строку UUEncoded в свойство X509SigninCertificate своих настроек.

var tokenValidationParameters = new TokenValidationParameters
        {
            // The signing key must match!
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = signingKey,

            // Validate the JWT Issuer (iss) claim
            ValidateIssuer = true,
            ValidIssuer = $"https://{options.AdfsHostName}/adfs/services/trust",

            // Validate the JWT Audience (aud) claim
            ValidateAudience = true,
            ValidAudience = options.ClientUri, //"https://YOUR-AUDIENCE/",

            // Validate the token expiry
            ValidateLifetime = true,


            // If you want to allow a certain amount of clock drift, set that here:
            ClockSkew = TimeSpan.Zero
        };

        var connectOptions = new OpenIdConnectConfiguration
        {
            Issuer = $"https://{options.AdfsHostName}/adfs/services/trust",
        };

        app.UseJwtBearerAuthentication(new JwtBearerOptions
        {
            AutomaticAuthenticate = true,
            AutomaticChallenge = true,
            TokenValidationParameters = tokenValidationParameters,
            Configuration = connectOptions                
        });

Важная линия здесь

Configuration = connectOptions

Делая это, вы говорите валидатору не извлекать метаданные. Просто как тот.

Мне удалось проверить свой токен (AUD, ISS и SIGN), и я могу использовать ADFS в своем проекте.

person JS Petit    schedule 01.12.2017
comment
Здравствуйте, я работаю над защитой api с помощью adfs и IdentityServer. Есть ли у вас какие-либо советы по использованию IdentityServer для проверки учетных данных и предоставления токена доступа? Я хочу, чтобы эта конечная точка была в моем API, чтобы мобильное приложение могло передавать мне имя пользователя и пароль. Есть какие-нибудь советы по этому поводу? - person Connor Williams; 08.03.2019
comment
В конце концов, я не стал использовать IdentityServer, так как смог обойти часть OpenId ... С ADFS взаимодействует наше мобильное приложение, а не наш сервис. Наш сервис проверяет только токен oAuth. - person JS Petit; 09.03.2019
comment
Возможно, вы можете посмотреть в документации / коде IdentitySertver способ обойти вызов OpenID, который обычно используется для получения сертификата и другой информации. - person JS Petit; 09.03.2019

Только ADFS 2016 поддерживает OpenID Connect. Если вы хотите использовать конечную точку OAuth в 2012 году, вам необходимо написать собственный обработчик авторизации. Примером для использования может быть person Martin Ullrich    schedule 30.11.2017