Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
438 views
in Technique[技术] by (71.8m points)

c# - Replicate cURL Command Using Redirect and Cookies in .Net Core 3.1

This one seems a long shot. But I have seen several answers that indicate that HttpClient (and similar) should be used when cURL is needed in a .Net Core Application.

I have the following cURL command (that works perfectly):

curl -v -L --negotiate -u : -b ~/cookiejar.txt  "https://idp.domain.net/oauth2/authorize?scope=openid&response_type=code&redirect_uri=https://localhost:5001&client_id=client_id_here"

The flow of this command goes like this:

  1. Loads the provided url (https://idp.domain.net/oauth2/authorize....)
  2. Gets a 302 response to redirect to https://idp.domain.net/iwa-kerberos?state=state_guid_here
    • Because the -L option is there, it follows the redirect
  3. The redirect responds with a 401 (Unauthorized) with a www-authenticate:Negotiate header.
  4. cURL sees the www-authenticate:Negotiate header and gets a Kerberos token from the operating system (because of the --negotiate and -u options).
  5. cURL calls the redirect url (https://idp.domain.net/iwa-kerberos?state=state_guid_here) with an additional header of Authorization: Negotiate <kerberos token here>.
  6. A response of 302 returned redirecting to https://idp.domain.net/commonauth?state=state_guid_here&iwaauth=1 with an added cookie
    • Because of the -b option, the cookie is picked up by cURL.
  7. cURL calls the redirect url (https://idp.domain.net/commonauth?state=state_guid_here&iwaauth=1) with the cookie returned in the 302 of the previous step.
  8. Another 302 redirect is returned. Redirecting to https://idp.domain.net/oauth2/authorize?sessionDataKey=session_key_guid_here with more cookies. (Again picked up because of the -b option.)
  9. The redirect to https://idp.domain.net/oauth2/authorize?sessionDataKey=session_key_guid_here is followed with the added cookies.
  10. Another 302 redirect is returned to https://localhost:5001/?code=code_guid_here&session_state=session_state_here (with an added cookie).
  11. cURL folows the redirect to https://localhost:5001/?code=code_guid_here&session_state=session_state_here with the added cookie.
  12. Contents of https://localhost:5001/?code=code_guid_here&session_state=session_state_here are returned to the cURL command line.

Writing this all out, it seems like a serious undertaking to get this to work in a .Net Application. But I figured I would ask in case it is built in to the framework somewhere.

Is there a .Net Core Framework class (or similar) that can allow me to reproduce this cURL command in C# code?

NOTE: I am able to do it by calling out to powershell. This question is about doing it with HttpClient.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Converting curl flags to HttpClient

-L

HttpClient should automatically follow redirects because HttpClientHandler.AllowAutoRedirect defaults to true.

--negotiate -u :

HttpClient will handle negotiation if you supply its constructor with a HttpClientHandler that supplies it with credentials. Since you're using default Windows credentials with -u :, you can use the code from this answer:

var client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });

-b ~/cookiejar.txt

HttpClient can store cookies by supplying its constructor with an HttpClientHandler with a CookieContainer:

var client = new HttpClient(new HttpClientHandler() { CookieContainer = new CookieContainer() })

This depends on the HttpClientHandler having UseCookies = true, but it is true by default.

Returning Contents

You can use HttpClient.GetAsync and HttpResponseMessage.Content to read the response of the HttpClient

var response = await client.GetAsync("");
var content = await response.Content.ReadAsStringAsync();

Everything Combined

Here's what constructing HttpClient and making an equivalent request should look like if we explicitly set every value referenced above:

var client = new HttpClient(
    new HttpClientHandler()
    {
        // -L
        AllowAutoRedirect = true,

        // --negotiate -u :
        UseDefaultCredentials = true,

        // -b ~/cookiejar.txt
        CookieContainer = new CookieContainer(),
        UseCookies = true
    }
);

var response = await client.GetAsync("https://idp.domain.net/oauth2/authorize?scope=openid&response_type=code&redirect_uri=https://localhost:5001&client_id=client_id_here");
var content = await response.Content.ReadAsStringAsync();

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...