如何将Daemon或Server的Azure AD OAuth2访问令牌和刷新令牌转换为C#ASP.NET Web API

时间:2017-05-24 14:50:58

标签: c# azure security oauth-2.0 azure-active-directory

我已将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);
    }   

这只返回访问令牌。我想要一个实现,一个守护进程或服务器实现,它返回访问令牌和刷新令牌。有你看过或做过类似的实现。欢迎任何有用的示例链接。

4 个答案:

答案 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();
        }
    }
}

邮递员的截图 - 预期结果。除了不太可读之外,您将在控制台中获得相同的结果

enter image description here

答案 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;
        }

测试刷新令牌:

我已成功生成刷新令牌。请参见以下屏幕截图:

enter image description here

  

注意:我已将此示例用于Azure活动目录方面,您可以更改范围和凭据

如果您还有任何问题,请随时分享。谢谢,祝您编程愉快!