Смущает аутентификация Graph API на ASP. Net MVC - PullRequest
1 голос
/ 27 января 2020

Я не могу понять это. Я смущен всем процессом аутентификации. Существует так много жаргона - токены, коды авторизации, идентификаторы, учетные записи, арендаторы, субъекты заявок, области действия, клиентские приложения, OWIN, OpenID, MSAL, ADAL, Azure, AD, Office365, Graph API и др. c. И это менялось несколько раз, так что шансы на то, что документация, на которую я смотрю, не относится даже к текущей версии!

Я рассмотрю свою текущую проблему, но я ищу некоторую общую помощь, так как хорошо. Для аутентификации сайта у меня есть некоторый код в моем классе запуска, который инициализирует аутентификацию для сайта:

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

app.UseCookieAuthentication(new CookieAuthenticationOptions { CookieManager = new SystemWebCookieManager() });

string authority = string.Format(CultureInfo.InvariantCulture, aadInstance, tenant);

app.UseOpenIdConnectAuthentication(
    new OpenIdConnectAuthenticationOptions
    {
        ClientId = clientID,
        Authority = authority,

        Notifications = new OpenIdConnectAuthenticationNotifications()
        {
            // when an auth code is received...
            AuthorizationCodeReceived = OnAuthorizationCodeReceivedAsync,
            AuthenticationFailed = (context) =>
            {
                context.HandleResponse();
                return Task.FromResult(0);
            }
        }
    });

Я думаю, что это обрабатывает отправку пользователя для входа в систему. Тогда (я думаю ?!) Microsoft отправляет обратно код авторизации, который обрабатывается здесь:

private async Task OnAuthorizationCodeReceivedAsync(AuthorizationCodeReceivedNotification notification)
{
    var idClient = ConfidentialClientApplicationBuilder.Create(clientID)
        .WithAuthority(AzureCloudInstance.AzurePublic, tenant)
        .WithRedirectUri(notification.Request.Uri.AbsoluteUri)
        .WithClientSecret(clientSecret)
        .Build();

    var signedInUser = new ClaimsPrincipal(notification.AuthenticationTicket.Identity);
    var tokenStore = new MemoryTokenStore(idClient.UserTokenCache, HttpContext.Current, signedInUser);

    try
    {
        string[] scopes = graphScopes.Split(' ');

        var result = await idClient.AcquireTokenByAuthorizationCode(scopes, notification.Code).ExecuteAsync();

        var graphClient = new GraphServiceClient(
            new DelegateAuthenticationProvider(
                async (requestMessage) => {
                    requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
                }));

        // Grab and cache user details...
    }
    catch (Exception ex) 
    {
        // Handle exception...
    }
}

Затем в моих контроллерах я украшаю безопасные действия с помощью [Authorize]. Я считаю, что все вышеперечисленное работает правильно. Я не совсем понимаю, что он делает, но я могу войти и просмотреть безопасные действия. У меня проблемы с доступом к API Graph в действии:

public async Task<GraphServiceClient> GetAuthenticatedClient()
{
    var idClient = ConfidentialClientApplicationBuilder.Create(clientID)
        .WithAuthority(AzureCloudInstance.AzurePublic, tenant)
        .WithRedirectUri(HttpContext.Request.Url.AbsoluteUri)
        .WithClientSecret(clientSecret)
        .WithLogging(writeToLog, LogLevel.Verbose, true)
        .Build();

    var tokenStore = new MemoryTokenStore(idClient.UserTokenCache, HttpContext, ClaimsPrincipal.Current);

    var accounts = await idClient.GetAccountsAsync();

    var scopes = graphScopes.Split(' ');
    var result = await idClient.AcquireTokenSilent(scopes, accounts.FirstOrDefault()).ExecuteAsync();

    return new GraphServiceClient(
        new DelegateAuthenticationProvider(
            async (requestMessage) => {
                requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
            }
        )
    );
}

Я делаю то же самое, что и при аутентификации сайта, но так как у меня нет кода авторизации, я ' Я пытаюсь использовать AcquireTokenSilent. Но для этого требуется идентификатор, который из прочитанных мною учебников сказал, что я должен получать из ConfidentialClientApplication, как показано. Но в большинстве случаев я получаю ноль учетных записей при вызове GetAccountsAsyn c (). Раз или два я получил учетную запись, и все работало, но это очень прерывисто. Когда я смотрю на информацию об отладке, я получаю что-то вроде этого:

Tried to use network cache provider for login.microsoftonline.com. Success? False

Tried to use known metadata provider for login.microsoftonline.com. Success? True

В одном случае он успешно получил учетную запись во время отладки, он сказал:

Tried to use network cache provider for login.microsoftonline.com. Success? True

1 Ответ

1 голос
/ 04 февраля 2020

Прежде всего при использовании технологии на основе OAuth я рекомендую:

  • Понимание решений на основе стандартов
  • Возможность просмотра сообщений OAuth

У меня есть некоторые примечания по Azure устранению неполадок AD , которые могут показать вам тип подхода, который я использую - у него также есть некоторые настройки Azure / Graph.

Если вы можете добраться до состояния, в котором Вы можете публиковать HTTP-сообщения - больше, чем C# код - вы получите лучшие ответы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...