AuthenticationContext.AcquireToken 在 .NET 3.5 中等效

AuthenticationContext.AcquireToken equivalent in .NET 3.5

我有一些代码可以在 .Net Framework 4.5 中运行,但我需要 .Net 3.5 中的等效代码。我的问题是,我的几乎所有 google 搜索结果要么是使用新 WIF 的解决方案,要么是关于旧 WIF 3.5 的一般信息。

代码如下所示:

using Microsoft.IdentityModel.Clients.ActiveDirectory;

namespace x 
{
    class y 
    {
        public string GetAuthenticationHeader(Ax7Config config)
        {
            var user = new UserCredential(config.username, config.password);
            return new AuthenticationContext(config.tenant)
                .AcquireToken(config.resource, config.clientAppId, user)
                .CreateAuthorizationHeader();
        }
    }
}

PS: 生成的 dll 作为插件导入到 3.5 .net 框架上的应用程序 运行 中,无法重新编译为最新框架。所以那是行不通的。

Ps: 对于它的价值,我知道 .CreateAuthorizationHeader() 只是 returns "Bearer " + AccessToken。所以这不是问题。获取AccessToken是。

最后,AcquireToken 只是向您的STS 发送一个https 请求。您可以自己轻松模拟。请求是这样的(对于 AAD):

POST https://login.microsoftonline.com/your-tenant-id/oauth2/token HTTP/1.1
Accept: application/json
x-client-Ver: 3.13.5.907
x-client-CPU: x64
x-client-OS: Microsoft Windows NT 6.2.9200.0
x-ms-PKeyAuth: 1.0
client-request-id: 10a9f6d3-1247-493e-874f-fab04e1427c7
return-client-request-id: true
Content-Type: application/x-www-form-urlencoded
Host: login.microsoftonline.com
Content-Length: 183
Expect: 100-continue
Connection: Keep-Alive

resource=your-resource-guid&client_id=your-lcient-guid&client_secret=***** CREDENTIALS REMOVED HERE *****&grant_type=client_credentials

使用 WebClient 很容易做到这一点 (p.e;How to fill forms and submit with Webclient in C#)。服务器的响应通常是这样的:

HTTP/1.1 200 OK
Cache-Control: no-cache, no-store
...
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.5
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
client-request-id: 10a9f6d3-1247-493e-874f-fab04e1427c7
x-ms-request-id: bla-bla
…
X-Powered-By: ASP.NET
Date: Thu, 23 Feb 2017 08:35:26 GMT
Content-Length: 1278

{"token_type":"Bearer","expires_in":"3599","ext_expires_in":"10800","expires_on":"1487842528","not_before":"1487838628","resource":"your-resource-id","access_token":"your-access-token"}

结果是 json 并且令牌在 "access_token" 字段中。您可以使用诸如 Fiddler 之类的工具来获得正确的请求,但基本上就是这样。 (您可能会使用 Newtonsoft 正确反序列化 json。)

不要让我说这就是 ADAL 为您所做的一切。此外,ADAL 还执行令牌缓存等操作,因此您不必在每次调用时都请求令牌,它会自动处理过期等。但是您也可以通过一些代码自行滚动。 希望这有帮助。

下面是我用来获取令牌的代码。结果将在 json 中,您必须对其进行反序列化才能读取 "access_token" 字段。

HttpClient client = new HttpClient();
var values = new Dictionary<string, string>
                {
                   { "resource", "xxx" },
                   { "client_id", "xxx" },
                { "client_secret","xxx"},
                {"client_info","1" },
                {"grant_type","client_credentials" }
                };

var content = new FormUrlEncodedContent(values);

var response = client.PostAsync("https://login.microsoftonline.com/contoso.com/oauth2/token", content).Result;

var responseString = response.Content.ReadAsStringAsync().Result;

return responseString;