In C# How to get Windows Credentials from credential manager - c#

Every where they are giving answers for getting user......but i want to get credentials from Credential Manager?
I have tried all the ways using .,
1.System.Security.Principal.WindowsIdentity.GetCurrent().Name
**Output:** => "DESKTOP\\India"
This is giving domain name and not credentail manager credentials.
2.I have tried below code..using credential package from nuget
var cm = new Credential();
cm.Target = "Here what i have to put????";
I got a doubt here to what i have to put in cm.target="?????"
3.Tried
Environment.UserName()
Output: "India"(This is not from credential manager credentials)
4.Tried
System.Net.CredentialCache.DefaultCredentials()
Output:
{
`Username:'',`
password:''
}
Here i think we have to send the parametred and these are also not from windows credential manager credentials.
Iam waiting for help from you folks.any help will be appreciated.

In short, Windows credentials under the credential manager can only obtain usernames and not passwords. This is determined by the Native underlying API.
As for how to get the usernames in Windows Credential, please refer to the below link.
https://github.com/AdysTech/CredentialManager
The usage (the target parameter means the target network/internet address, namely the name in the left side):
//get the username of "a" credential. username:b, password:123456
var result=CredentialManager.GetCredentials("a", CredentialManager.CredentialType.Windows);
Console.WriteLine(result.UserName+": "+result.Password);
Result.
Here is a discussion related to this subject.
Retrieve credentials from Windows Credentials Store using C#
wish it is useful to you.

The original answer is confusing. It seems to say only usernames can be retrieved then links a project that can retrieve full credentials. I know this is tagged ASP, but it's also tagged C#. I've had minimal experience with ASP, but the code-behind shouldn't work any differently (and the answer above says nothing about it).
I've been retrieving stored credentials for some time now with PowerShell. Just now, I needed a C# solution (and I can't use that PS package with my project).
https://github.com/meziantou/Meziantou.Framework
Nothing special, but I wrote this now to confirm it worked. StoredCredentialName is the "Internet or network address" field for a generic credential.
Private Function GetCredentialFromStorage() As Net.NetworkCredential
Try
Dim c = Meziantou.Framework.Win32.CredentialManager.ReadCredential(StoredCredentialName)
Return New Net.NetworkCredential(c.UserName, c.Password)
Catch ex As Exception
Return Nothing
End Try
End Function

Related

Azure Function fails to find file

I have an azure function that uses the Azure context. When I execute my function from visual studio 2019 on my machine, it executes correctly. However when I publish this to my Azure account, I get an error that the my.azureauth file cannot be found.
Could not find file 'D:\Program Files (x86)\SiteExtensions\Functions\2.0.12950\32bit\my.azureauth'
The code that is used:
var authFilePath = "my.azureauth";
Console.WriteLine($"Authenticating with Azure using credentials in file at {authFilePath}");
azure = Azure.Authenticate(authFilePath).WithDefaultSubscription();
sub = azure.GetCurrentSubscription();
Console.WriteLine($"Authenticated with subscription '{sub.DisplayName}' (ID: {sub.SubscriptionId})");
This is code that I found on one of the Microsoft tutorials. I have set my my.azureauth file to "Copy Always".
Could anyone point my in the right direction?
You are get this file path because the Directory.GetCurrentDirectory() would return D:\Program Files (x86)\SiteExtensions\Functions\2.0.12950\32bit instead of D:\home\site\wwwroot\ or D:\home\site\wwwroot\FunctionName.
And if you want to get the wwwroot folder or the function app directory you should use ExecutionContext. Further more information you could refer to this wiki doc.
So the right file path should be context.FunctionDirectory+"\my.azureauth" or context.FunctionAppDirectory+"\my.azureauth", which one to use depends on where your file is stored.
I have found that Kudu is extremely useful in seeing what has been deployed to Azure.
Navigate to your function in the Azure portal.
The instructions here will help get to the kudu console.
https://www.gslab.com/blogs/kudu-azure-web-app
From there you can browse the files which have been deployed into your function's file system.
If you add " , ExecutionContext context)" at the end of the function's run entry point, you can then get the folder which your function is running from with "var path = context.FunctionAppDirectory;
PS apologies for any formatting I am editing this on my phone.
Welcome to Stackoverflow.
Firstly, I'd recommend strongly against using file-based authentication as shown in your question.
From notes:
Note, file-based authentication is an experimental feature that may or may not be available in later releases. The file format it relies on is subject to change as well.
Instead, I would personally store the connection string details (AzureCredentials) in the config file (Web/SiteSettings) and use the provided constructor...
Again, the below are taken from the documentation notes:
Similarly to the file-based approach, this method requires a service principal registration, but instead of storing the credentials in a local file, the required inputs can be supplied directly via an instance of the AzureCredentials class:
var creds = new AzureCredentialsFactory().FromServicePrincipal(client, key, tenant, AzureEnvironment.AzureGlobalCloud);
var azure = Azure.Authenticate(creds).WithSubscription(subscriptionId);
or
var creds = new AzureCredentialsFactory().FromServicePrincipal(client, pfxCertificatePath, password, tenant, AzureEnvironment.AzureGlobalCloud);
var azure = Azure.Authenticate(creds).WithSubscription(subscriptionId);
where client, tenant, subscriptionId, and key or pfxCertificatePath and password are strings with the required pieces of information about your service principal and subscription. The last parameter, AzureEnvironment.AzureGlobalCloud represents the Azure worldwide public cloud. You can use a different value out of the currently supported alternatives in the AzureEnvironment enum.
The first example is most likely the one you should be looking at.
The notes I got this information from can be accessed here.
If you have some problems with AAD, these screenshots may help you.
Client ID:
Key:
Please note that the Key value can only be copied when it is created, after which it will be hidden.
Hope this helps you get started with AAD quickly.

