lithnet / windows-credential-provider

A library for creating secure Windows Credential Providers in .NET
MIT License
18 stars 5 forks source link

Windows Credential Provider

A library for creating secure Windows Credential Providers in .NET, without the COM complications.

The Lithnet Credential Provider for Windows provides an easy way to create a credential provider, without having to implement the COM components. The COM components are still there, but abstracted away into a fully managed implementation.

Getting started

<PropertyGroup>
    <TargetFramework>net6.0-windows</TargetFramework>
    <RegisterForComInterop>false</RegisterForComInterop>
    <Platform>x64</Platform>
    <EnableComHosting>true</EnableComHosting>
</PropertyGroup>
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("MyCredentialProvider")]
[Guid("00000000-0000-0000-0000-000000000000")]
public class MyCredentialProvider : CredentialProviderBase
{
}
public override bool IsUsageScenarioSupported(UsageScenario cpus, CredUIWinFlags dwFlags)
{
    switch (cpus)
    {
        case UsageScenario.Logon:
        case UsageScenario.UnlockWorkstation:
        case UsageScenario.CredUI:
        case UsageScenario.ChangePassword:
            return true;

        default:
            return false;
    }
}

public override bool ShouldIncludeGenericTile() { return true; }

public override CredentialTile CreateGenericTile() { return new MyTile(this); }

public override CredentialTile2 CreateUserTile(CredentialProviderUser user) { return new MyTile(this, user); }


* Create your tile class. Inherit from `CredentialTile2` if you want to create personalized tiles supported by Windows 8 and later, or `CredentialTile1` if you only want to implement a generic tile. Grab the instances of your controls in the `Initialize` method, so you can attach to their properties to read and respond to value changes. Finally, override the `GetCredentials` method, which is called when the user clicks the submit button.

```cs
public class MyTile : CredentialTile2
{
    private TextboxControl UsernameControl;
    private SecurePasswordTextboxControl PasswordControl;
    private SecurePasswordTextboxControl PasswordConfirmControl;

    public MyTile(CredentialProviderBase credentialProvider) : base(credentialProvider)
    {
    }

    public MyTile(CredentialProviderBase credentialProvider, CredentialProviderUser user) : base(credentialProvider, user)
    {
    }

    public string Username
    {
        get => UsernameControl.Text;
        set => UsernameControl.Text = value;
    }

    public SecureString Password
    {
        get => PasswordControl.Password;
        set => PasswordControl.Password = value;
    }

    public SecureString ConfirmPassword
    {
        get => PasswordConfirmControl.Password;
        set => PasswordConfirmControl.Password = value;
    }

    public override void Initialize()
    {
        if (UsageScenario == UsageScenario.ChangePassword)
        {
            this.PasswordConfirmControl = this.Controls.GetControl<SecurePasswordTextboxControl>("ConfirmPasswordField");
        }

        this.PasswordControl = this.Controls.GetControl<SecurePasswordTextboxControl>("PasswordField");
        this.UsernameControl = this.Controls.GetControl<TextboxControl>("UsernameField");

        Username = this.User?.QualifiedUserName;
    }

    protected override CredentialResponseBase GetCredentials()
    {
        string username;
        string domain;

        if (Username.Contains("\\"))
        {
            domain = Username.Split('\\')[0];
            username = Username.Split('\\')[1];
        }
        else
        {
            username = Username;
            domain = Environment.MachineName;
        }

        var spassword = Controls.GetControl<SecurePasswordTextboxControl>("PasswordField").Password;

        return new CredentialResponseSecure()
        {
            IsSuccess = true,
            Password = spassword,
            Domain = domain,
            Username = username
        };
    }
}

* Build your project and you have a functional credential provider!

Installing the credential provider

You can use the traditional methods of registering a credential provider (regasm, regsvr32, create registry keys etc), but we've provided a PowerShell module to automatically register your credential provider with a single command.

Install-Module Lithnet.CredentialProvider.Management
Register-CredentialProvider -File C:\path-to-your-provider.dll

You can disable, enable, and uninstall the provider with the following commands

Disable-CredentialProvider -File "C:\path-to-your-provider.dll"
Enable-CredentialProvider -File "C:\path-to-your-provider.dll"
Unregister-CredentialProvider -File "C:\path-to-your-provider.dll"

Once the credential provider is registered, you can use the Invoke-CredUI cmdlet provided as part of the module, to bring up CredUI window and render your credential provider.

How can I contribute to the project?

Enteprise support

Enterprise support is not currently offered for this product.

Keep up to date