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.
Related
Can someone please assist with the following question
I want to be able to force either an NTLM logon or Kerberos logon to an Active Directory Domain controller as a separate user principle
Initially, I simply tried the Windows NET command as follows
net use \DCName\Sharename /user:DomainName\Username password01
and
net use \10.10.10.10\Sharename /user:DomainName\Username password01
the first one for Kerberos as the SPN (service principal name) can be obtained and therefore the hash to use with Kerbberos ticket encryption
The second one for NTLM as no SPN can be retrieved based on IP address and therefore fall back to NTLM
I have had very mixed results with the above, therefore I want to look for an alternative method (as I need to feed in lots or username and password to create lots of logons at the DC e.g. Kerberos or NTLM at will)
So next I tried
[system.reflection.assembly]::LoadWithPartialName('System.DirectoryServices.AccountManagement')
$D = [system.DirectoryServices.AccountManagement.ContextType]::Domain
$PC = [system.DirectoryServices.AccountManagement.PrincipalContext]$D
$M = [system.DirectoryServices.AccountManagement.ContextOptions]::Negotiate
$PC.ValidateCredentials('User01','Password01',$m)
However as one might imagine this only validated the username password combination it did not create a Kerberos TGT for the user for example (which is what I want to do when forcing a kerberos logon)
So my question is please, if there a .NET namespace when given a know username and password you can force the issuance of a TGT (for Kerberos authentication) or NTLM token, logon ?
Thanks very much in advance
EB
Why exactly are you wanting to do this?
Windows really doesn't want you to specify what protocol to use and instead just wants you to use Negotiate so it can safely move to better and more secure protocols without impacting apps.
That philosophy has mostly bubbled up through the major frameworks, so you're not going to get dedicated API's for each protocol.
That said, you can call directly in to SSPI specifically passing in "Kerberos" or "NTLM".
The gist of this is:
Client:
AcquireCredentialsHandle(..."Kerberos"...) ->
InitiateSecurityContext(..."spn/kerb.host"...) => server
Server:
AcquireCredentialsHandle(..."Kerberos"...) ->
AcceptSecurityContext(...iscTicket...)
I'm still trying to tinker around with the new ASP.NET Core MVC6 (former vNext). This time I tried to implement my authentication against an Active Directory instead of an Entity-Framework Database.
Since I found so little Documentation, I took the very well done ASP.NET-Template and started to alter it for my needs.
I also use ReSharper to decompile the Parts, since I'm really interested in the Details.
To not go too much into the details, I'm a bit worried I'm doing not the stuff Microsoft intended:
I left the SignInManager as it is and removed the UserManager, since
return await _signInManager.PasswordSignInAsync(model.UserName, model.Password, false, false);
Internally calls the UserManager. Now it gets quite tricky: To provide an alternative store to Entity Framework I need to implement
IUserPasswordStore<ApplicationUser>
Which has around 15 Methods, most of them seem never to get called for my simple Login-Check.
Furthermore, I also need to implement
IRoleStore<IdentityRole>
Which has another 10 Methods, although I don't even want Role-base Security at the moment!
Furthermore, the Verification of the Password does require a Hash, here is the decompiled Method:
protected virtual async Task<PasswordVerificationResult> VerifyPasswordAsync(IUserPasswordStore<TUser> store, TUser user, string password)
{
string hashedPassword = (string) await store.GetPasswordHashAsync(user, this.CancellationToken);
return hashedPassword != null ? this.PasswordHasher.VerifyHashedPassword(user, hashedPassword, password) : PasswordVerificationResult.Failed;
}
According to other SO-Threads, there is no way to get the Password of the AD, so I can't implement that properly as well.
I think the way to go would be to overwrite the SignInManager as well, but this seems to get quite a huge amount of Code, the most not even needed. Also the 2 Store-Interfaces seem to hurt SOLID quite alot, since the interfaces are so big.
Am I dong there something fundamentally wrong?
The reason we don't provide an AD version is security.
By implementing one you either now have an AD open to brute force attacks, because you're not disabling accounts (as that could take admin rights, and no-one should run their web app as a domain admin), or you do disable accounts and now, with a few requests I can lock out your users out of AD, which not only affects your web app, but their desktop computers.
Now add on top that in case of a breach I am now authenticated to your AD and, well, that will make attackers happy, but not your network admins.
As an aside, the password check doesn't need hashed passwords, simply authenticate against AD inside VerifyPasswordAsync and return the appropriate result.
My recommendation is either you look at integrated authentication if you are running in an intranet only environment, or Windows Azure AD if you are wanting to run in the cloud. Both of those are markedly more secure than attempting to leverage AD into an HTML forms based scheme.
I have coded a C# Web API application and some of the calls require the user to be logged in.
Here is my current code to log the user in:
[InitializeSimpleMembership]
public bool TestLogon(string userName, string password, bool rememberMe)
{
return WebSecurity.Login(userName, password, persistCookie: rememberMe);
}
My question is this:
How secure is the above call? Is the above code secure enough for a commercial application, and if not, how can the code be improved? Do I need to implement any sort of AntiForgeryToken?
Thanks in advance
please see my answers below.
1. How secure is the above call
Because, by default, the credentials are not encrypted, so if there isn't any encryption in place like SSL to protect communication, the data will not be secure. More details from here
2. Is the above code secure enough for a commercial application, and if not, how can the code be improved?
Like the other has suggested, you'de better to use Token-Based security, and enable SSL communication. This link is really useful
3. Do I need to implement any sort of AntiForgeryToken?
Yes, you will have to prevent cross site request forgery attacks.
Hope this help.
We are currently using forms auth as follows:
FormsAuthentication.SetAuthCookie(userId, rememberMe);
With that we can always get the user id. And we were able to get the user details when you need them using the user id.
With a web service call like
objRegisteredUser = CMembership.GetByLoginID(sLoginID);
We know need to upgrade the site with the new APIS service calls that require the users Password like this:
objRegisteredUser = CMembership.GetByLoginIDandPasword(sLoginID, sPassword);
For the "remember" me function, what would be the best way to remember the password?
Could we encrypt it, then store it in a cookie, then retrieve and decrypt?
We can't populate the new profile without the password.
Any suggestions?
Does storing password data, even encrypted go against best practices?
Passwords should always be stored using a one-way encryption algorithm (SHA). This means you will not be able to retrieve the underlying password. You will only have access to the hashed value.
You can use membership class in asp.net
http://msdn.microsoft.com/en-us/library/ff648345.aspx
The "remember me" button should be used to determine whether or not a cookie should be placed on the user's machine. This is how other developers accomplish your requirement. See below question on SO for further details:
What is the best way to implement "remember me" for a website?
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(); $ }