我已将Azure AD OAuth2守护程序或服务器实现为ASP.NET Web API。 但是我只收到一个访问令牌,它是AuthenticationResult上的属性。见下面的实现。
public IHttpActionResult GetAccessToken(string clientId, string clientkey)
{
AuthenticationContext authContext = new AuthenticationContext(authority);
ClientCredential clientCredential = new ClientCredential(clientId, clientkey);
AuthenticationResult authenticationResult = authContext.AcquireTokenAsync(resourceUri, clientCredential).Result;
Authorisation authorisation = new Authorisation {access_token = authenticationResult.AccessToken,
token_type = authenticationResult.AccessTokenType,
expires_on = authenticationResult.ExpiresOn };
return Ok(authorisation);
}
这只返回访问令牌。我想要一个实现,一个守护进程或服务器实现,它返回访问令牌和刷新令牌。有你看过或做过类似的实现。欢迎任何有用的示例链接。
答案 0 :(得分:5)
当我发布此问题时,这是我正在寻找的答案,请参阅下面的屏幕截图以获得预期结果和c#控制台解决方案。 找到解决方案之后,值得在这里分享,有些人可能对某人有用
C#控制台应用程序代码,以实现下面邮递员屏幕截图的预期效果
using System;
using System.Collections.Generic;
using System.Net.Http;
namespace AzureADTokenApp
{
class Program
{
static void Main(string[] args)
{
var client = new HttpClient();
var uri = "https://login.microsoftonline.com/<tenant-name>.onmicrosoft.com/oauth2/token?api-version=1.0";
var pairs = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("resource", "https://graph.microsoft.com"),
new KeyValuePair<string, string>("client_id", "<azure ad client id e.g. 9b864-a5e6-4f0d-b155-1f53a6c78>"),
new KeyValuePair<string, string>("client_secret", "<azure ad client secret e.g. MTMiXaO1P9HnhSawdXWmcnuQ="),
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", "<azure ad user e.g. julius.depulla@example.com>"),
new KeyValuePair<string, string>("password", "<azure ad user password e.g. Pa$$word01>"),
new KeyValuePair<string, string>("scope", "openid")
};
var content = new FormUrlEncodedContent(pairs);
var response = client.PostAsync(uri, content).Result;
string result = string.Empty;
if (response.IsSuccessStatusCode)
{
result = response.Content.ReadAsStringAsync().Result;
}
Console.WriteLine(result);
Console.ReadLine();
}
}
}
邮递员的截图 - 预期结果。除了不太可读之外,您将在控制台中获得相同的结果
答案 1 :(得分:1)
您正在使用客户端凭据流。在该流程中,不应包含刷新令牌https://tools.ietf.org/html/rfc6749#section-4.4.3。此外,它看起来你正在使用ADAL v3,它无论如何都不会返回刷新令牌(按设计),但它会自动为您使用它们。更多信息http://www.cloudidentity.com/blog/2015/08/13/adal-3-didnt-return-refresh-tokens-for-5-months-and-nobody-noticed/
答案 2 :(得分:1)
如果您使用ADAL v3进行开发,则无需使用刷新令牌手动兑换访问令牌。
在这种情况下,我们应该使用AuthenticationContext
并捕获异常。在access_token过期后,我们应该重新初始化AcquireTokenAsync
并再次调用class Program
{
static string authority = "https://login.microsoftonline.com/adfei.onmicrosoft.com";
static string resrouce = "https://graph.microsoft.com";
static string clientId = "";
static string secret = "";
static ClientCredential credential = new ClientCredential(clientId, secret);
static AuthenticationContext authContext = new AuthenticationContext(authority);
static void Main(string[] args)
{
while (true)
{
var client = new GraphServiceClient(new DelegateAuthenticationProvider(request =>
{
request.Headers.Authorization = new AuthenticationHeaderValue("bearer", GetAccessToken());
return Task.FromResult(0);
}));
var users = client.Users.Request().GetAsync().Result.CurrentPage;
foreach (var user in users)
{
Console.WriteLine(user.DisplayName);
}
Thread.Sleep(1000 * 60 * 5);
}
Console.Read();
}
static string GetAccessToken()
{
try
{
var token = authContext.AcquireTokenAsync(resrouce, credential).Result.AccessToken;
return token;
}
catch (Exception ex)
{
authContext = new AuthenticationContext(authority);
return GetAccessToken();
}
}
以发送获取access_token的请求。
以下是供您参考的代码示例:
[
{
"id": 1,
"name": "Carbo",
"menus": [
{
"id": 33,
"name": "FloralWhite",
"image": {
"web": "https://lorempixel.com/640/360/food/?89722",
"mobile": "https://lorempixel.com/640/360/food/?89722",
"square": "https://lorempixel.com/640/360/food/?89722"
},
"logs": {
"price": 2
}
},
{
"id": 40,
"name": "LightGray",
"image": {
"web": "https://lorempixel.com/640/360/food/?63930",
"mobile": "https://lorempixel.com/640/360/food/?63930",
"square": "https://lorempixel.com/640/360/food/?63930"
},
"logs": {
"price": 2
}
},
]
}
]
答案 3 :(得分:0)
似乎您正在尝试从C# ASP.NET Web API
代码示例生成刷新令牌。
您可以尝试以下代码段:
刷新令牌类:
public class RefreshTokenClass
{
public string token_type { get; set; }
public string expires_in { get; set; }
public string resource { get; set; }
public string scope { get; set; }
public string access_token { get; set; }
public string refresh_token { get; set; }
}
刷新令牌方法:
private async Task<string> GetRefreshToken()
{
string tokenUrl = $"https://login.microsoftonline.com/YourTenantIdOrName/oauth2/token";
var tokenRequest = new HttpRequestMessage(HttpMethod.Post, tokenUrl);
tokenRequest.Content = new FormUrlEncodedContent(new Dictionary<string, string>
{
["grant_type"] = "password",
["client_id"] = "YourApplicationId",
["client_secret"] = "YourApplicationSecret",
["resource"] = "https://graph.microsoft.com",
["username"] = "YourUsername",
["password"] = "YourPass"
});
dynamic json;
dynamic results;
HttpClient client = new HttpClient();
var tokenResponse = await client.SendAsync(tokenRequest);
json = await tokenResponse.Content.ReadAsStringAsync();
results = JsonConvert.DeserializeObject<RefreshTokenClass>(json);
Console.WriteLine("Your Refresh Token=>{0}", results.refresh_token);
return results.refresh_token;
}
测试刷新令牌:
我已成功生成刷新令牌。请参见以下屏幕截图:
注意:我已将此示例用于Azure活动目录方面,您可以更改范围和凭据
如果您还有任何问题,请随时分享。谢谢,祝您编程愉快!