Подключение к Microsoft Graph из MVC от имени вошедшего в систему пользователя - PullRequest
0 голосов
/ 27 ноября 2018

Я создал веб-приложение MVC, на котором есть определенные страницы, требующие входа пользователя в систему. Приложение является многопользовательским, и аутентификация настраивается в файле Startup.Auth.cs.Файл ConfigureAuth выглядит следующим образом:

public void ConfigureAuth(IAppBuilder app){
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

    app.UseCookieAuthentication(new CookieAuthenticationOptions());

    app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions {
        ClientId = clientId,
        Authority = authority,
        RedirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"],                
        TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters{
            ValidateIssuer = false,
        },
        Notifications = new OpenIdConnectAuthenticationNotifications(){
            SecurityTokenValidated = (context) => {
                return Task.FromResult(0);
            },
            AuthorizationCodeReceived = (context) => {
                var code = context.Code;

                ClientCredential credential = new ClientCredential(clientId, appKey);
                string tenantID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
                string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
                AuthenticationContext authContext = new AuthenticationContext(
                    aadInstance + tenantID,
                    new ADALTokenCache(signedInUserID)
                );
                AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
                    code,
                    new Uri(ConfigurationManager.AppSettings["ida:RedirectUri"]),
                    credential,
                    graphResourceID
                );

                return Task.FromResult(0);
            },
            AuthenticationFailed = (context) => {
                context.HandleResponse(); // Suppress the exception
                context.Response.Redirect("/Error?message=" + context.Exception.Message);
                return Task.FromResult(0);
            }
        }
    });
}

Это работает - отлично.Моя проблема в том, что я хотел бы получить такую ​​же авторизацию в моем контроллере при вызове конечной точки Microsoft Graph.

Я вижу, что AccessToken, содержащийся в AuthenticationResult, имеет правильные области видимости, то есть я должен иметь возможностьиспользуйте это снова при вызове Graph, верно?

Но как мне использовать это в моем контроллере?И как мне убедиться, что токен обновлен?

Все примеры, которые я могу найти, используют MSAL с конечной точкой v2 или подключаются от имени клиента - это не работает для меня.

1 Ответ

0 голосов
/ 27 ноября 2018

Вы не можете повторно использовать токен из вашего контроллера и отправить его в Graph, чтобы Graph считал вас пользователем.Это не работает, потому что токен также содержит IP-адрес клиента, и это не тот IP-адрес, на котором работает ваш контроллер (возможно, только на компьютере разработчика).Вместо этого ваше приложение должно иметь разрешение Directory.AccessAsUser.All.

Если у вас есть это, в своем бэкэнде вы можете создать

new AuthenticationContext("https://login.microsoftonline.com/common/")

и позвонить AuthenticationContext.AcquireTokenAsync(scope, clientCredentials, userAssertation).

  • В этом случае scope должно быть https://graph.microsoft.com/.
  • clientCredentials должно содержать идентификатор вашего приложения и секрет.
  • userAssertation должен содержать
    • токен пользователя в виде диссертации
    • тип должен быть urn:ietf:params:oauth:grant-type:jwt-bearer
    • имя пользователя должно быть пользователями UPN

Когда этот звонок вернется, вы получите новый токен.Это может использоваться в вызовах графа как токен-носитель из кода вашего контроллера для доступа к ресурсам так, как это сделает сам пользователь.

Но убедитесь, что этот токен не выходит из-под вашего контроля (например, секрет приложения),Потому что до тех пор, пока этот токен не истекает, его можно использовать с любой машины в мире, чтобы действовать как пользователь.

Обновление

Если у вас нет токена пользователя, вынужен токен приложения для доступа к графику API.Согласно https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow вы можете получить токен для вашего приложения, позвонив по номеру

using (var client = new HttpClient())
{
    var content = new Dictionary<string, string>
    {
        { "grant_type", "client_credentials" },
        { "scope", "https://graph.microsoft.com/.default"},
        { "client_id", "<ApplicationId>" },
        { "client_secret", "<ApplicationSecret>" }
    };

    var response = await client.PostAsync($"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token", content);
    var content = await response.Content.ReadAsStringAsync();
    dynamic answer = JObject.Parse(content);

    return answer.access_token;
}

Когда вы отправите этот токен на график в заголовке авторизации с префиксом Bearer, вы сможете получить доступвсе ресурсы данного арендатора, предоставленные вашему заявлению.

...