Convert a Kerberos based WindowsIdentity into a Base64 string - c#

If I have the following code:
var token = System.Security.Principal.WindowsIdentity.GetCurrent();
I get a WindowsIdentity that is Kerberos based. I need to make a call with a header like this:
Authorize: Negotiate <Kerberos Token Here>
Is there a way to convert that token object into a Base64 string?

As the maintainer of the Kerberos.NET as mentioned in the other answer, you can always go that route. However, if you want SSO using the currently signed in Windows identity you have to go through Windows' SSPI stack.
Many .NET clients already support this natively using Windows Integrated auth, its just a matter of finding the correct knobs. It's unclear what client you're using so I can't offer any suggestions beyond that.
However if this is a custom client you have to call into SSPI directly. There's a handful of really good answers for explaining how to do that such as: Client-server authentication - using SSPI?.
The aforementioned Kerberos.NET library does have a small wrapper around SSPI: https://github.com/dotnet/Kerberos.NET/blob/develop/Kerberos.NET/Win32/SspiContext.cs
It's pretty trivial:
using (var context = new SspiContext($"host/yourremoteserver.com", "Negotiate"))
{
var tokenBytes = context.RequestToken();
var header = "Negotiate " + Convert.ToBase64String(tokenBytes);
...
}

I could not get this to work, but I was able to get a token using the excellent Kerberos.NET NuGet package. With that I was able to get it like this:
var client = new KerberosClient();
var kerbCred = new KerberosPasswordCredential("UserName", "p#ssword", "domain");
await client.Authenticate(kerbCred);
Console.WriteLine(client.UserPrincipalName);
var ticket = await client.GetServiceTicket("http/ServerThatWantsTheKerberosTicket.domain.net");
return Convert.ToBase64String(ticket.EncodeGssApi().ToArray());
As an aside, I needed help figuring out what the SPN value was for the GetServiceTicket and the project maintainer was fantastically helpful (and fast!).

Related

C#: Download Release Asset from Github

