graph\u authentication\u示例
这是控制台应用程序基于令牌的身份验证的示例。应用程序必须至少运行一次,每次都会提示您登录,但一旦登录完成,将在运行应用程序的机器上存储身份验证令牌。
我从服务器上运行一个控制台应用程序作为任务,并访问Graph API以使用Graph端点获取各种ActiveDirectory数据集——通常我需要在发布后登录,然后再运行——这刚刚处于测试阶段,但似乎很好用。
依赖项:
设置
[Endpoint]
; we don't want v1.0 because of our needs but it is valid
GraphVersion = beta ; v1.0 or beta
; Common Graph endpoint - we sub version
GraphEndpoint = https://graph.microsoft.com/{version}
[Auth]
; authentication uri
Uri = https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token
; authority uri
Authority = https://login.microsoftonline.com/{tenant}
; if we need to login or re-login
RedirectUri = https%3A%2F%2Flogin.microsoftonline.com%2Fcommon%2Foauth2%2Fnativeclient
; you may have a GUID style tenant but 'common' worked fine since it auth's back to Azure anyway
Tenant = common
; the scopes we needed with Graph, yours may vary
Scopes = { User.ReadBasic.All, User.Read.All, User.ReadWrite.All, Directory.AccessAsUser.All, Directory.Read.All, Directory.ReadWrite.All, Group.ReadWrite.All }
; the id of your azure application - guid
ClientId = xxxx###-2##8-4##9-b##1-ec#########8f2
GrantType = client_credentials
代码段
我试图包括完整的函数,并通过指示它们来自哪些文件来指示分离。这些是令牌身份验证的主要部分,大部分代码是完整的,但“私有”代码除外。
起点:
让我们在我的程序中这样说。cs我调用了以下函数,一切都从这里开始进行身份验证:
// we are just getting a group by id - CreateAuthenticatedClient() is called before every call to Graph
public static async Task<Group> GetGroupAsync(string groupId)
{
var graphClient = AuthenticationHelper.CreateAuthenticatedClient();
try
{
var group = await graphClient.Groups[groupId].Request().GetAsync();
if (group == null) return null;
return group;
}
catch (ServiceException e)
{
ConsoleHelper.WriteException($"GetGroupAsync.{ServiceErrorString(e)}");
return null;
}
}
AuthenticationHelper。cs-完整类
public class AuthenticationHelper
{
public static string TokenForUser = null;
public static DateTimeOffset TokenForUserExpiration;
// this is the 'magic' where we get the user cache
public static PublicClientApplication IdentityClientApp = new PublicClientApplication(Settings.AuthClientId, Settings.AuthAuthority, TokenCacheHelper.GetUserCache());
private static GraphServiceClient graphClient = null;
// Get an access token for the given context and resourceId. An attempt is first made to
// acquire the token silently. If that fails, then we try to acquire the token by prompting the user.
public static GraphServiceClient CreateAuthenticatedClient()
{
if (graphClient == null)
{
try
{
graphClient = new GraphServiceClient(
Settings.GraphEndpoint,
new DelegateAuthenticationProvider(
async (requestMessage) =>
{
var token = await GetTokenForUserAsync();
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", token);
requestMessage.Headers.Add("azure-graph-test", "manage group membership");
}));
return graphClient;
}
catch (ServiceException sex)
{
Console.WriteLine($"Could not create a graph client service: {sex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"Could not create a graph client: {ex.Message}");
}
}
return graphClient;
}
/// <summary>
/// get Token for User
/// </summary>
public static async Task<string> GetTokenForUserAsync()
{
if (TokenForUser == null || TokenForUserExpiration <= DateTimeOffset.UtcNow.AddMinutes(5))
{
AuthenticationResult authResult;
try
{
authResult = await IdentityClientApp.AcquireTokenSilentAsync(Settings.AuthScopes, IdentityClientApp.Users.FirstOrDefault());
TokenForUser = authResult.AccessToken;
}
catch (Exception)
{
if (TokenForUser == null || TokenForUserExpiration <= DateTimeOffset.UtcNow.AddMinutes(5))
{
authResult = await IdentityClientApp.AcquireTokenAsync(Settings.AuthScopes);
TokenForUser = authResult.AccessToken;
TokenForUserExpiration = authResult.ExpiresOn;
}
}
}
return TokenForUser;
}
}
令牌缓存助手。反恐精英
-这是一个microsoft类,它是获取/设置令牌缓存的关键
// Copyright (c) Microsoft Corporation.
// All rights reserved.
// This code is licensed under the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
static class TokenCacheHelper
{
/// <summary>
/// Get the user token cache
/// </summary>
public static TokenCache GetUserCache()
{
if (usertokenCache == null)
{
usertokenCache = new TokenCache();
usertokenCache.SetBeforeAccess(BeforeAccessNotification);
usertokenCache.SetAfterAccess(AfterAccessNotification);
}
return usertokenCache;
}
static TokenCache usertokenCache;
/// <summary>
/// Path to the token cache
/// </summary>
public static string CacheFilePath = System.Reflection.Assembly.GetExecutingAssembly().Location + "msalcache.txt";
private static readonly object FileLock = new object();
public static void BeforeAccessNotification(TokenCacheNotificationArgs args)
{
lock (FileLock)
{
args.TokenCache.Deserialize(File.Exists(CacheFilePath)
? File.ReadAllBytes(CacheFilePath)
: null);
}
}
public static void AfterAccessNotification(TokenCacheNotificationArgs args)
{
// if the access operation resulted in a cache update
if (args.TokenCache.HasStateChanged)
{
lock (FileLock)
{
// reflect changes in the persistent store
File.WriteAllBytes(CacheFilePath, args.TokenCache.Serialize());
// once the write operationtakes place restore the HasStateChanged bit to filse
args.TokenCache.HasStateChanged = false;
}
}
}
}