如何使用 ADAL 在 .NET 中获取代表用户令牌
How to get On-Behalf-Of-User token in .NET using ADAL
我创建了一个 webapp 类型的 Azure AAD 应用程序,它具有客户端密钥和重定向 url。现在,我想代表使用 AAD 应用程序的用户获取访问令牌。通过查看文档,到目前为止我得到了以下代码。
static void Main(string[] args)
{
var clientId = "<REDACTED>";
var clientSecret = "<REDACTED>";
var resourceAppIdURI = "https://api.office.com/discovery/";
var authority = "https://login.microsoftonline.com/common";
AuthenticationContext ac = new AuthenticationContext(authority, new FileCache());
ClientCredential cc = new ClientCredential(clientId, clientSecret);
// Get token as application
var task = ac.AcquireTokenAsync(resourceAppIdURI, cc);
task.Wait();
var appToken = task.Result.AccessToken;
// Get tokenn on behalf of user
UserCredential uc = new UserCredential("usrname@mytenant.com");
task = ac.AcquireTokenAsync(resourceAppIdURI, clientId, uc);
var userToken = task.Result.AccessToken;
Console.ReadLine();
}
但这是我在尝试获取用户令牌时遇到的错误,如下所示。
Message "AADSTS70002: The request body must contain the following
parameter: 'client_secret or client_assertion'.\r\nTrace ID:
0e977f67-d5cb-4cf5-8fea-bac04b6d0400\r\nCorrelation ID:
824a96bf-8007-4879-970c-2680644b8669\r\nTimestamp: 2017-07-21
05:02:41Z" string
为什么会出现此错误以及如何解决?
我是否需要先登录用户然后使用 UserAssertion 代替?
AcquireTokenAsync 方法有很多重载方法,但不确定我应该使用什么。
我也看了这个 github url 看看他们是怎么做的
https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof/blob/8afb3e6a648d8e7246685bf6747d009006c761b8/TodoListService/Controllers/TodoListController.cs
这是获取登录用户令牌的相关代码
ClientCredential clientCred = new ClientCredential(clientId, appKey);
var bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext as System.IdentityModel.Tokens.BootstrapContext;
string userName = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn) != null ? ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn).Value : ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email).Value;
string userAccessToken = bootstrapContext.Token;
UserAssertion userAssertion = new UserAssertion(bootstrapContext.Token, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName);
string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);
string userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
AuthenticationContext authContext = new AuthenticationContext(authority, new DbTokenCache(userId));
这里他们已经有一个登录用户并从该登录用户的令牌创建一个 UserAssertion。在我的控制台应用程序中,用户尚未登录。
所以我需要一种在我的控制台应用程序中执行此操作的方法。如何将 AAD 登录页面作为弹出窗口显示给用户,然后在用户输入凭据后使用该信息创建 UserAssertion 对象?
谢谢
您的方案是一个代表用户调用 Web API 的本机应用程序。本机应用程序可以通过使用 OAuth 2.0 authorization code grant 为用户获取访问令牌,然后在请求中将访问令牌发送到 Web API,从而授权用户和 returns 所需的资源:
请阅读更多关于本机应用程序到 Web API 场景的协议流 here .Also see the code samples 的描述。
此外,您可以单击 here 查看有关如何从本机客户端(.net 控制台应用程序)调用 Azure AD Graph API 的代码示例,它使用 Active Directory 身份验证库(ADAL) 用于身份验证。
我创建了一个 webapp 类型的 Azure AAD 应用程序,它具有客户端密钥和重定向 url。现在,我想代表使用 AAD 应用程序的用户获取访问令牌。通过查看文档,到目前为止我得到了以下代码。
static void Main(string[] args)
{
var clientId = "<REDACTED>";
var clientSecret = "<REDACTED>";
var resourceAppIdURI = "https://api.office.com/discovery/";
var authority = "https://login.microsoftonline.com/common";
AuthenticationContext ac = new AuthenticationContext(authority, new FileCache());
ClientCredential cc = new ClientCredential(clientId, clientSecret);
// Get token as application
var task = ac.AcquireTokenAsync(resourceAppIdURI, cc);
task.Wait();
var appToken = task.Result.AccessToken;
// Get tokenn on behalf of user
UserCredential uc = new UserCredential("usrname@mytenant.com");
task = ac.AcquireTokenAsync(resourceAppIdURI, clientId, uc);
var userToken = task.Result.AccessToken;
Console.ReadLine();
}
但这是我在尝试获取用户令牌时遇到的错误,如下所示。
Message "AADSTS70002: The request body must contain the following parameter: 'client_secret or client_assertion'.\r\nTrace ID: 0e977f67-d5cb-4cf5-8fea-bac04b6d0400\r\nCorrelation ID: 824a96bf-8007-4879-970c-2680644b8669\r\nTimestamp: 2017-07-21 05:02:41Z" string
为什么会出现此错误以及如何解决? 我是否需要先登录用户然后使用 UserAssertion 代替? AcquireTokenAsync 方法有很多重载方法,但不确定我应该使用什么。
我也看了这个 github url 看看他们是怎么做的 https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof/blob/8afb3e6a648d8e7246685bf6747d009006c761b8/TodoListService/Controllers/TodoListController.cs
这是获取登录用户令牌的相关代码
ClientCredential clientCred = new ClientCredential(clientId, appKey);
var bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext as System.IdentityModel.Tokens.BootstrapContext;
string userName = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn) != null ? ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn).Value : ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email).Value;
string userAccessToken = bootstrapContext.Token;
UserAssertion userAssertion = new UserAssertion(bootstrapContext.Token, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName);
string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);
string userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
AuthenticationContext authContext = new AuthenticationContext(authority, new DbTokenCache(userId));
这里他们已经有一个登录用户并从该登录用户的令牌创建一个 UserAssertion。在我的控制台应用程序中,用户尚未登录。 所以我需要一种在我的控制台应用程序中执行此操作的方法。如何将 AAD 登录页面作为弹出窗口显示给用户,然后在用户输入凭据后使用该信息创建 UserAssertion 对象?
谢谢
您的方案是一个代表用户调用 Web API 的本机应用程序。本机应用程序可以通过使用 OAuth 2.0 authorization code grant 为用户获取访问令牌,然后在请求中将访问令牌发送到 Web API,从而授权用户和 returns 所需的资源:
请阅读更多关于本机应用程序到 Web API 场景的协议流 here .Also see the code samples 的描述。
此外,您可以单击 here 查看有关如何从本机客户端(.net 控制台应用程序)调用 Azure AD Graph API 的代码示例,它使用 Active Directory 身份验证库(ADAL) 用于身份验证。