.Net Core 2.0-获取要与Microsoft Graph一起使用的AAD访问令牌 [英] .Net Core 2.0 - Get AAD access token to use with Microsoft Graph

查看:84
本文介绍了.Net Core 2.0-获取要与Microsoft Graph一起使用的AAD访问令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Azure AD身份验证启动新的.Net Core 2.0项目时,您会获得一个可以登录到租户的工作示例,好极了!

When starting up a fresh .Net Core 2.0 project with Azure AD Authentication you get a working sample that can sign in to your tenant, great!

现在,我想获取已登录用户的访问令牌,并将其用于Microsoft Graph API.

Now I want to get an access token for the signed in user and use that to work with Microsoft Graph API.

我没有找到有关如何实现此目的的任何文档.我只想使用一种简单的方法来获得访问令牌,并使用在启动新的.NET Core 2.0项目时创建的模板来访问图形API.从那里我应该能够找出其余的部分.

I am not finding any documentation on how to achieve this. I just want a simple way to get an access token and access the graph API, using the template created when you start a new .NET Core 2.0 project. From there I should be able to figure out the rest.

非常重要的一点是,它可以与在Visual Studio中创建新的2.0 MVC Core应用程序时选择工作帐户和学校帐户进行身份验证的过程一起使用时创建的项目.

Very important that it works with the project that gets created when following the process where you select Work and school accounts for authentication when creating a new 2.0 MVC Core app in Visual Studio.

推荐答案

我写了一篇博客文章,展示了如何做到这一点:

I wrote a blog article which shows just how to do that: ASP.NET Core 2.0 Azure AD Authentication

TL; DR是当您从AAD收到授权代码时应添加这样的处理程序:

The TL;DR is that you should add a handler like this for when you receive an authorization code from AAD:

.AddOpenIdConnect(opts =>
{
    Configuration.GetSection("Authentication").Bind(opts);

    opts.Events = new OpenIdConnectEvents
    {
        OnAuthorizationCodeReceived = async ctx =>
        {
            var request = ctx.HttpContext.Request;
            var currentUri = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path);
            var credential = new ClientCredential(ctx.Options.ClientId, ctx.Options.ClientSecret);

            var distributedCache = ctx.HttpContext.RequestServices.GetRequiredService<IDistributedCache>();
            string userId = ctx.Principal.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;

            var cache = new AdalDistributedTokenCache(distributedCache, userId);

            var authContext = new AuthenticationContext(ctx.Options.Authority, cache);

            var result = await authContext.AcquireTokenByAuthorizationCodeAsync(
                ctx.ProtocolMessage.Code, new Uri(currentUri), credential, ctx.Options.Resource);

            ctx.HandleCodeRedemption(result.AccessToken, result.IdToken);
        }
    };
});

这里的context.Options.Resourcehttps://graph.microsoft.com(Microsoft Graph),我将它与其他设置(客户端ID等)从config绑定在一起.

Here my context.Options.Resource is https://graph.microsoft.com (Microsoft Graph), which I'm binding from config along with other settings (client id etc.).

我们使用ADAL兑换令牌,并将生成的令牌存储在令牌缓存中.

We redeem a token using ADAL, and store the resulting token in a token cache.

令牌缓存是您必须要做的,这是来自示例应用的示例:

The token cache is something you will have to make, here is the example from the example app:

public class AdalDistributedTokenCache : TokenCache
{
    private readonly IDistributedCache _cache;
    private readonly string _userId;

    public AdalDistributedTokenCache(IDistributedCache cache, string userId)
    {
        _cache = cache;
        _userId = userId;
        BeforeAccess = BeforeAccessNotification;
        AfterAccess = AfterAccessNotification;
    }

    private string GetCacheKey()
    {
        return $"{_userId}_TokenCache";
    }

    private void BeforeAccessNotification(TokenCacheNotificationArgs args)
    {
        Deserialize(_cache.Get(GetCacheKey()));
    }

    private void AfterAccessNotification(TokenCacheNotificationArgs args)
    {
        if (HasStateChanged)
        {
            _cache.Set(GetCacheKey(), Serialize(), new DistributedCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(1)
            });
            HasStateChanged = false;
        }
    }
}

此处的令牌缓存使用分布式缓存来存储令牌,以便为您的应用提供服务的所有实例都可以访问令牌.它们是按用户缓存的,因此您以后可以为任何用户检索令牌.

The token cache here uses a distributed cache to store tokens, so that all instances serving your app have access to the tokens. They are cached per user, so you can retrieve a token for any user later.

然后,当您想要获得令牌并使用MS图时,您会做类似的事情(GetAccessTokenAsync()中的重要内容):

Then when you want to get a token and use MS graph, you'd do something like (important stuff in GetAccessTokenAsync()):

[Authorize]
public class HomeController : Controller
{
    private static readonly HttpClient Client = new HttpClient();
    private readonly IDistributedCache _cache;
    private readonly IConfiguration _config;

    public HomeController(IDistributedCache cache, IConfiguration config)
    {
        _cache = cache;
        _config = config;
    }

    [AllowAnonymous]
    public IActionResult Index()
    {
        return View();
    }

    public async Task<IActionResult> MsGraph()
    {
        HttpResponseMessage res = await QueryGraphAsync("/me");

        ViewBag.GraphResponse = await res.Content.ReadAsStringAsync();

        return View();
    }

    private async Task<HttpResponseMessage> QueryGraphAsync(string relativeUrl)
    {
        var req = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0" + relativeUrl);

        string accessToken = await GetAccessTokenAsync();
        req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

        return await Client.SendAsync(req);
    }

    private async Task<string> GetAccessTokenAsync()
    {
        string authority = _config["Authentication:Authority"];

        string userId = User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
        var cache = new AdalDistributedTokenCache(_cache, userId);

        var authContext = new AuthenticationContext(authority, cache);

        string clientId = _config["Authentication:ClientId"];
        string clientSecret = _config["Authentication:ClientSecret"];
        var credential = new ClientCredential(clientId, clientSecret);

        var result = await authContext.AcquireTokenSilentAsync("https://graph.microsoft.com", credential, new UserIdentifier(userId, UserIdentifierType.UniqueId));

        return result.AccessToken;
    }
}

我们在那里(使用令牌缓存)静默获取令牌,并将其附加到对图的请求中.

There we acquire a token silently (using the token cache), and attach it to requests to the Graph.

这篇关于.Net Core 2.0-获取要与Microsoft Graph一起使用的AAD访问令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