代码之家  ›  专栏  ›  技术社区  ›  Tab

MS Graph-获取应用程序令牌(控制台应用程序)

  •  0
  • Tab  · 技术社区  · 8 年前
    • 控制台应用程序-C#。净额4.6
    • 专用管理员用户

    我只是想让bearer令牌和Graph SDK调用一起发送。 我得到一个令牌 但我听说它已经过期了。信息如下:

    访问令牌已过期,请使用访问;刷新令牌以验证

    由于这是一个控制台应用程序,我不知道如何才能 获取/保留 访问和刷新令牌来执行此操作。

    仅供参考:我之前的努力遵循了以下步骤 无需用户即可访问 : https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_service 我无法通过该页面上的简单令牌HTTP请求:未经授权。

    这是我最近的努力。欢迎提供任何帮助:

    using Microsoft.Graph;
    using Microsoft.Identity.Client;
    
    public static async Task<string> GetTokenForAppAsync()
    {
        if (TokenForApplication == null || TokenForApplicationExpiration <= DateTimeOffset.UtcNow.AddMinutes(5))
        {
            TokenCacheUser = null;
            TokenCacheApplication = null;
    
            ConfidentialClientApplication cl = new ConfidentialClientApplication(Settings.AuthClientId,
                returnUrl,
                new ClientCredential(Settings.AuthClientSecret),
                TokenCacheUser,
                TokenCacheApplication);
    
            AuthenticationResult authResult = cl.AcquireTokenForClientAsync(new string[] { "https://graph.microsoft.com/.default" }, true).Result;
            TokenForApplication = authResult.AccessToken;
            Console.WriteLine(authResult.AccessToken);
        }
        return TokenForApplication;
    }
    

    我对任何利用MS Graph和Identity LIB的解决方案持开放态度。

    1 回复  |  直到 8 年前
        1
  •  0
  •   Tab    8 年前

    graph\u authentication\u示例

    这是控制台应用程序基于令牌的身份验证的示例。应用程序必须至少运行一次,每次都会提示您登录,但一旦登录完成,将在运行应用程序的机器上存储身份验证令牌。

    我从服务器上运行一个控制台应用程序作为任务,并访问Graph API以使用Graph端点获取各种ActiveDirectory数据集——通常我需要在发布后登录,然后再运行——这刚刚处于测试阶段,但似乎很好用。

    依赖项:

    • 必须具有Azure Active Directory用户,该用户将用于登录和后续身份验证。一切都是在这个用户的上下文中发生的。
    • 使用了以下Nuget包:
      • 微软图形>=v1.6.2
      • 微软图表核心>=v1.6.2
      • 微软身份客户>=v1.1.0预览
      • 微软标识模型。客户。ActiveDirectory>=v3.17.1
      • Newtonsoft。Json>=v1.0.3
      • 系统安全密码学。算法>=v4.3.0
      • 系统安全密码学。编码>=v4.3.0
      • 系统安全密码学。基本体>=v4.3.0
    • 您必须在此处创建应用程序[ https://apps.dev.microsoft.com/]
    • 你们可以在这里看到图表[ https://developer.microsoft.com/en-us/graph/graph-explorer/] 并使用上面创建的用户登录,对您自己的Azure Active Directory进行测试。

    设置

    [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;
                }
            }
        }
    }
    
    推荐文章