Use Kerberos-ticket in C# client application - c#

I have a web-application where I'm automatically logged in with my Windows Credentials.
I now want to consume information from this web-application, in a c# windows application using my Windows Account. Therefore I need to be able to get the session-cookie from this web-site.
Here you can see a piece of my code, where I want to retrieve the cookie :
string URLAuth = extractParameterFromProperties("relatieBeheer_login_url");
WebClient webClient = new WebClient();
webClient.Credentials = CredentialCache.DefaultCredentials;
// webClient.UseDefaultCredentials = true;
byte[] responseBytes = webClient.DownloadData(URLAuth);
//byte[] responseBytes = webClient.UploadValues(URLAuth, "POST", formData);
string resultAuthTicket = Encoding.UTF8.GetString(responseBytes);
if(resultAuthTicket.Contains("Verkeerde combinatie gebruikersnaam")){
sessionCookie="NoSession";
}else{
WebHeaderCollection cookies = webClient.ResponseHeaders;
sessionCookie = cookies[HttpResponseHeader.SetCookie];
}
When I debug the application, I can see nothing is filled in the credentials :
Domain, Username & Password are empty.
Any help would be most welcome.

The ICredentials instance returned by DefaultCredentials cannot be used to view the user name, password, or domain of the current security context.
http://msdn.microsoft.com/en-us/library/system.net.credentialcache.defaultcredentials.aspx

Related

Does CredentialCache.DefaultCredentials always return current user's credentials?

I'm writing a C# app that is supposed to pass current user's credentials (Domain, Username and Password) to WebClient. For some reason the web service returns error 401 - Unauthorized even though I know for a fact, that credential of Window's user that is accessing it are the same as in the web service I'm trying to connect to.
var wc = new WebClient();
string jsonbefore = "";
Uri uri = new Uri(ConnectionString);
wc.UseDefaultCredentials = true;
wc.Credentials = System.Net.CredentialCache.DefaultCredentials;
wc.Headers["Accept"] = "application/json;odata=nometadata";
System.IO.Stream response = wc.OpenRead(conn);
StreamReader reader = new StreamReader(response);
jsonbefore = reader.ReadToEnd();
response.Flush();
Are there any environment/system settings that are stopping credentials from flowing? I've read up something about EnvironmentPermission class, but I don't know whether it's relatable to my problem.
Are there any better, more consistent ways of passing Windows credentials to a web service? Or is there any way to check if the username, password or domain from DefaultCredentials is being passed as null?

the remote server returned an error 403 forbidden

I'm calling a WebAPI method from c# code and I'm getting:
the remote server returned an error 403 forbidden
In Local machine it's working perfect and in my deveopment server I am getting 403 forbidden error.
WebClient wc = new WebClient();
string url = string.Empty;
if (Tag == "L") {
url = ConfigurationSettings.AppSettings["MajraApi"].ToString();
}
var httpWebRequest = (HttpWebRequest) WebRequest.Create(url);
wc.UseDefaultCredentials = true;
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using(var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream())) {
string json1 = "Some JSON String";
streamWriter.Write(json1);
streamWriter.Flush();
streamWriter.Close();
}
httpWebRequest.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
var httpResponse = (HttpWebResponse) httpWebRequest.GetResponse();
using(var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
You probably have set up an authentication to connect to your server iis in production, so you have to define the credentials to allow access to the API. You can't leave the default credentials System.Net.CredentialCache.DefaultCredentials.
Replace the line 14 by this changing userName and password defined in IIS :
httpWebRequest.Proxy.Credentials = new NetworkCredential() {
UserName = "userName";
Password = "password";
Domain = "mydomain"; // facultative
};
When you send a request with DefaultCredentials, it means the current user, the one who executes the application. In your local machine that is probably your domain user, while on your dev server it is the user set for the app pool - which may not have permissions for the api you try to call.
Have you set in IIS, Application Pools of your WebApi service .NET CLR version to:
No Managed Code
Also, did u give permissions to your wwwroot of webapi folder to user IIS_IUSRS to Read and Write or even for Modify too (or even Full control) depending of needs. Also add permissions to NETWORK SERVICE.
Also check this:
IIS_IUSRS and IUSR permissions

C# - login to website, $_POST and cookies

I'm trying to login to website and download some pages as it see logged user in C#.
I have class, where are functions to send POST to login page to login. I have verified, that I actually log in, but data's are not keeped, so when I download HTML of the page I need, I get page saying to log in.
I found this, but I don't know how to implement it.
I have class with two funtions: Login() used to login to website, based on this example:
using(WebClient client = new WebClient())
{
System.Collections.Specialized.NameValueCollection reqparm = new System.Collections.Specialized.NameValueCollection();
reqparm.Add("param1", "<any> kinds & of = ? strings");
reqparm.Add("param2", "escaping is already handled");
byte[] responsebytes = client.UploadValues("http://localhost", "POST", reqparm);
string responsebody = Encoding.UTF8.GetString(responsebytes);
}
Then, second function DownloadHtml(string url), contains this:
using (WebClient client = new WebClient()) {
client.Encoding = Encoding.UTF8;
html = client.DownloadString(url);
return html;
}
How to save cookis in Login() and use them in DownloadHtml() to see the page as logged user? Or shouldn't I use WebClient? If no, what should I use?
Thanks.
After you receive cookies from your first request to authorization you should saved them (in some variable perhaps) and then manually add them to any subsequent request that you will be make.
Adding cookies to request can be made like this:
using (WebClient client = new WebClient())
{
client.Headers.Add("Cookie", "AUTH_COOKIE_NAME=" + AUTH_COOKIE_VALUE);
client.Encoding = Encoding.UTF8;
html = client.DownloadString(url);
return html;
}

Download file using System.Net.WebClient for pages with form based logins

I am trying to download a file from a microsoft site, that uses form based logins (microsoft account). How can I do that using WebClient ?
The link is something like "http://go.microsoft.com/fwlink/ ....."
Thanks
You can set credentials to the WebRequest as follows. This post explains how to download the file.
// Create a request for the specified remote file name
WebRequest request = WebRequest.Create(remoteFilename);
if (request != null)
{
string username = "username";
string password = "password";
request.Credentials = new System.Net.NetworkCredential(username, password);
}

Trouble downloading a file

I am trying to download a file from a C# application. I have tried two different methods, but both yield the same response:
"The remote server returned an error: (401) Unauthorized."
I am pretty sure this is a credentials issue (because of the 401). If I navigate to the url from a browser, and enter the very same credentials provided, the file downloads just fine. In "Attempt 2" (below), for authtype, I have tried:
NTLM, Basic, Negotiate, and Digest without any luck.
Does anyone see what I might be doing wrong here?
Thanks for the help!
Attempt 1:
string username = "username";
string password = "password";
string domain = "domain";
string url = #"http://LiveLinkInstance.com/livelink/llisapi.dll/999999/WordDocument.docx?func=doc.Fetch&nodeid=999999&ReadOnly=True&VerNum=-2&nexturl=/livelink/llisapi.dll?func=ll&objId=888888&objAction=browse&viewType=1";
// Create an instance of WebClient
WebClient client = new WebClient();
client.Proxy = null;
client.Credentials = new System.Net.NetworkCredential(username, password, domain);
client.DownloadFile(new Uri(url), #"C:\FileDownloads\test.txt");
Attempt 2:
string username = "username";
string password = "password";
string domain = "domain";
string url = #"http://LiveLinkInstance.com/livelink/llisapi.dll/999999/WordDocument.docx?func=doc.Fetch&nodeid=999999&ReadOnly=True&VerNum=-2&nexturl=/livelink/llisapi.dll?func=ll&objId=888888&objAction=browse&viewType=1";
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
string credentials = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(domain + "\\" + username + ":" + password));
wr.Headers.Add("Authorization", "Basic " + credentials);
CredentialCache cc = new CredentialCache();
cc.Add(new Uri(url), "NTLM", new NetworkCredential(username, password, domain));
wr.Credentials = cc;
Stream str = ws.GetResponseStream();
As Amitay said, using fiddler to compare against traffic from browser is the best way to go. BTW, look here on SO - what's happening is OP's case was that request was getting redirected to different location but credentials were not re-passed. So OP did manual redirection to solve the issue.
Did you try
client.UseDefaultCredentials = true
if you are using MVC or WebApi you should decorate your method with
[Authorize]
If you are able to impersonate a user, use it like this
WindowsIdentity wi = null;
wi = (WindowsIdentity)HttpContext.Current.User.Identity;
using (wi.Impersonate())
{
var client = new WebClient { UseDefaultCredentials = true };
client.Headers.Add(HttpRequestHeader.ContentType, "application/json; charset=utf-8");
var result = JsonConvert.DeserializeObject<Object>(Encoding.UTF8.GetString(client.DownloadData("http://api.com/api/values")));
return Request.CreateResponse(result);
}
I saw LL using its own form-based authentication or SSO based on IWA. I don't know if you can use other HTTP authentication types.
If your server uses the (default) form authentication you would have to use LAPI or WS to download the document providig the LL credentials within the LAPI/WS call. You could also just get a cookie for HTTP communication by LAPI/WS.
If you have SSO configured you can set Credentials to CredentialCache.DefaultCredentials to pass in credentials of the currently authentified Windows session.

Categories

Resources