Validate domain user credentials with .NET 2 - c#

This question is solved with Framework 3.5, however I need to do this using .NET Framework 2 and C#.
I want to validate a given domain\user and password combination. For example:
Username: TheDomain\TheName
Password: ThePassword
Also note the drawbacks to the suggested solutions given in the link.
Current solution that I am using, however note the false negative possibilities

You can use NetworkCredential.Domain Property
The following code example uses the Domain property to set the domain associated with the credentials
// Create an empty instance of the NetworkCredential class.
NetworkCredential myCredentials = new NetworkCredential("", "", "");
myCredentials.Domain = domain;
myCredentials.UserName = username;
myCredentials.Password = password;
// Create a WebRequest with the specified URL.
WebRequest myWebRequest = WebRequest.Create(url);
myWebRequest.Credentials = myCredentials;
Console.WriteLine("\n\nUser Credentials:- Domain: {0} , UserName: {1} , Password: {2}",
myCredentials.Domain, myCredentials.UserName, myCredentials.Password);
// Send the request and wait for a response.
Console.WriteLine("\n\nRequest to Url is sent.Waiting for response...Please wait ...");
WebResponse myWebResponse = myWebRequest.GetResponse();
// Process the response.
Console.WriteLine("\nResponse received sucessfully");
// Release the resources of the response object.
myWebResponse.Close();
Here is the MSDN Link for more reading
Hope it will help

Related

REST C# Get List Items

I am completely new to REST API.
I would like to retrieve ListItems in xml format from an external site in C#.
I have got the username and password for the site (which uses Mixed authentication by the way).
HttpWebRequest endpointRequest = (HttpWebRequest)HttpWebRequest.Create("https://<site>/_api/web/lists");
endpointRequest.Method = "GET";
endpointRequest.Accept = "application/atom+xml";
//endpointRequest.Headers.Add("Authorization", "Bearer " + accessToken);
endpointRequest.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes("<domain>\\<username>:<password>"));
HttpWebResponse endpointResponse = (HttpWebResponse)endpointRequest.GetResponse();
I am using this piece of code that I found on MSDN.
Would anybody please be kind enough to tell me how do I get an access token?
Why am I getting 403 Forbidden error?
I think you can better use the NetworkCredential class:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
NetworkCredential credentials = new NetworkCredential("testuser", "testpass");
request.Credentials = credentials;
No need to send the Authorization header
When I have to use REST API I use Tiny.RestClient 1
In your case you have to write the call like that :
var client = new TinyRestClient(new HttpClient(), "https://<site>/_api/");
client.GetRequest("web/lists")
Hopes that help.
WithBasicAuthentication("username", "password").
ExecuteAsync();

Provide Credentials for BackgroundTransferRequest (WP8)

When I am using HttpWebRequest I use the following code to set the Credentials
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlToCall);
request.Method = "GET";
request.Credentials = new NetworkCredential(username, pass);
How do I do the same when I am using BackgroundTransferService in Windows Phone 8.
For reference I am using the following.
http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh202955%28v=vs.105%29.aspx
http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh202959%28v=vs.105%29.aspx
*Edit:
The authentication method is Digest
This is what I get in the Authorization Header when I use my browser to download the file.
Digest username="adf", realm="bcd", nonce="XXXXXXXXX", uri="/ans/1268e52399.txt", algorithm=MD5, response="XXXXXXXXXXXXXXX", qop=auth, nc=00000001, cnonce="XXXXXXXXXXXX"
Unfortunately this isn't supported on the BackgroundTranserService. One possible solution might be to manually create a header for your request like below:
var credentials = new UTF8Encoding().GetBytes(username + ":" +password);
var transferRequest = new BackgroundTransferRequest(transferUri);
transferRequest.Headers["Authorization"] ="Basic " + convert.ToBase64String(credentials);
Unfortunately I'm unable to test this at the minute, give it a try and let me know how you get on.

Getting the default credentials?

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

Why my Http client making 2 requests when I specify credentials?

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.

Twitter: verifying username and password in C#

