使用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的请求中.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。