Get domain UserName for computer that not in domain

I hope somebody could help me to solve my problem.
There is some domain, and some shared directory in that domain. User has domain username and password, to get access to that shared directory, but his computer is not in domain most of time. I mean, when he need to connect to that directory he is typing network path (for example "\\fileserver"), than windows asks for username and password, and after writing it he will get the access until restart windows or logout.
So my question is, how can i get domain user name that user uses to connect to network, by using C# code?
I tryed to use CredentialCache.GetCredential, but i think it works only if user connect to shared directory by using NetworkCredentials in C# program. If connection already was before C# program started, it will be empty.
I also tryed Environment.UserName, but since computer is not in domain, it returns only local user name, that different from domain username.
Sorry for my bad english, i hope you could understand my explanation.
Have you took a look at the nugget package CredentialManagement ?
I used it already, but couldn't roam credential saved with enterprise persistence
using CredentialManagement;
using (CredentialSet credentials = new CredentialSet())
{
Debug.Print(credentials.Count.ToString() + " credential(s) found.");
foreach (Credential credential in credentials)
{
Debug.Print(credential.Target); //This is domain/IP of the saved credential.
Debug.Print(credential.Type.ToString());
Debug.Print(credential.Username);
Debug.Print(credential.PersistanceType.ToString());
Debug.Print(credential.Description);
Debug.Print(credential.LastWriteTime.ToString());
}
Debug.Print("End");
}

C# UserPrincipal.ChangePassword for local accounts is broken after KB3167679 and KB3177108

Since Microsoft release the two following patches, my C# code just stopped working and always sends back an error message (The system cannot contact a domain controller to service the authentication request. Please try again later.) when trying to change the password.
https://support.microsoft.com/en-us/kb/3167679
https://support.microsoft.com/en-us/kb/3177108
private void ChangePassword(string username, string oldPassword, string newPassword)
{
string machineName = Environment.MachineName;
string contextUser = String.Format(#"{0}\{1}", machineName, username);
using (PrincipalContext ctx = new PrincipalContext(ContextType.Machine, machineName, null, ContextOptions.Negotiate, contextUser, oldPassword))
using (UserPrincipal user = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, username))
{
user.ChangePassword(oldPassword, newPassword);
}
}
If the submitted credential is not valid, i get a specific error message saying bad username or password so the submitted credential is valid.
I tried many scenarios and they all fail:
Use the user/password of the user i want to change its password for the PrincipalContext.
Use a different user/password for the PrincipalContext.
User a local admin user/password for the PrincipalContext.
None works.
Read a lot about this "new behavior" and i can't seem to find a way to change a valid, not locked, not disabled local user.
Those posts are similar to mine and it seems like some people got a workaround but only for Active Directory and not local user accounts.
C# Active Directory Invoke “ChangePassword” cannot contact domain
Changing Active Directory user passwords in c#/asp.net after MS patch KB3167679
c# Change AD password Directoryservices
Can anyone tell me what's wrong with my code and explain me why it broke since the patches please?
If you just want to change the password for a local user you should be able to use NetUserChangePassword.
That still works for me. At least for the local machine (use the name of that as the domain name parameter).
Microsoft has updated this article: https://support.microsoft.com/en-us/kb/3177108 . Here they have given us problems created by the original "fixes" as well as some tips for working with Kerberos and self-service password reset.
As of October 11, 2016 Microsoft re-released the patches associated with https://technet.microsoft.com/en-us/library/security/ms16-101.aspx to resolve issues caused by the original updates (which you can read in https://support.microsoft.com/en-us/kb/3177108 including the fact that you could no longer change passwords on local accounts-- see "known issue #3").
So in short you should be able to change local passwords now with the latest updates (October 11, 2016).

