I'd like to utilize the Windows Authentication Model for authenticating users that use my C# 3.5 WinForms application:
The user that has logged on Windows is automatically logged in to my application.
If the user wants to log in explicitely, his user name and password should be checked by Windows, or even better, prompted by Windows with a standard Windows Dialog. The outcome should be another WindowsIdentity object.
The first was very easy to solve long time ago: I read the
WindowsIdentity identity = WindowsIdentity.GetCurrent();
Just to make sure, I check for the
if (identity.IsAuthenticated) { ... }
For the second case I've found some API calls in other SO Q&A's, but I'm pretty sure there must be a managed way for that, am I wrong?
Further I wonder whether my approach for 1. is save and appropriate. Thanks for your feedback!
Update: According to Ivan, I have to use the P/Invoke approach. This is basically alright, but then I still need a way to retrieve a WindowsIdentity object for that certain user, which has its IsAuthenticated property set to true. The P/Invoke call in itself doesn't return such an object. How can this be done?
I am not certain about this but it looks like you want to use the WindowsIdentity Ctor that takes an IntPtr. To get the parameter that is passed into this constructor you can PInvoke the Win32 API LogonUser() function. This will give you a WindowsIdentity for this user.
There is no managed way of doing this, you have to do pinvoke (api call) as you said. Approach #1 is totaly ok ... trust microsoft :)
Related
Is there a way to get the privileges associated with a C# program? If yes, how?
I know that in C, you have to create a token and make use of the GetTokenInformation() method to get information about the token.
Is there something similar in C#?
My C# is a little rusty, but if i remember correctly this does the trick
WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent();
I'd like to use C# to authenticate a username and password through SMF (Simple Machines Forum). I was wondering if there is a secure way to send a username and password string through HTTPWebRequest that can be easily combined with SMF's authentication system, unless there is a better way (I do not want to use direct mySQL access).
What I am thinking of is something like, on the server side, check if the login is successful. If so, it will echo a certain string "true" and "false".
I've taken a look at the "verification hooks", but I'm not sure how to use them. I also took a look at the login scripts and saw that there's quite a bit of security behind it. Does SMF have any sort of API that can isolate just the login authentication and return a true/false?
Thanks.
There's a quasi RESTful API for SMF 2.x here:
http://www.simplemachines.org/community/index.php?topic=458832.0
One of the functions will validate your login for you. If you need to expand it to do other things it can easily be done.
I want to write a application in C# using WMI that can get and change Windows credential stored in the Windows Credential Manager, as you see in the picture below:
Ookii.Dialogs contains a credential dialog, which calls into CredUIPromptForCredentials or CredUIPromptForWindowsCredentials as appropriate.
Edit: The Credentials API is detailed at http://msdn.microsoft.com/en-us/library/aa374731%28v=VS.85%29.aspx#credentials_management_ui_functions - but it could be tricky to implement from managed code. After CredUIPromptForWindowsCredentials you would call CredWrite to save the credentials.
Edit: Misunderstood the original question since the pic wasn't visible.
I'm not sure if you can do what you want via WMI. However, I think it might be possible using the DPAPI, but the documentation for that doesn't seem to make it very easy. However, there is an opensource project called NCrypto that has a class called UICredentialsHelper which might show you how to do it, or at least how to get started.
There is no Windows API to get a user's password. Passwords are not stored in Windows. Instead Windows stores a one-way hashed version.
You can get the username using WindowsIdentity.GetCurrent(). Alternatively you can get the logged in user name via the Environment.UserName property.
Although to change credentials..... good luck :) Thats my best answer on that. I don't think Microsoft would ever give us the ability to do that.
[void]Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime]
(new-object Windows.Security.Credentials.PasswordVault).RetrieveAll() | % { $.RetrievePassword(); $ }
In .NET, there appears to be several ways to get the current Windows user name. Three of which are:
string name = WindowsIdentity.GetCurrent().Name;
or
string name = Thread.CurrentPrincipal.Identity.Name;
or
string name = Environment.UserName;
What's the difference, and why choose one method over the other? Are there any other ways?
Environment.UserName calls GetUserName within advapi32.dll. This means that if you're impersonating another user, this property will reflect that.
Thread.CurrentPrincipal has a setter and can be changed programmatically. (This is not impersonation btw.)
WindowsIdentity is your current windows identity, if any. It will not necessarily reflect the user, think ASP.NET with FormsAuthentication. Then the WindowsIdentity will be the NT-service, but the FormsIdentity will be the logged in user. There's also a PassportIdentity, and you can build your own stuff to complicate things further.
You asked for alternative ways.
Of course, you can always use the native Windows API: GetUserName.
I believe the property was put in several places so that it would be easier for the programmer to find. There's only one logged in user, and only one respective name.
The three methods are described as follow:
HttpContext = HttpContext.Current.User, which returns an IPrincipal object that contains security information for the current Web request. This is the authenticated Web client.
WindowsIdentity = WindowsIdentity.GetCurrent(), which returns the identity of the security context of the currently executing Win32 thread.
Thread = Thread.CurrentPrincipal which returns the principal of the currently executing .NET thread which rides on top of the Win32 thread.
And they change in result depending on your IIS configuration as explained in this article:
http://msdn.microsoft.com/en-us/library/aa302377.aspx
We use Sharepoint as CMS for our webpages at work. I know how to create controls that can be only visible if you have logged in in SharePoint with:
<Sharepoint:SPSecurityTrimmedControl ID="SPSecurityTrimmedControl1" runat="server" PermissionsString="AddAndCustomizePages"><br />
<Sharepoint:CssLink ID="CssLink1" runat="server"/><br />
</Sharepoint:SPSecurityTrimmedControl>
But I want to know how to make controls visible (or whatever) programmatically depending on permissions.
I cannot use the methods for .NET windows form authentication like:
if (!(HttpContext.Current.User == null) && HttpContext.Current.User.Identity.IsAuthenticated){}
because we use this for anonymous users who has another type of log in.
Could you provide some code? I know that it must be something like verifying the SPContext.Current.FormContext.
How are the users authenticated? With forms authentication or Windows/active directory?
If active directory, then I think in that case you might need to get a reference to the current SPWeb, and then do web.CurrentUser.ID. This might come out null when you are anonymous. If not, try web.SiteUsers.GetByID(web.CurrentUser.ID) and see what you get.
DoesUserHavePermissions
You can use this method on the current web to check if the current user has a specific permission.
I assume your authenticated users have some permission to check for that the anonymous crowd is denied.
Although I haven't tested it, I imagine the LoginName property of the SPUser object will be blank, or throw an exception.
... of course, its never safe to presume anything when dealing w/the SharePoint OM :(