【问题标题】:Get Azure AD token on behalf of user - NetCore2代表用户获取 Azure AD 令牌 - NetCore2
【发布时间】:2019-04-07 22:54:49
【问题描述】:

我正在尝试代表用户获取 Azure AD 令牌,以便我可以通过 Azure AD 应用程序访问一些资源(该应用程序连接到 SharePoint Online API)。

我的问题是代表用户获取令牌。我在我的应用程序中添加了带有权限的 Azure AD 应用程序作为 Auth 方法(使用 Visual Studio 2017 自动添加)。有没有办法使用内置身份验证代表用户获取令牌? (因为它已经重定向用户登录,如果他还没有)。

我已经尝试过类似的操作,但我认为此令牌用于应用程序,而不是代表用户(如果我尝试访问 SharePoint,则会给出 401)。

string clientId = 'xxxxxxxx';
string clientSecret = 'xxxxxxxxx'
var credential = new ClientCredential(clientId, clientSecret);

AuthenticationResult result = await authContext.AcquireTokenAsync("https://MYSITE.onmicrosoft.com/APPID", credential);

【问题讨论】:

    标签: asp.net-mvc azure asp.net-core-2.0


    【解决方案1】:

    我正在尝试代表用户获取 Azure AD 令牌,以便我可以通过 Azure AD 应用程序访问一些资源(该应用程序连接到 SharePoint Online API)。

    如果我们想要访问共享点,我们需要在 Azure AD 中创建一个有权访问 API 的应用。并且不要忘记授予权限。

    Microsoft Graph 使开发人员能够访问来自多个 Microsoft 云服务的数据,包括:

    • Azure AD(用于用户和组)
    • Office 365
    • SharePoint Online
    • 在线交流
    • OneDrive for Business
    • OneNote
    • 规划师
    • Excel
    • OneDrive 消费者
    • Outlook.com

    另一件事是资源应该是https://graph.microsoft.com 而不是您的应用程序。

    以下是演示代码

     private static async Task<string> GetAppTokenAsync(string tenantId, string clientId, string username,string password)
     {  
        var graphResource = "https://graph.microsoft.com";
         string aadInstance = "https://login.microsoftonline.com/" + tenantId + "/oauth2/token";
         //Instantiate an AuthenticationContext for my directory (see authString above).
         AuthenticationContext authenticationContext = new AuthenticationContext(aadInstance, false);
         // Create a ClientCredential that will be used for authentication.
         //This is where the Client ID and Key / Secret from the Azure Management Portal is used.
         UserPasswordCredential credential = new UserPasswordCredential(username, password); //username is email format
         // Acquire an access token from Azure AD to access the Azure Microsoft Graph(the resource)
         //  using the Client ID and Key / Secret as credentials.
         AuthenticationResult authenticationResult = await authenticationContext.AcquireTokenAsync(graphResource, clientId, credential);
         // Return the access token.
         return authenticationResult.AccessToken;
    
     }
    

    【讨论】:

    • 应用已在 Azure AD 中创建。你的答案不是我真正想要的。我已经使用内置的 Azure AD 身份验证登录用户,我不喜欢让用户输入他们的用户名和密码的想法(因为他们在访问应用程序时已经被重定向到登录)。
    • 正如 Nan Yu 提到的,您可以使用 OpenID Connect 中间件和 Active Directory 身份验证库 (ADAL.NET) 为使用 OAuth 2.0 协议的登录用户获取 JWT 不记名令牌。用户登录。然后您可以使用令牌访问图形资源。
    • 我的实现中有一个不同的中间件,请参阅以下答案中的 cmets。我将尝试使用它来获取令牌(不确定它是否有效)。感谢您尝试帮助我,不胜感激!
    【解决方案2】:

    有没有办法使用内置身份验证代表用户获取令牌? (因为它已经重定向用户登录,如果他还没有)。

    是的,用户通过身份验证后,您应该获取访问令牌以访问 SharePoint Online API/ Microsoft Graph api。

    您可以使用 OpenID Connect 中间件和 Active Directory 身份验证库 (ADAL.NET) 为使用 OAuth 2.0 协议的登录用户获取 JWT 不记名令牌:

    // Because we signed-in already in the WebApp, the userObjectId is know
    string userObjectID = (User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value;
    
    // Using ADAL.Net, get a bearer token to access the TodoListService
    AuthenticationContext authContext = new AuthenticationContext(AzureAdOptions.Settings.Authority, new NaiveSessionCache(userObjectID, HttpContext.Session));
    ClientCredential credential = new ClientCredential(AzureAdOptions.Settings.ClientId, AzureAdOptions.Settings.ClientSecret);
    result = await authContext.AcquireTokenSilentAsync(AzureAdOptions.Settings.TodoListResourceId, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
    

    您可以参考代码示例:Calling a web API in an ASP.NET Core web application using Azure AD。请将资源替换为 SharePoint Online API/Microsoft Graph api 以满足您的要求。

    我已经尝试过类似的操作,但我认为此令牌用于应用程序,而不是代表用户(如果我尝试访问 SharePoint,则会给出 401)。

    是的,您的代码正在使用Client credentials grant flow,它使用应用自己的凭据而不是模拟用户,在调用另一个网络服务时进行身份验证。

    【讨论】:

    • 我看了一下示例,但它使用的是 MVC。我可以用什么来代替 HttpContext.Current 因为它似乎不存在于 AspNetCore 中?
    • 我用HttpContextAccessor为netcore修改了我的代码。在加载时我做了Session.Get("spotoken") 并且坚持我做了.Set("spotoken", CacheId) 。不确定这是否是正确的方法(直到现在还没有在netcore中使用过会话),但是代码给了我一个错误,说缓存中没有令牌,它需要AcquireToken(),据我所知它将重定向用户.是我做错了什么还是重定向是获取用户令牌的唯一方法?
    • @DanteR。您是否遵循客户端示例(TodoListWebApp)并使用 OIDC 中间件和 ADAL 来获取访问令牌?在该代码示例中,它使用token cache 来存储令牌。使用 AcquireTokenSilentAsync 时,将检查当前用户是否有访问缓存中该资源的令牌,如果存在,它将直接使用该令牌,如果没有,它将为您获取访问令牌
    • 你也可以参考这篇文章,可以更好地解释这个过程:joonasw.net/view/aspnet-core-2-azure-ad-authentication
    • 我的问题是,我总体上是“新手”,身份验证部分,我有点困惑,很抱歉冗长的 cmets。我的身份验证(使用 vs 2017 构建)看起来像这样。 ` services.AddAuthentication(AzureADDefaults.AuthenticationScheme) .AddAzureAD(options => Configuration.Bind("AzureAd", options)) .AddAzureADBearer(options => Configuration.Bind("AzureAd", options));` 身份验证有效。我可以将它用于访问令牌还是应该切换到手动 openid 集成?感谢您花时间回答我,我真的很感激。
    猜你喜欢
    • 2021-03-03
    • 1970-01-01
    • 1970-01-01
    • 2019-09-15
    • 2020-10-16
    • 2019-05-15
    • 1970-01-01
    • 2023-03-29
    • 2020-08-02
    相关资源
    最近更新 更多