加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net – .Net Core 2.0 – 获取AAD访问令牌以与Microsoft Gra

发布时间:2020-12-16 07:25:45 所属栏目:asp.Net 来源:网络整理
导读:使用Azure AD身份验证启动新的.Net Core 2.0项目时,您将获得可以登录租户的工作示例,太棒了! 现在,我想获取已登录用户的访问令牌,并使用它来使用Microsoft Graph API. 我没有找到任何关于如何实现这一目标的文档.我只是想要一种简单的方法来获取访问令牌并
使用Azure AD身份验证启动新的.Net Core 2.0项目时,您将获得可以登录租户的工作示例,太棒了!

现在,我想获取已登录用户的访问令牌,并使用它来使用Microsoft Graph API.

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

非常重要的是它适用于在Visual Studio中创建新的2.0 MVC Core应用程序时选择Work和school帐户进行身份验证的过程中创建的项目.

解决方法

我写了一篇博客文章,展示了如何做到这一点: ASP.NET Core 2.0 Azure AD Authentication

TL; DR是你应该在从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.Resource是https://graph.microsoft.com(Microsoft Graph),我从配置中绑定了其他设置(客户端ID等).

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

令牌缓存是你必须要做的,这是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;
        }
    }
}

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

然后,当你想获得一个令牌并使用MS图时,你会做类似的事情(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",new UserIdentifier(userId,UserIdentifierType.UniqueId));

        return result.AccessToken;
    }
}

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读