1

I have a peace of code which works in .Net Framework 4.5, but for which I need the equivalent in .Net 3.5. And my problem is that almost all my google searches result in either solutions using the new WIF or general info about the old WIF 3.5.

The code looks like this:

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: The resulting dll is imported as a plugin in an application running on the 3.5 .net framework and cannot be recompiled to the latest framework. So that won't work.

Ps: For what it's worth, I know that .CreateAuthorizationHeader() just returns "Bearer " + AccessToken. So that's not the problem. To get the AccessToken is.

2 Answers2

0

In the end, AcquireToken just sends a https request to your STS. You can easily simulate this yourself. The request goes like this (for 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

This is easy to do with a WebClient (p.e; How to fill forms and submit with Webclient in C#). The response of the server will typically be something like this:

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"}

The result is a json and the token is in the "access_token" field. You can use a tool such as Fiddler to get your request right but that's basically what there is to it. (You will probably use Newtonsoft to deserialize the json properly.)

Don't make me say that that's all ADAL does for you. ADAL in addition does things such as token caching so you don't have to request a token on each call and it automatically handles expiration etc. But with a little code you can roll that yourself too. Hope this helps.

Community
  • 1
  • 1
0

Below is the code that i used to get the token. The result will be in json which you have to deserialize to read the "access_token" field.

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;
shanmuga raja
  • 685
  • 6
  • 19