Bounty Question
I am using c# 3.5 Window Forms Application. I am using the code mentioned in the accepted answer. and I am getting below error
The remote server returned an error: (401) Unauthorized.
Sample code to verify the UserName and Password will be really appreciated
Bounty Question Ends
I have an application with the following use-case: when the user first starts using the application, he inputs his username and password. Then, at a much later stage, the application may update his status.
Currently I'm using Twitterizer, but I believe the question is beyond the scope of the specific library I'm using. Following are the two relevant lines of code:
Twitter twitter = new Twitter("username", "password", "source");
twitter.Status.Update("update");
The construction of the Twitter object does not throw an exception if the username/password are incorrect. This is probably because nothing is sent at this point. On the other hand, the status update does throw an exception if the username/password are invalid.
My problem is that I want to validate the username/password at the point of user input, not when trying to post the update.
How can I validate the username/password without posting anything (in Twitterizer or otherwise)?
Taking a quick look at the verify_credentials API as mentioned by peSHIr, I wrote a little routine which seems to do the trick. It's late, but I was able to test it a couple of times and seems to work.
In my function, I am just returning true if I I get an HttpResponseCode.OK, and false if I get anything else or an exception is thrown. If twitter does not like the uid/password an exception will be thrown with a 401 error (not authorized.)
public bool CheckTwitterCredentials(string UserName, string Password)
{
// Assume failure
bool Result = false;
// A try except block to handle any exceptions
try {
// Encode the user name with password
string UserPass = Convert.ToBase64String(
System.Text.Encoding.UTF8.GetBytes(UserName + ":" + Password));
// Create our HTTP web request object
HttpWebRequest Request =
(HttpWebRequest)WebRequest.Create("http://twitter.com/account/verify_credentials.xml");
// Set up our request flags and submit type
Request.Method = "GET";
Request.ContentType = "application/x-www-form-urlencoded";
// Add the authorization header with the encoded user name and password
Request.Headers.Add("Authorization", "Basic " + UserPass);
// Use an HttpWebResponse object to handle the response from Twitter
HttpWebResponse WebResponse = (HttpWebResponse)Request.GetResponse();
// Success if we get an OK response
Result = WebResponse.StatusCode == HttpStatusCode.OK;
} catch (Exception Ex) {
System.Diagnostics.Debug.WriteLine("Error: " + Ex.Message);
}
// Return success/failure
return Result;
}
You could try to use the API call account/verify_credentials. Hopefully the API library you use already supports this.. Twitter is notorious now for really hating third party programmers, so unless you have good reason to do something with Twitter, just stay away...
I have used other Twitter Libraries but none of them support checking the username and password for validitity. This might be because Twitter API does not have the facility to validate the username and password unless we try to do something which requires authentication.
One thing you can do is try to get friend list or any other methods that requires authentication.
Twitter API hasn't supported username/password in years. Instead, you have OAuth, which lets the user authorize your application to act on their behalf. Twitter has an account/verify_credentials endpoint you can use to verify whether the user who's tokens you have still authorizes your app. Here's an example of how you could call this endpoint with LINQ to Twitter:
var accounts =
from acct in twitterCtx.Account
where acct.Type == AccountType.VerifyCredentials
select acct;
You can visit Account/VerifyCredentials documentation for more details:
as #joe-mayo informed, you have to switch to OAuth. twitter expired v1 of their API and they documented that in following url https://dev.twitter.com/docs/faq#17750.
Here's a function i wrote that will verify twitter username and password in C# :
public bool isTwitterValid(string username, string password)
{
try
{
string user = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(username + ":" + password));
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://twitter.com/statuses/verify.xml");
request.Method = "POST";
request.ServicePoint.Expect100Continue = false;
request.Headers.Add("Authorization", "Basic " + user);
request.ContentType = "application/x-www-form-urlencoded";
WebResponse response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string responseString = reader.ReadToEnd();
reader.Close();
}
catch (Exception ex)
{
if (ex.Message.Contains("404")) { return true; }
}
return false;
}

Categories