Skip to content
This repository has been archived by the owner on Nov 24, 2021. It is now read-only.

Basic C# .NET Client code example for this? #8

Closed
megakid opened this issue May 29, 2018 · 10 comments
Closed

Basic C# .NET Client code example for this? #8

megakid opened this issue May 29, 2018 · 10 comments

Comments

@megakid
Copy link

megakid commented May 29, 2018

Apologies if this isn't the correct place for this type of question but has anyone got this working with a .NET/C# client?

I can't for the life of me get it to work, my local user has permissions via kerberos and works with the README python code:

var spn = "HTTP/vault.MYDOMAIN.ORG@MYDOMAIN.ORG";
KerberosSecurityTokenProvider tokenProvider = new KerberosSecurityTokenProvider(spn,
    TokenImpersonationLevel.Impersonation, CredentialCache.DefaultNetworkCredentials);
KerberosRequestorSecurityToken securityToken = tokenProvider.GetToken(TimeSpan.FromMinutes(1)) as KerberosRequestorSecurityToken;
var token = Convert.ToBase64String(securityToken.GetRequest());

HttpClient client = new HttpClient();//new HttpClientHandler { UseDefaultCredentials = true, PreAuthenticate = true });

var serializeObject = JsonConvert.SerializeObject(new { authorization = "Negotiate " + token });
var resp = await client.PostAsync(new Uri(vaultUri, "v1/auth/kerberos/login"),
    new StringContent(serializeObject)); // 500 error

var content = await resp.Content.ReadAsStringAsync(); // {"errors":["SPNEGO negotiation token is not a NegTokenInit: OID does not match SPNEGO OID 1.3.6.1.5.5.2"]}
@megakid megakid changed the title C# .NET Client code for this? Basic C# .NET Client code example for this? May 29, 2018
@ah-
Copy link
Contributor

ah- commented May 29, 2018

Hi,

we haven't tried this with .NET so far, but it'd be good to get working.

From the error message it seems like the token you are getting isn't a SPNEGO token, maybe there is some flag you can set to ask for one?
I think I've seen the same error when leaving off mech_oid=kerberos.GSS_MECH_OID_SPNEGO in the python example.

@megakid
Copy link
Author

megakid commented May 29, 2018

Yeh I don't think my current method can request different types of tokens. I'm tried using TokenImpersonationLevel.Impersonation and TokenImpersonationLevel.Identification with the same error.

As a related tangent: Is there any reason why this plugin doesn't accept the Negotiate token as a HTTP header - as then the built in .NET HttpClient would then deal with sending the correct Authorization HTTP header. I assume the Vault auth plugin framework doesn't allow you access to those?

@ah-
Copy link
Contributor

ah- commented May 29, 2018

Yes, it's due to how vault runs the plugin, that mechanism didn't have a way to pass through headers when I wrote this originally.

It looks like https://github.com/hashicorp/vault/pull/4172/files added that functionality though. Maybe adding support for that would be the easier path?

Should be pretty straightforward, allow the Authorization header and then in https://github.com/wintoncode/vault-plugin-auth-kerberos/blob/master/path_login.go#L103 don't just look at the field but also check the header.

@megakid
Copy link
Author

megakid commented May 29, 2018

Interesting - yes, that would definitely bring it's usage more inline with standard practice.

The .NET HttpClient (and maybe others) expects a 401 challenge before it will send the auth token (see https://weblog.west-wind.com/posts/2010/Feb/18/NET-WebRequestPreAuthenticate-not-quite-what-it-sounds-like) so it might not work unless the plugin framework allows that also.

@ah-
Copy link
Contributor

ah- commented May 29, 2018

See hashicorp/vault#3005 for a bit more discussion on that. Not sure if sending that specific response works yet.

@megakid
Copy link
Author

megakid commented May 29, 2018

Interesting thread, would be great to have a standardised Kerberos auth method in Vault- but I can’t see anything in there preventing HTTP Headers being read and a 401 challenge being returned on the initial request (provided the necessary request headers offering auth are present).

@megakid
Copy link
Author

megakid commented May 29, 2018

From reviewing the code it seems like perhaps the only thing we can't do currently is respond with a WWW-Authenticate HTTP header. We can response with a 401 but as per the rfc, https://tools.ietf.org/html/rfc7235#section-4.1, we must also attach a WWW-Authenticate: Negotiate header along with it, something vault doesn't seem to allow yet? If we could do this, it should cause the requester to send a repeat request, this time with Authorization: Negotiate ...... as a header.

I wonder if this custom response headers feature could be added?

@megakid
Copy link
Author

megakid commented May 29, 2018

Sorry - getting up to speed on this now. As noted, the custom headers in the response is the big thing here - as per the PR you previously referred to. I guess it's a bigger job if auditing and black/whitelisting on a per header basis is necessary.

@ah-
Copy link
Contributor

ah- commented May 30, 2018

Yes, that sounds about right. Will be interesting to see what the response in hashicorp/vault#3005 will be.

@sambott
Copy link
Contributor

sambott commented Apr 29, 2019

Hi @megakid ,
With the header passthrough now working, we have PR #19 which allows the default .NET HttpClient to negotiate with SPNEGO when DefaultCredentials are set to true. We'll get an example snippet added to the README.

@sambott sambott assigned ghost Apr 29, 2019
sambott pushed a commit to sambott/vault-plugin-auth-kerberos that referenced this issue Sep 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants