I am looking at an intranet site (not developed by me) and it has basic authentication enabled.
It needs to be changed to Windows authentication and I have done just that in IIS.
Basically I have installed the Visual Studio 2010 Remote debugger to check why it works fine using basic auth but when changed to Windows it doesn't.
It hangs on the first line on the try, on error 401 unauthorized:
oReq.ContentType = "application/x-www-form-urlencoded";
oReq.Method = "POST";
// Set the script timeout to a desired value. Timeout value is specified in milliseconds.
oReq.Timeout = 60000;
WindowsIdentity wId = (WindowsIdentity)HttpContext.Current.User.Identity;
WindowsIdentity wIdb4 = WindowsIdentity.GetCurrent();
string name = wIdb4.Name;
WindowsImpersonationContext wIdCon = wId.Impersonate();
// Set credentials to use for this request.
oReq.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
Stream oDataStream = oReq.GetRequestStream();
// Use EncodeParam to enocde the parameters passed in the URL
String sParam = "...";
UTF8Encoding encoding = new UTF8Encoding();
Byte[] Buffer = encoding.GetBytes(sParam);
oDataStream.Write(Buffer, 0, Buffer.Length);
oDataStream.Close();
try
{
HttpWebResponse oResp = (HttpWebResponse)oReq.GetResponse();
....
}
Makes no sense, how come it gets pased it with basic auth and not with Windows?
Also when I run the site on the local machine asp.net server, it works fine.
Related
First of all I am new to C#. I am writing a WPF program in Visual Studio 2019.
In my project I have multiple web requests and whilst testing how they work the functionality was minimal: only the web requests were made and they were working fine until now. The login authorization request still works.
This is my webrequest.
using (var client = new WebClientEx())
{
client.BaseAddress = serverurl.serviceurl;
client.UseDefaultCredentials = true;
string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(excelvertibas.username + ":" + excelvertibas.password));
client.Headers[HttpRequestHeader.Authorization] = "Basic " + credentials;
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
client.Timeout = 90000;
byte[] postArray = Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(domObjectVariables));
client.Headers.Add("Content-Type", "application/json");//----------------
client.Encoding = Encoding.UTF8;
byte[] responseArray = client.UploadData(serverurl.serviceurl + "StartAddDigitalObject", "post", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(domObjectVariables))); //----------------------------
domMetadataAddResponse = JsonConvert.DeserializeObject<StartAddDigitalObjectResponse>(Encoding.UTF8.GetString(responseArray));
}
The base address works, I tested it manually through Postman.
Username and password are also correct which I have tested.
Post array is also passing information which is needed, and I have checked it whilst adding breakpoints.
My question is why could this be not working anymore and what should I look for?
fyi this is the line of code where is should be getting information back into the response array but for some reason it stays null.
byte[] responseArray = client.UploadData(serverurl.serviceurl + "StartAddDigitalObject", "post", Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(domObjectVariables)));
After this the program breaks because the response array contains nothing when I try to pass it further.
Ok i understood what was the problem , when i got the response from the server , it was me who didnt provide the necessary field for the server to respond with anything.So everything was fine with the code.
I have a windows service that is attempting to create a folder on my FTP server. The service works fine locally with no issues at all. When I try and execute on the server however I get a 530. What's really odd is that I created a little .aspx page that runs the same code and it works. It only fails in my service code.
var ftpLocation = ConfigurationManager.AppSettings["FtpLocation"];
var ftpUserName = ConfigurationManager.AppSettings["FtpUserName"];
var ftpPassword = ConfigurationManager.AppSettings["FtpPassword"];
var request = (FtpWebRequest)WebRequest.Create(ftpLocation);
request.Method = WebRequestMethods.Ftp.MakeDirectory;
request.EnableSsl = true;
request.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
try
{
logger.Debug("Calling MakeDirectory for " + ftpPath);
using (var response = (FtpWebResponse)request.GetResponse())
{
if (response.StatusCode != FtpStatusCode.PathnameCreated)
throw new ApplicationException(string.Format("FTP failed with the following response: {0} - {1}",
response.StatusCode, response.StatusDescription));
response.Close();
}
logger.Debug("Calling MakeDirectory for " + ftpPath);
}
I should also note the directory I'm trying to create has a space in it, but again it works 100% correct on my aspx page.
ugh! I looked at the password at least a dozen times. Turns our our deployment server is replacing 3 characters in our password when it deploys
I have page A.aspx in my domain
this page (in its c# codes) makes a request to another page.(B.aspx). - which is in my domain also
the whole site is in windows authentication
HttpWebRequest loHttp = (HttpWebRequest)WebRequest.Create("http://mydom.com/b.aspx");
loHttp.UseDefaultCredentials = true;
loHttp.Timeout = 100000;
HttpWebResponse loWebResponse = (HttpWebResponse)loHttp.GetResponse();
Encoding enc = Encoding.GetEncoding("UTF-8"); // Windows default Code Page
StreamReader loResponseStream = new StreamReader(loWebResponse.GetResponseStream(), enc);
string lcHtml = loResponseStream.ReadToEnd();
loWebResponse.Close();
loResponseStream.Close();
return lcHtml;
Im using impersonation in my web site to a specific account.
the account is being transferred by the statement :
loHttp.UseDefaultCredentials = true;
all is fine.....
However, I want to see those credentials ( I need their "get")
I know that the current thread account(being affected by impersonation)is given by :
WindowsIdentity.GetCurrent().Name
but I want to see the values that in the UseDefaultCredentials !
something like
DefaultCredentials.getCurrent.username
DefaultCredentials.getCurrent.password...
how can I do that ?
I had to do this but in WinForms. It might be work for you too:
System.Net.CredentialCache.DefaultNetworkCredentials
or
System.Net.CredentialCache.DefaultCredentials
I created RESTful webservice (WCF) where I check credentials on each request. One of my clients is Android app and everything seems to be great on server side. I get request and if it's got proper header - I process it, etc..
Now I created client app that uses this service. This is how I do GET:
// Create the web request
var request = WebRequest.Create(Context.ServiceURL + uri) as HttpWebRequest;
if (request != null)
{
request.ContentType = "application/json";
// Add authentication to request
request.Credentials = new NetworkCredential(Context.UserName, Context.Password);
// Get response
using (var response = request.GetResponse() as HttpWebResponse)
{
// Get the response stream
if (response != null)
{
var reader = new StreamReader(response.GetResponseStream());
// Console application output
var s = reader.ReadToEnd();
var serializer = new JavaScriptSerializer();
var returnValue = (T)serializer.Deserialize(s, typeof(T));
return returnValue;
}
}
}
So, this code get's my resource and deserializes it. As you see - I'm passing credentials in my call.
Then when debugging on server-side I noticed that I get 2 requests every time - one without authentication header and then server sends back response and second request comes bach with credentials. I think it's bad for my server - I'd rather don't make any roundtrips. How should I change client so it doesn't happen? See screenshot of Fiddler
EDIT:
This is JAVA code I use from Android - it doesn't do double-call:
MyHttpResponse response = new MyHttpResponse();
HttpClient client = mMyApplication.getHttpClient();
try
{
HttpGet request = new HttpGet(serviceURL + url);
request.setHeader(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
request.addHeader("Authorization", "Basic " + Preferences.getAuthorizationTicket(mContext));
ResponseHandler<String> handler = new BasicResponseHandler();
response.Body = client.execute(request, handler);
response.Code = HttpURLConnection.HTTP_OK;
response.Message = "OK";
}
catch (HttpResponseException e)
{
response.Code = e.getStatusCode();
response.Message = e.getMessage();
LogData.InsertError(mContext, e);
}
The initial request doesn't ever specify the basic header for authentication. Additionally, since a realm is specified, you have to get that from the server. So you have to ask once: "hey, I need this stuff" and the server goes "who are you? the realm of answering is 'secure area'." (because realm means something here) Just because you added it here:
request.Credentials = new NetworkCredential(Context.UserName, Context.Password);
doesn't mean that it's going to be for sure attached everytime to the request.
Then you respond with the username/password (in this case you're doing BASIC so it's base64 encoded as name:password) and the server decodes it and says "ok, you're all clear, here's your data".
This is going to happen on a regular basis, and there's not a lot you can do about it. I would suggest that you also turn on HTTPS since the authentication is happening in plain text over the internet. (actually what you show seems to be over the intranet, but if you do go over the internet make it https).
Here's a link to Wikipedia that might help you further: http://en.wikipedia.org/wiki/Basic_access_authentication
Ok, I got it. I manually set HttpHeader instead of using request.Credentials
request.Headers.Add(HttpRequestHeader.Authorization, "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(Context.UserName + ":" + Context.Password)));
Now I see only single requests as expected..
As an option you can use PreAuthenticate property of HttpClientHandler. This would require a couple of lines more
var client = new HttpClient(new HttpClientHandler
{
Credentials = yourCredentials,
PreAuthenticate = true
});
With using this approach, only the first request is sent without credentials, but all the rest requests are OK.
I'm not sure why but in my asp.net project in this code block when i get an exception on GetRequestStream() i cannot move my cursor to another point in the function as i normally do when i get a function.
The reason is Unable to set the next statement to this location. The next statement cannot be set to another function.
Is there something i can do to allow this?
static public CookieContainer login(string user, string pass)
{
var cookie = new CookieContainer();
var request = (HttpWebRequest)HttpWebRequest.Create(#"https://www.somesite.com/users/login");
request.CookieContainer = cookie;
{
var postData = string.Format("ref=http://www.somesite.com/&username={0}&password={1}", user, pass);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postData.Length;
using (Stream writeStream = request.GetRequestStream())
{
UTF8Encoding encoding = new UTF8Encoding();
byte[] bytes = encoding.GetBytes(postData);
writeStream.Write(bytes, 0, bytes.Length);
}
}
var resp = request.GetResponse();
return cookie;
}
You need to disable Just-in-time debugging.
See: http://msdn.microsoft.com/en-us/library/09yze4a9.aspx
You should try putting a breakpoint at the line where the exception occurs.
Another option is to put in a try/catch in your code, and place a breakpoint in the catch.
In Visual Studio 2010, this seems to be a security restriction. You can circumvent it by Tools / Options / Debugging / Edit and Continue / Check: Enable while remote debugging or debugging an application running under another user account.
This worked when I was debugging an ASP.NET application.
Where are you trying to place the cursor?
The message seems to stay that you are trying to place it in a different function. If you want to place the cursor in the calling function, you might be able to move to the return cookie; statement, hit the F10 key 2 times, then move your cursor in the calling function (where you should be by now).