如何在测试代码中以用户身份登录Azure Active Directory?

问题描述 投票:0回答:2

我是Azure的新手,在学习Azure Active Directory(AAD)的所有功能方面做了一些努力,所以我希望你能为我清除一些东西。这是我已经做过的事情:

  • 我注册了一个Web应用程序,它充当资源提供者,并提供API管理服务背后的不同API。
  • Web应用程序在AAD中具有多个用户和角色。此外,在App-Level上设置了更详细的权限。所以AAD不控制我的用户的所有权限。
  • 用户通过使用OAuth 2.0进行身份验证。在实践中,这意味着如果新用户尝试登录我的应用程序,他将被重定向到Microsofts登录页面,输入用户名和密码,然后从Microsofts认证服务器获取JWT令牌。

现在我想做什么:

我想编写一个在我的构建服务器上运行的应用程序来测试用户权限。该应用程序必须使用C#.NET Core编写。现在我正在努力研究如何从我的代码以用户身份登录,所以我的问题是:

如何以用户身份从代码登录到AAD并获取JWT令牌来测试用户权限?我可以通过使用用户名/密码来完成此操作,还是需要在AAD中注册我的测试应用程序?达到目标的最佳解决方案是什么?

先感谢您

azure authentication oauth .net-core azure-active-directory
2个回答
2
投票

Juunas的评论已涵盖了大部分要求。只是在它背后添加一些细节。

一些措辞可以帮助你:

  • ClientId:请求令牌的客户端应用程序的ID。
  • 范围:您获取令牌的API的范围。应该已经在API中的某个位置配置了。通常是带有AppId URI的东西。可能的示例可能如下所示: https://<yourtenant>.onmicrosoft.com/<yourapi>/user_impersonation https://<clientId-of-API>/.default ...
  • 权威:你的AAD,例如https://login.microsoftonline.com/yourtenant.onmicrosoft.com

来自wiki的密码授权的代码示例(更多示例):

static async Task GetATokenForGraph()
{
    string authority = "https://login.microsoftonline.com/contoso.com";
    string[] scopes = new string[] { "user.read" };
    PublicClientApplication app = new PublicClientApplication(clientId, authority);

        try
        {
            var securePassword = new SecureString();
            foreach (char c in "dummy")        // you should fetch the password
                securePassword.AppendChar(c);  // keystroke by keystroke

            result = await app.AcquireTokenByUsernamePasswordAsync(scopes, "[email protected]",
                                                                   securePassword);
        }
        catch(MsalException)
        {
          // See details below
        }

    Console.WriteLine(result.Account.Username);
}

1
投票

我实际上在没有使用MSAL库的情况下找到了在“纯”C#中实现它的方法,我遇到了一些问题。因此,如果您正在寻找没有MSAL的解决方案,您可以按照下面描述的方式进行。

先决条件

  • 用户必须存在于AAD中,并且不得使用Microsoft帐户(Active Directory中的源不能是“Microsoft帐户”)。
  • 客户端应用程序必须在Azure Active Directory中注册。必须为客户端应用程序授予您要测试的应用程序的权限。如果客户端应用程序的类型为“Native”,则不必提供客户端密钥。如果客户端应用程序的类型为“Web app / api”,则必须提供客户端密钥。出于测试目的,建议使用“Native”类型的应用程序,而无需客户机密。
  • 必须没有双因素身份验证。

C#代码

你可以创建一个类“JwtFetcher”并使用这样的代码:

    public JwtFetcher(string tenantId, string clientId, string resource)
    {
        this.tenantId = !string.IsNullOrEmpty(tenantId) ? tenantId : throw new ArgumentNullException(nameof(tenantId));
        this.clientId = !string.IsNullOrEmpty(clientId) ? clientId : throw new ArgumentNullException(nameof(clientId));
        this.resource = !string.IsNullOrEmpty(resource) ? resource : throw new ArgumentNullException(nameof(resource));
    }

    public async Task<string> GetAccessTokenAsync(string username, string password)
    {
        var requestContent = this.GetRequestContent(username, password);

        var client = new HttpClient
        {
            BaseAddress = new Uri(ApplicationConstant.Endpoint.BaseUrl)
        };

        var message = await client.PostAsync(this.tenantId + "/oauth2/token", requestContent).ConfigureAwait(false);

        message.EnsureSuccessStatusCode();

        var jsonResult = await message.Content.ReadAsStringAsync().ConfigureAwait(false);
        dynamic objectResult = JsonConvert.DeserializeObject(jsonResult);

        return objectResult.access_token.Value;
    }

    private FormUrlEncodedContent GetRequestContent(string username, string password)
    {
        List<KeyValuePair<string, string>> requestParameters = new List<KeyValuePair<string, string>>()
        {
            new KeyValuePair<string, string>(ApplicationConstant.RequestParameterName.GrantType, ApplicationConstant.RequestParameterValue.GrantTypePassword),
            new KeyValuePair<string, string>(ApplicationConstant.RequestParameterName.Username, username),
            new KeyValuePair<string, string>(ApplicationConstant.RequestParameterName.Password, password),
            new KeyValuePair<string, string>(ApplicationConstant.RequestParameterName.ClientId, this.clientId),
            new KeyValuePair<string, string>(ApplicationConstant.RequestParameterName.Resource, this.resource)
        };

        var httpContent = new FormUrlEncodedContent(requestParameters);
        return httpContent;
    }

此授权类型只是“密码”。

© www.soinside.com 2019 - 2024. All rights reserved.