problem connecting to Active Directory server in C# .NET

I'm currently writing some software in C# which needs to connect to an AD server and get some user details. When I connect using the code below it works against most AD servers that I connect to but there are a couple where it fails with an error of "Logon failure: unknown user name or bad password.". The server name / credentials I'm using are definately correct as I've tested them with an LDAP Browser and the AD server is using standard security (port 389 etc). Can anyone offer any advice?
Cheers
Tim
DirectoryEntry d = new DirectoryEntry("LDAP://" + domain, admin_username, admin_password);
try
{
object x = d.NativeObject;
}
catch
{
throw;
}
I've had similar issues programming .net / AD in the past. One thing I found useful is using an LDAP viewer to see if I can connect to certain servers, etc. In this way, I can at least determine if it is a .NET error (perhaps my code), a credential error, etc.
I use the free/lite version of Softerra's LDAP viewer (http://www.ldapbrowser.com/download.htm) although I'm sure there are many others to choose from out there. If you try the one listed here, make sure to download the 'LDAP browser' and not 'LDAP Administrator'. The browser is the free one.
Try connecting to the same LDAP path you're having trouble with in code, using a LDAP browser/viewer. This will at least as step one determine if it is a .NET/code issue or not. If you can't connect via the browser, it can be helpful to play around with the connection options, such as port, domain (FQDN), etc.
Hope this might help narrow things down.
Active Directory allows at least three different logon name styles:
LDAP - i.e. LDAP DN. For example: cn=JohnS, ou=Users, dc=example, dc=com
NTLM. For example: EXAMPLE\JohnS
Kerberos principal name: For example: johns#example.com
However, you cannot login with just JohnS like you do with Windows box. It's a very common mistake.

How should I validate a user's credentials against an ADAM instance over SSL?

Apologies in advance as I haven't had much experience with directories before.
I have an ASP.net application, and I have to validate its users against an Active Directory Application Mode instance running on Server 2k3. I was previously attempting a connection with DirectoryEntry and catching the COMException if the user's credentials (userPrincipalName & password) were wrong, but I had a number of problems when trying to bind as users who weren't a member of any ADAM groups (which is a requirement).
I recently found the System.DirectoryServices.AccountManagement library, which seems a lot more promising, but although it works on my local machine, I'm having some troubles when testing this in our testbed environment. Chances are I'm simply misunderstanding how to use these objects correctly, as I wasn't able to find any great documentation on the matter. Currently I am creating a PrincipalContext with a Windows username and password, then calling the AuthenticateCredentials with the user's userPrincipalName and password. Here's a very short exert of what I'm doing:
using (var serviceContext = new PrincipalContext(
ContextType.ApplicationDirectory,
serverAddress,
rootContainer,
ContextOptions.Negotiate | ContextOptions.SecureSocketLayer,
serviceAccountUsername,
serviceAccountPassword)) {
bool credentialsValid = serviceContext.ValidateCredentials(userID, password, ContextOptions.SecureSocketLayer | ContextOptions.SimpleBind)
}
If the user's credentials are valid, I then go on to perform other operations with that principal context. As I said, this works for both users with and without roles in my own environment, but not in our testbed environment. My old DirectoryEntry way of checking the user's credentials still works with the same configuration.
After a very long morning, I was able to figure out the problem!
The exception message I was receiving when calling ValidateCredentials was extremely vague. After installing Visual Studio 2008 in the test environment (which is on the other side of the country, mind you!), I was able to debug and retrieve the HRESULT of the error. After some very deep searching in to Google, I found some very vague comments about "SSL Warnings" being picked up as other exceptions, and that enabling "SCHANNEL logging" (which I'm very unfamiliar with!) might reveal some more insight. So, after switching that on in the registry and retrying the connection, I was presented with this:
The certificate received from the remote server does not contain the expected name. It is therefore not possible to determine whether we are connecting to the correct server. The server name we were expecting is ADAMServer. The SSL connection request has failed. The attached data contains the server certificate.
I found this rather strange, as the old method of connecting via SSL worked fine. In any case, my co-worker was able to spot the problem - the name on the SSL certificate that had been issued on the server was that of the DNS name ("adam2.net") and not the host name ("adamserver"). Although I'm told that's the norm, it just wasn't resolving the correct name when using PrincipalContext.
Long story short; re-issuing a certificate with the computer name and not the DNS name fixed the problem!

Categories