我是Azure的新手,在学习Azure Active Directory(AAD)的所有功能方面有些挣扎,所以希望您能为我解决一些问题。这是我已经做过的:
我注册了一个网络应用程序,该应用程序充当资源提供者,并在API管理服务后面提供不同的API。
该Web应用在AAD中具有多个用户和角色。另外,在应用程序级别上设置了更详细的权限。因此,AAD不能控制我用户的所有权限。
使用 OAuth 2.0 对用户进行身份验证。实际上,这意味着如果新用户尝试登录到我的应用程序,他将被重定向到Microsoft的登录页面,输入用户名和密码,然后从Microsoft的身份验证服务器获取JWT令牌。
现在我想做什么:
我想编写一个在构建服务器上运行的应用程序,用于测试用户权限。该应用程序必须使用C#.NET Core编写。现在,我在为如何以用户身份登录我的代码而苦苦挣扎,所以我的问题是:
我如何以用户身份从代码登录到AAD并获取JWT令牌以测试用户权限?我可以仅使用用户名/密码来执行此操作,还是需要在AAD中注册测试应用程序?实现我的目标的最佳解决方案是什么?
提前谢谢
答案 0 :(得分:2)
Juunas的评论已经涵盖了大部分要求。只是在后面加上一些细节。
一些措辞可以帮助您:
https://<yourtenant>.onmicrosoft.com/<yourapi>/user_impersonation
https://<clientId-of-API>/.default
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, "joe@contoso.com",
securePassword);
}
catch(MsalException)
{
// See details below
}
Console.WriteLine(result.Account.Username);
}
答案 1 :(得分:1)
实际上,我找到了一种无需使用MSAL库即可在“纯” C#中执行此操作的方法。因此,如果您正在寻找不使用MSAL的解决方案,则可以按照以下说明的方法进行。
先决条件
必须在Azure Active Directory中注册客户端应用程序。必须向客户端应用程序授予您要测试的应用程序的权限。如果客户端应用程序的类型为“本机”,则无需提供任何客户端机密。如果客户端应用程序的类型为“ Web应用程序/ 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;
}
为此授予的类型只是“密码”。