I want to download release asset zipball´s in a C# application for further use.
I´m using Octokit to get all release informations from the repo, including the respective browserdownload_url.
After some research it seemed to me, that you cant download this release asset zip´s via octokit, so trying with httpclient as suggested by some SO posts, that were asking these questions.
The release zip´s are on a Github Enterprise Repository, so they require Authentication.
And that is probably my issue, i cant make the authentication work with the httpClient...
The request always responds with Code 404
(which is the regular behaviour if you try by putting the url into the regular browser without logging in)
My actual implementation looks like this
public void DownloadRelease(string dlUrl, string targetPath)
{
var githubToken = "aaaaaaaaaaabbbbbbbbbcccccccccdddddddddd"; //Token created in the github developer settings with all available rights
//dlUrl = https://github.server.de/organization/project/releases/download/v1.2.34/release.zip
using (var client = new System.Net.Http.HttpClient())
{
var credentials = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}:", githubToken);
credentials = Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(credentials));
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", credentials);
//client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", githubToken);
var contents = client.GetByteArrayAsync(dlUrl).Result;
System.IO.File.WriteAllBytes(targetPath, contents);
}
}
Update:
At the End we followed the way of using the curl way:
https://docs.github.com/en/enterprise-server#3.0/rest/reference/repos#download-a-repository-archive-zip
And one more mistake on my end: There were releases without downloadable Asset IDs which i didnt catch in the code.
Based on the documentation (https://docs.github.com/en/enterprise-server#2.22/rest/overview/other-authentication-methods#via-oauth-and-personal-access-tokens) my best guess is, that your crendentials are wrong.
The docs say, the format should be username:token, yet you are only using token followed by a colon : - that doesn't look right to me, either.
So essentially you need to refactor your credentials variable a bit:
var credentials = $"{username}:{githubToken}";

Send custom messages to Azure Service Bus from MS CRM Plugins (Sandbox)

I know I can register a new "Service Endpoint" in MS CRM and use that to send messages to Azure Service Bus, but this... isn't really what I'm looking for. The above method ends up sending a serialized RemoteExecutionContext.
In my case, I want to have full control over what the Service Bus messages will contain. This means serializing my own classes.
I've tried using the WindowsAzure.ServiceBus nugget (and ILmerging the new DLL) but this only works in a non-sandboxed setting (on-premise CRM), but I'd also like for my solution to work in CRM Online. When attempting to use the same code in CRM Online then attempting to create a TopicClient throws an error:
System.Security.SecurityException: That assembly does not allow partially trusted callers
Is there any way around the above problem?
Here is a way to do this without additional classes and without using ILMerge. I verified this works in CRM online version 9.1.0.646 (Dynamics 365 Customer Engagement)
Your plugin project will need the following references and using statements.
References: System.Net, System.Net.Http
Usings: System.Net, System.Net.Http, System.Security.Cryptography, System.Globalization
In this sample code, I have built up a string variable named json that is the JSON message I want to post. Then the following code will send the message.
string asbUri =
"https://<azurenamespace>.servicebus.windows.net/<topicname>/messages";
TimeSpan ts = new TimeSpan(0, 0, 90);
string sasToken = GetSASToken("sb://<azurenamespace>.servicebus.windows.net", "
<nameofSASkey>", "<SASKeyValue>", ts);
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", sasToken);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, asbUri)
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
HttpResponseMessage response = client.SendAsync(request).Result;
private static string GetExpiry(TimeSpan ttl)
{
TimeSpan expirySinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1) + ttl;
return Convert.ToString((int)expirySinceEpoch.TotalSeconds);
}
public static string GetSASToken(string resourceUri, string keyName, string key,
TimeSpan ttl)
{
var expiry = GetExpiry(ttl);
//string stringToSign = HttpUtility.UrlEncode(resourceUri) + "\n" + expiry;
//NOTE: UrlEncode is not supported in CRM, use System.Uri.EscapeDataString instead
string stringToSign = Uri.EscapeDataString(resourceUri).ToLowerInvariant() + "\n"
+ expiry;
HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key));
var signature =
Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
var sasToken = String.Format(CultureInfo.InvariantCulture, "SharedAccessSignature
sr={0}&sig={1}&se={2}&skn={3}",
Uri.EscapeDataString(resourceUri).ToLowerInvariant(),
Uri.EscapeDataString(signature), expiry, keyName);
return sasToken;
}
I found a way that's compatible with Sandboxed MS CRM.
The idea is to use the Azure REST endpoint to send messages to. It's fairly easy to authenticate and use... at least if you have a working example, which I was able to find here.
It's a fairly decent sample, albeit a bit messy. Still, it shows how to get the basics working, which is authentication and the actual calls.
(Minor note: reading topic messages from ASB based on the sample was not working reliably for me - it would work once and then would not work until the auth key timed out... this didn't bother me as I needed to send messages only, but if this is a functionality you need then this might be not as straightforward.)
I know this is an old question but I had to do something similar recently and I used the SharedVariable Collection to pass additional details and parameter to the ServiceBus.
This is an example:
context.SharedVariables.Add("AttachmentType", attachmentType);
For CRM Online you could take the logic of message conversion/processing outside of sandbox. It will require to have some external compute. Considering you're already using CRM online, that shouldn't be an issue.
An approach you could take is to convert CRM constructed RemoteExecutionContext to whatever type you want. There's a sample of how to integrate Dynamics 365 with NServiceBus, which take this approach as well. The compute I was referring to would be the equivalent of the CRMAdapterEndpoint endpoint from the sample. The endpoint is using a Mapper object to convert JSON serialized RemoteExecutionContext to custom types, ContactCreate and ContactUpdate. That would allow you to achieve what you want.

Implementing refresh tokens in Xamarin (Authorization code flow - OAuth2)

Can anyone maybe share some tutorial, resources, link, anything related to implementing refresh tokens when using Xamarin.
What I am trying to accomplish is authentication code flow(where user firstly provides credentials to identity server, gets temporary code, which later gets exchanged for real access token, for accessing APIs).
I was looking all around, but nothing helped me. I have realized that implementing refresh tokens is not so easy in Xamarin, but still there must be a way.
I was trying something with TokenClient() class.
var client = new TokenClient("https://localhost:44305/connect/token", "mylegislature");
var request = await client.RequestResourceOwnerPasswordAsync(username, password);
if (!request.IsError)
{
_secureService.StoreAuthToken(request);
}
And with AuthorizeRequest() class:
var authorizeRequest =
new AuthorizeRequest("https://localhost:44305/connect/token");
var parameters = new Dictionary<string, string>();
parameters.Add("response_type", "token");
parameters.Add("client_id", "mylegislature");
parameters.Add("scope", "MyLegislatureAPI");
parameters.Add("redirect_uri", "https://localhost:44301/account/oAuth2");
var authorizeUri = authorizeRequest.Create(parameters);
But with non of them I have succeed in sending request to IdentityServer, which is ok since it is expecting respecting of authorization code flow of OAuth2, but I am unable to implement code in right way since I couldn't find any useful resources about this. If someone has something for sharing please help.

Simple C# Evernote API OAuth example or guide?

Anybody know where I can find a simple example C# code example? Apparently really tough to find.
I'm just starting out, got my Developer key.
Initial (really noob question/presumption) - -Can (should/must) my solution be a web service client? No new libraries I need to install in .Net right?
Basically, as a test, I want to be able to securely present a single note from a private notebook in html similar to what the Everfort export in html looks like on a outside WebSite.
Many Thanks in Advance!
You should start by downloading our API ZIP from http://www.evernote.com/about/developer/api/. You'll find C# client sample code in /sample/csharp. This sample code demonstrates using the Evernote API from a desktop application that authenticates using username and password.
I am not sure if you ever got this working, but I was playing around with Evernote, OpenAuth and C# this morning and managed to get it all working. I have put together a blog post / library explaining the experience and outlining how to do it with MVC here - http://www.shaunmccarthy.com/evernote-oauth-csharp/ - it uses the AsyncOAuth library: https://github.com/neuecc/AsyncOAuth
I wrote a wrapper around AsyncOAuth that you might find useful here: https://github.com/shaunmccarthy/AsyncOAuth.Evernote.Simple
One prickly thing to be aware of - the Evernote Endpoints (/oauth and /OAuth.action) are case sensitive
// Download the library from https://github.com/shaunmccarthy/AsyncOAuth.Evernote.Simple
// Configure the Authorizer with the URL of the Evernote service,
// your key, and your secret.
var EvernoteAuthorizer = new EvernoteAuthorizer(
"https://sandbox.evernote.com",
"slyrp-1234", // Not my real id / secret :)
"7acafe123456badb123");
// First of all, get a request token from Evernote - this causes a
// webrequest from your server to Evernote.
// The callBackUrl is the URL you want the user to return to once
// they validate the app
var requestToken = EvernoteAuthorizer.GetRequestToken(callBackUrl);
// Persist this token, as we are going to redirect the user to
// Evernote to Authorize this app
Session["RequestToken"] = requestToken;
// Generate the Evernote URL that we will redirect the user to in
// order to
var callForwardUrl = EvernoteAuthorizer.BuildAuthorizeUrl(requestToken);
// Redirect the user (e.g. MVC)
return Redirect(callForwardUrl);
// ... Once the user authroizes the app, they get redirected to callBackUrl
// where we parse the request parameter oauth_validator and finally get
// our credentials
// null = they didn't authorize us
var credentials = EvernoteAuthorizer.ParseAccessToken(
Request.QueryString["oauth_verifier"],
Session["RequestToken"] as RequestToken);
// Example of how to use the credential with Evernote SDK
var noteStoreUrl = EvernoteCredentials.NotebookUrl;
var noteStoreTransport = new THttpClient(new Uri(noteStoreUrl));
var noteStoreProtocol = new TBinaryProtocol(noteStoreTransport);
var noteStore = new NoteStore.Client(noteStoreProtocol);
List<Notebook> notebooks = client.listNotebooks(EvernoteCredentials.AuthToken);
http://weblogs.asp.net/psteele/archive/2010/08/06/edamlibrary-evernote-library-for-c.aspx might help. As the author states it just bundles some and fixes some. Haven't tried it myself but thought I'd mention for a possibly easier way to get started. Possibly.
This might help too...found it using the Way Back Machine since the original blog site was offline.
https://www.evernote.com/pub/bluecockatoo/Evernote_API#b=bb2451c9-b5ff-49bb-9686-2144d984c6ba&n=c30bc4eb-cca4-4a36-ad44-1e255eeb26dd
The original blog post: http://web.archive.org/web/20090203134615/http://macrolinz.com/macrolinz/index.php/2008/12/
Scroll down and find the post from December 26 - "Get it while it's hot..."

Get credentials from SharpSvn in C#

I am writing some C# code to perform multiple commits to SVN in one pass, much like the tool svnmucc. So far I've been using SharpSvn to do the rest of the necessary communication with SVN, so I'm thinking I can take advantage of it to accomplish the following:
How can I get the credentials (username, password) that are used by SharpSvn?
I'd like to do something like this:
using (SvnClient svnClient = new SvnClient())
{
SomeFictitiousCredentialsClass credentials = svnClient.Authentication.FictitiousGetCachedCredentialsMethod();
// Call my code that performs svnmucc-like work here, passing username and password
// obtained from 'credentials' variable.
}
Sharpsvn doesn't have an api that provides you the credentials from Subversion. It mostly implements the libsvn_client api, and at this level there is no access to this data.
SharpSvn gets a callback from the subversion libraries when these need credentials; in most cases after the builtin password store fails to authenticate.
If your svnmucc code also uses the Subversion apis, you can just plugin the subversion predefined authentication handlers..
SharpSvn itself doesn't have svnmucc support yet. (There was some talk about somebody who liked to add this to SharpSvn, but I haven't got any news about this lately)
While the other answer is still valid for all current versions of SharpSvn, SvnMucc support has just landed in the development code for SharpSvn. So soon it will be possible to perform SvnMucc like operations from .Net.
using SharpSvn;
SvnCommitResult cr;
using (SvnMultiCommandClient mucc = new SvnMultiCommandClient("http://my-repos/svn/"))
{
mucc.CreateDirectory("trunk");
mucc.CreateDirectory("branches");
mucc.CreateDirectory("tags");
mucc.CreateDirectory("trunk/src");
mucc.SetProperty("", "svn:auto-props", "*.cs = svn:eol-style=native");
mucc.SetProperty("", "svn:global-ignores", "bin obj");
mucc.Commit(out cr); // Commit r1
}
using (SvnClient client = new SvnClient())
{
client.CheckOut("http://my-repos/svn/", #"C:\wc");
}
There is a slightly different syntax available if you would like to perform the operation from an existing SvnClient, but this is the general idea.

Categories