I have a winform app that requires me to check whether a page exists on our Wiki or not. However, that query requires a users NetWork credentials to be passed.
I don't want to hardcode my credentials, and I don't want users to have to manipulate the App.config everytime someone else uses it (there's also the issue of them having to expose their password in the App.Config). Is there a way I can get the current user's NT credentials? I don't need to see it (that would be an obvious security issue), I just need it for the following line of code:
HttpWebRequest WikiPageRequest;
WikiPageRequest.Credentials = new NetworkCredential("user", "pass", "dom");
//maybe do something like this
WikiPageRequest.Credentials = GetNTCredentials();
Can you try using CredentialCache.DefaultCredential? That seems to get you the current logged in users credential.
If by "wiki", you mean a deployment of MediaWiki, then sadly you need user id and password.
Unfortunately you cannot get it from Windows, because, even the Windows OS itself does not know the password. It just stores a hash of the password.
By the way, why dont you ask for user id/password for wiki each time the user starts the app?
Related
Situation:
I have an application where our domain users can register their domain account via an Active Directory interface. They can then unlock their account or reset their password via this application. These two "functionalities", the registration/administration & the unlock/reset, take place on different servers. The whole process of unlocking or resetting uses two-factor authentication via a token app on the mobile phone. The only way to link the token to the app is by scanning a QR code (or typewriting the code) which is shown in the registration process. So far so good.
Now it can happen that we have to reset the mobile phone of a user completely, for example for sending it to repair. Even with a backup, the data in the token app cannot be restored. So far, the only possibility to get the QR code back, is to completely delete the registration in our service and re-register again, thereby generating a new QR code. The process of registration takes a while, as you have to think of several security questions (and answers). This is not very user-friendly.
My task now is to implement a function that allows you to show the QR code. This page can be accessed from the "administration" page each user has for their account. The whole site uses single sign on, which of course makes sense, as you don't want to enter the password every time you want to edit a security question for example.
Problem:
With single sign on, every person can walk up to another user's computer and if it isn't locked, show and scan their QR code, change the security questions so they know the answers, reset the victim's password and log into their account. This has to be prevented of course, as it poses a huge security risk.
My approach was to prompt the user's credentials and check whether the user is the same as via SSO by clearing IE's authentication cache via JavaScript. I use the Windows Security window for the credential validation. This way, I don't have to worry about the AD interface.
To check if it's the same user that logged in, I use a cookie with the username from SSO. Then, in the controller, I check if it's equal to User.Identity.Name. If not, I set the cookie with the username from SSO and the rest of the response:
if (cookie.Value.equals(User.Identity.Name))
{
// do some irrelevant stuff
return View();
}
else
{
Request.Cookies["cookieName"] = User.Identity.Name;
Response.AppendHeader("Connection", "close");
Response.StatusCode = 401;
Response.StatusDescription = "Unauthorized";
Response.Clear();
Response.Write("Unauthorized Access");
Response.End();
}
This works just fine. There is one problem though: If you click on cancel in the Windows Security window, you'll be redirected to a "unauthorized access" page. You can then, however, refresh the page and TADA! Single Sign On logged you in automatically and you or the attacker can therefor see the QR code.
Question:
How can I go around SSO in this specific scenario? So far I have only found solutions saying that I should turn off SSO which would affect the whole application.
Sorry
I know this is a long question, my English might not be clear in some cases and I possibly left out some information unintentionally. Feel free to ask for more information.
I have a web site from where I fire a mail to members in my offices
This mail have a yes no button.
on click of yes/no button I call a web service, my yes no link looks somewhat like this
yes
Now users i.e. my office staff will login their system open their outlook find this mail and then click it.
After they click, takevotingOpt method in my web service will be called. In this method I want to know, from which user this call has came.
so that I can maintain record in database like xyz user has voted yes/no
say for e.g. their are two members in my organisation A and B
A's windows loginId is "AaLoginId" and
B's windows loginId is "BbLoginId"
both A and B receives the mail with the above mentioned link in it. when A click the yes/no link my web method should give me A's login Id i.e "AaLoginId". After I get this I make an entry in my database as A has voted yes.
I have tried below thing in my web service to get the user name but of no use please help.
tried this things to get windows login username.
//string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
//Uri uri = new Uri("http://tempuri.org/");
//ICredentials credentials = CredentialCache.DefaultCredentials;
//NetworkCredential credential = credentials.GetCredential(uri, "Ntlm");
////userName = credential.UserName;
//userName = User.Identity.Name;
//userName= System.Threading.Thread.CurrentPrincipal.Identity.Name;
//userName = Context.Request.ServerVariables["LOGON_USER"].ToString();
//userName = HttpContext.Current.User.Identity.Name.ToString();
I went to authentication in my inetmgr and enabled windows authentication for my hosted web service now it does what I want (userName = User.Identity.Name;) but it opens a browser window and ask for windows userid and password I dont want that It should pick up without login window.
Please help or suggest any other approach to achieve this.
You need to turn on windows authentication for the webservice and in IIS, then you should be able to look at Request object to get the user
Use Environment.UserName
Here's the MSDN docs.
http://msdn.microsoft.com/en-us/library/system.environment.username.aspx
Edit - To retrieve all users logged into the current system, check out this Question/Answer - Logoff interactive users in Windows from a service
It shows a way to use WMI and through system DLLs to retrieve a list of logged in users on the current system (which may or may not include service accounts, I haven't tried it myself).
Edit - Using Integrated Security would work for what you're trying to achieve, but can be a bit tricky to setup in large corporations. To get rid of the login prompt, Internet Explorer auto-authenticates to sites in the "Intranet Zone", but does not auto-authenticate to sites in the "Internet Zone". Make sure your web service URL is Intranet based, i.e. http://myserver/ and not Internet based i.e http://myserver.mycorp.com/, unless the user's are within the same domain. If they are not, have the users add "*.mycorp.com" to the Intranet Zone. FireFox has a similar configuration, where specific sites must be "trusted" in order to auto-authenticate.
I'll start off by saying that I have no idea if what I want can actually be done. If that's the case, do not hesitate to tell me that I'm dreaming.
I want to create a custom active directory "authenticator" in C#. By that, I mean, I would like that whenever someone logs in, their password stored in the AD is checked first, and then a second step of authentication is performed. Only if both steps pass does the user get to log in.
Now, I imagine the above isn't too far fetched, providing I wanted to integrate this authenticator into a custom product, right?. Am I totally insane for also wondering if this authenticator can be used when, say, logging into Windows itself? Or perhaps a pre-existing product which authenticates against the AD?
If I'm not dreaming, would anyone also know of any good articles/APIs to get me going? The APIs don't have to be free, as I'm willing to part with some cash to get things moving faster.
This is entirely feasible. However I'd like to note that, when issuing a server bind to Active Directory, you're checking the provided username (usually the sAMAccountName) and the password entered in one action. There are a few ways of doing this in C#, but many folks (including myself) have opted to use the System.DirectoryServices and System.DirectoryServices.Protocols namespace.
This is how I currently bind users to Active Directory, which then based on the result of this method, I either display the reason for authorization failure, or I allow them to continue on to their account within the application.
//Define your connection
LdapConnection ldapConnection = new LdapConnection("123.456.789.10:389");
try
{
//Authenticate the username and password
using (ldapConnection)
{
//Pass in the network creds, and the domain.
var networkCredential = new NetworkCredential(Username, Password, Domain);
//Since we're using unsecured port 389, set to false. If using port 636 over SSL, set this to true.
ldapConnection.SessionOptions.SecureSocketLayer = false;
ldapConnection.SessionOptions.VerifyServerCertificate += delegate { return true; };
//To force NTLM\Kerberos use AuthType.Negotiate, for non-TLS and unsecured, use AuthType.Basic
ldapConnection.AuthType = AuthType.Basic;
ldapConnection.Bind(networkCredential);
}
catch (LdapException ldapException)
{
//Authentication failed, exception will dictate why
}
}
If you'd like to go a step further and retrieve properties about this user as well, check out this thread here.
Also, I highly recommend Softerra's LDAP Browser for testing anything LDAP related - it is a wonderful product, and it's free. You can download it from here.
Hopefully that gets you going in the right direction.
I am using the following code in c# to download a file from my website:
WebClient webClient = new WebClient();
webClient.Credentials = new System.Net.NetworkCredential("username", "password");
webClient.DownloadFile("http://example.com/file.txt", "file.txt");
The file is only downloaded when certain criteria are met, so I don't want the users to be able to access the files on my site
My corcern is that if a curios users decompiles the code, he will find the password and be able to access all the files on my site.
I've read that a secure way to save the password is to store its hash, but I don't know how to implement it in this example.
What options do I have to keep my password secure and make it impossible for a user to find it?
A sobering reality: You can't protect information contained in your program like this.
A must-do: Choose a username/password that is only for accessing the special files this single program needs - not your "access my whole website" username and password.
But just know that all you are doing is adding a little bit of an obstacle, here; anyone who wants to can examine your program and find the username and password.
The only 'correct' way to do this is to do it based on the user's own credentials; their username and password within your own system, for example. Then you would need to give them access based on that information, and your program would need to prompt them for it.
You simply don't. Users give you passwords to do stuff, not the other way around.
If the user has to prove "certain conditions", then pass proof of those certain conditions to the server, and let it decide whether to allow the download or not.
There is no way to prevent that. If you program is able to access the file under condition X, the user is able to trick the program into condition X and get the file no matter what. You can make it harder, but you can't make it impossible.
If the data are in the program itself you can considered them as already being exposed to users. If the credentials are on the users computer regardless on how many measures you take to combat this there is always a possibility to find a way around it.
What you can do is implement a login form for your program and provide the users with login info. Then when the user enters the login info do a check on the server side if the credentials exist (usually by checking in a database) and if it matches send them the file.
But as always, there is the issue with users just sharing the login info with other people and so on.
I use the forms authentication in my asp.net application and I protect all the pages using:
deny user=*
And when a user logs in, I use:
FormsAuthentication.RedirectFromLoginPage(UserName.Text, false);
Now if I use IE6 when I open a window and login it works, but then if I open a new window ,I have to login again. It seems that a new IE6 window will open a new session or cookie (I am not sure) - how can I avoid this?
There are multiple approaches. I believe the impact for the user should be as little as possible.
You could store the last logged in, or last database action timestamp in your database. Doing so, you can verify if the last action the user had was within a number of minutes. Additionally, you could store the username ( not password ) in a cookie on the client. Next time the client opens a new session, you know the username, verify on database that the last database activity was within a number of minutes, and bypass the login obligation.
Second approach involves changing startup parameters of the clients browser, so that new windows share the session. I do not know whether this is available on all browers ( and versions ) and if you are capable of doing this.
redesign your web application so new windows don't need to be opened, unless they are from within the opened window. If they are opened from an existing, logged in window, you can send a hash key in query string, which bypasses the login procedure.
These are just a few possibilities which come to mind at this point.. If you should require more possibilities, just ask :-)
Do you mean deny user="?"? * means all users, while ? means anonymous users.