Cleans up static loggers

Adds test projects for different frameworks and architectures
Adds registration tool assembly
This commit is contained in:
Ryan Newington
2023-01-29 17:30:37 +11:00
parent 4366b24e63
commit 1205f217b3
46 changed files with 1589 additions and 200 deletions
@@ -0,0 +1,23 @@
namespace Lithnet.CredentialProvider.Samples
{
internal static class ControlKeys
{
internal const string LabelCredentialProvider = "LabelCredentialProvider";
internal const string ImageCredentialProvider = "ImageCredentialProvider";
internal const string LabelLargeHeading = "LabelHeadingLarge";
internal const string LabelSmallHeading = "LabelHeadingSmall";
internal const string Username = "TextUsername";
internal const string CommandLinkUsername = "CommandLinkUsername";
internal const string Password = "TextPassword";
internal const string ConfirmPassword = "TextPasswordConfirm";
internal const string Checkbox = "Checkbox";
internal const string LabelCheckboxValue = "LabelCheckbox";
internal const string CommandLinkCheckboxValue = "CommandLinkCheckbox";
internal const string ImageUserTile = "UerTileImage";
internal const string Combobox = "Combobox";
internal const string LabelComboboxSelectedItem = "ComboSelectedItemLabel";
internal const string CommandLinkComboboxAdd = "CommandLinkComboboxAdd";
internal const string CommandLinkComboboxRemove = "CommandLinkComboboxRemove";
internal const string ButtonSubmit = "SubmitButton";
}
}
@@ -0,0 +1,50 @@
# Using the sample credential provider
## Installing the sample
In order to install and run the sample app, you have to register the COM component
Build the EXE, and from an elevated command prompt, change to the bin folder, and run the following commands
```
SETLOCAL
SET CLSID={4EB911FA-CA18-40EA-86DF-19AFF5D1DA58}
SET BinaryPath=D:\dev\git\lithnet\windows-credential-provider\src\samples\Lithnet.CredentialProvider.Sample.net472.x64\bin\Debug\net472\Lithnet.CredentialProvider.Sample.net472.x64.dll
REM %windir%\Microsoft.NET\Framework64\v4.0.30319\regasm /codebase "Lithnet.CredentialProvider.Sample.net472.x64.dll"
REG ADD "HKLM\SOFTWARE\Classes\CLSID\%CLSID%" /ve /t REG_SZ /f /d "Lithnet.CredentialProvider.Samples.TestCredentialProvider"
REG ADD "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}"
REG ADD "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\InprocServer32" /ve /t /REG_SZ /f /d "mscoree.dll"
REG ADD "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\InprocServer32" /v "ThreadingModel" /t REG_SZ /f /d "Both"
REM REG ADD "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\InprocServer32" /v "Class" /t REG_SZ /f /d "Both"
REG ADD "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\InprocServer32" /v "RuntimeVersion" /t REG_SZ /f /d "v4.0.30319"
REG ADD "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\InprocServer32" /v "CodeBase" /t REG_SZ /f /d "%BinaryPath%"
REG ADD "HKLM\SOFTWARE\Classes\Lithnet.CredentialProvider.Sample.net472.x64" /ve /t REG_SZ /f /d "Lithnet.CredentialProvider.Samples.TestCredentialProvider"
REG ADD "HKLM\SOFTWARE\Classes\Lithnet.CredentialProvider.Sample.net472.x64\CLSID" /ve /t REG_SZ /f /d "%CLSID%"
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\%CLSID%" /ve /t REG_SZ /f /d "Lithnet.CredentialProvider.Sample.net472.x64"
```
## Disable the sample
To disable the credential provider, run the following command.
```
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{4eb911fa-ca18-40ea-86df-19aff5d1da58"}" /v "Disabled" /t REG_DWORD /f /d 1
```
## Re-enable the sample
To enable the provider again after disabling it, run the following command.
```
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{4eb911fa-ca18-40ea-86df-19aff5d1da58"}" /v "Disabled" /t REG_DWORD /f /d 0
```
## Uninstalling the sample
To remove the credential provider, run the following command.
```
%windir%\Microsoft.NET\Framework64\v4.0.30319\regasm /u "Lithnet.CredentialProvider.Sample.net472.x64.dll"
REG DELETE "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{4eb911fa-ca18-40ea-86df-19aff5d1da58"}" /f
```
@@ -0,0 +1,36 @@
using Microsoft.Extensions.Logging;
using NLog;
using NLog.Extensions.Logging;
namespace Lithnet.CredentialProvider.Samples
{
internal static class InternalLogger
{
internal static ILoggerFactory LoggerFactory { get; }
static InternalLogger()
{
/*
This sample uses NLog to capture trace events from the provider, but you can use any
logging system compatible with Microsoft.Extensions.Logging;
*/
var config = new NLog.Config.LoggingConfiguration();
var logconsole = new NLog.Targets.ConsoleTarget("logconsole");
/*
Add file based logging if required
*/
var logfile = new NLog.Targets.FileTarget("logfile") { FileName = "c:\\file.txt" };
config.AddRule(NLog.LogLevel.Trace, NLog.LogLevel.Fatal, logfile);
config.AddRule(NLog.LogLevel.Trace, NLog.LogLevel.Fatal, logconsole);
LogManager.Configuration = config;
InternalLogger.LoggerFactory = new NLogLoggerFactory(new NLogLoggerProvider(new NLogProviderOptions() { ReplaceLoggerFactory = true }, LogManager.LogFactory));
}
}
}
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<RegisterForComInterop>false</RegisterForComInterop>
<Platform>x64</Platform>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Lithnet.CredentialProvider" Version="1.0.0-beta.26" />
<PackageReference Include="NLog" Version="5.1.1" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.1" />
</ItemGroup>
</Project>
@@ -0,0 +1,73 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Lithnet.CredentialProvider.Samples {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Lithnet.CredentialProvider.Sample.Net472.x64.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap TileIcon {
get {
object obj = ResourceManager.GetObject("TileIcon", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}
@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="TileIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\TileIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

@@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Microsoft.Extensions.Logging;
namespace Lithnet.CredentialProvider.Samples
{
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("Lithnet.CredentialProvider.Sample.net472.x64")]
[Guid("4eb911fa-ca18-40ea-86df-19aff5d1da58")]
public class TestCredentialProviderNet472x64 : CredentialProviderBase
{
public static void SelfRegister()
{
CredentialProviderRegistrationServices.RegisterCredentialProvider<TestCredentialProviderNet472x64>();
}
protected override ILoggerFactory GetLoggerFactory()
{
return InternalLogger.LoggerFactory;
}
public override IEnumerable<ControlBase> GetControls(UsageScenario cpus)
{
var password = new SecurePasswordTextboxControl(ControlKeys.Password, "Password");
if (cpus == UsageScenario.ChangePassword)
{
var confirmPassword = new SecurePasswordTextboxControl(ControlKeys.ConfirmPassword, "Confirm password");
yield return new TextboxControl(ControlKeys.Username, "Username");
yield return password;
yield return confirmPassword;
yield return new SubmitButtonControl(ControlKeys.ButtonSubmit, "Submit", confirmPassword);
}
else
{
yield return new CredentialProviderLabelControl(ControlKeys.LabelCredentialProvider, "Login with showcase credential provider");
yield return new CredentialProviderLogoControl(ControlKeys.ImageCredentialProvider, "Credential provider logo", Resources.TileIcon);
yield return new CredentialProviderLogoControl(ControlKeys.ImageUserTile, "User tile image", Resources.TileIcon);
yield return new LargeLabelControl(ControlKeys.LabelLargeHeading, "The is our showcase credential provider");
yield return new SmallLabelControl(ControlKeys.LabelSmallHeading, "Let's see what we can do");
yield return new CheckboxControl(ControlKeys.Checkbox, "A checkbox");
yield return new SmallLabelControl(ControlKeys.LabelCheckboxValue, "The check box is currently unchecked");
yield return new CommandLinkControl(ControlKeys.CommandLinkCheckboxValue, "Click this link to change the check box value in code behind");
yield return new ComboboxControl(ControlKeys.Combobox, "Items to choose from:");
yield return new SmallLabelControl(ControlKeys.LabelComboboxSelectedItem, "This is the currently selected item: <none>");
yield return new CommandLinkControl(ControlKeys.CommandLinkComboboxAdd, "Add a random item to the combo box");
yield return new CommandLinkControl(ControlKeys.CommandLinkComboboxRemove, "Remove the last item from the combo box");
yield return new TextboxControl(ControlKeys.Username, "Username");
yield return new CommandLinkControl(ControlKeys.CommandLinkUsername, "Click this link to generate a random username");
yield return password;
yield return new SubmitButtonControl(ControlKeys.ButtonSubmit, "Submit", password);
}
}
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 ShouldIncludeUserTile(CredentialProviderUser user)
{
return true;
}
public override bool ShouldIncludeGenericTile()
{
return true;
}
public override CredentialProviderCredential1Tile CreateGenericTile()
{
return new TestCredentialProviderTile(this);
}
public override CredentialProviderCredential1Tile CreateUserTile(CredentialProviderUser user)
{
return new TestCredentialProviderTile(this, user);
}
}
}
@@ -0,0 +1,192 @@
using System;
using System.Runtime.InteropServices;
using System.Security;
using Microsoft.Extensions.Logging;
namespace Lithnet.CredentialProvider.Samples
{
public class TestCredentialProviderTile : CredentialProviderCredential2Tile
{
private TextboxControl UsernameControl;
private SecurePasswordTextboxControl PasswordControl;
private SecurePasswordTextboxControl PasswordConfirmControl;
private ComboboxControl ComboboxControl;
private CheckboxControl CheckboxControl;
private SmallLabelControl CheckboxStateControl;
private SmallLabelControl ComboboxStateControl;
private ILogger logger = InternalLogger.LoggerFactory.CreateLogger<TestCredentialProviderTile>();
public TestCredentialProviderTile(CredentialProviderBase credentialProvider) : base(credentialProvider)
{
}
public TestCredentialProviderTile(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 string ComboboxSelectedItemLabel
{
get => ComboboxStateControl.Label;
set => ComboboxStateControl.Label = value;
}
public bool IsChecked
{
get => CheckboxControl.IsChecked;
set => CheckboxControl.IsChecked = value;
}
public string CheckboxStateLabel
{
get => CheckboxStateControl.Label;
set => CheckboxStateControl.Label = value;
}
public override void Initialize()
{
if (UsageScenario == UsageScenario.ChangePassword)
{
PasswordConfirmControl = Controls.GetControl<SecurePasswordTextboxControl>(ControlKeys.ConfirmPassword);
}
PasswordControl = Controls.GetControl<SecurePasswordTextboxControl>(ControlKeys.Password);
CheckboxControl = Controls.GetControl<CheckboxControl>(ControlKeys.Checkbox);
CheckboxStateControl = Controls.GetControl<SmallLabelControl>(ControlKeys.LabelCheckboxValue);
Controls.GetControl<CommandLinkControl>(ControlKeys.CommandLinkCheckboxValue).OnClick = () =>
{
CheckboxControl.IsChecked = !CheckboxControl.IsChecked;
};
CheckboxControl.PropertyChanged += CheckboxControl_PropertyChanged;
UsernameControl = Controls.GetControl<TextboxControl>(ControlKeys.Username);
Controls.GetControl<CommandLinkControl>(ControlKeys.CommandLinkUsername).OnClick = () =>
{
Username = Guid.NewGuid().ToString();
};
ComboboxStateControl = Controls.GetControl<SmallLabelControl>(ControlKeys.LabelComboboxSelectedItem);
ComboboxControl = Controls.GetControl<ComboboxControl>(ControlKeys.Combobox);
ComboboxControl.PropertyChanged += ComboboxControl_PropertyChanged;
ComboboxControl.ComboBoxItems.Add("Item 1");
ComboboxControl.ComboBoxItems.Add("Item 2");
ComboboxControl.ComboBoxItems.Add("Item 3");
ComboboxControl.SelectedItemIndex = 0;
int count = 3;
Controls.GetControl<CommandLinkControl>(ControlKeys.CommandLinkComboboxAdd).OnClick = () =>
{
ComboboxControl.ComboBoxItems.Add($"Item {++count}");
};
Controls.GetControl<CommandLinkControl>(ControlKeys.CommandLinkComboboxRemove).OnClick = () =>
{
if (ComboboxControl.ComboBoxItems.Count > 0)
{
ComboboxControl.ComboBoxItems.Remove(ComboboxControl.ComboBoxItems[ComboboxControl.ComboBoxItems.Count - 1]);
}
};
Username = User?.QualifiedUserName;
}
private void ComboboxControl_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(ComboboxControl.SelectedItemIndex))
{
ComboboxSelectedItemLabel = $"Selected item: {(ComboboxControl.SelectedItem ?? "(none)")}";
}
}
private void CheckboxControl_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
CheckboxStateControl.Label = $"The check box is {(CheckboxControl.IsChecked ? "checked" : "not checked")}";
}
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>(ControlKeys.Password).Password;
if (!IsChecked)
{
logger.LogTrace("Performing secure login");
return new CredentialResponseSecure()
{
IsSuccess = true,
Password = spassword,
Domain = domain,
Username = username
};
}
else
{
logger.LogTrace("Performing insecure login");
string plainTextPassword = GetPlainTextPasswordFromSecureString(spassword);
return new CredentialResponseInsecure()
{
IsSuccess = true,
Password = plainTextPassword,
Domain = domain,
Username = username
};
}
}
private string GetPlainTextPasswordFromSecureString(SecureString s)
{
string plainTextPassword;
IntPtr pPassword = IntPtr.Zero;
try
{
pPassword = Marshal.SecureStringToGlobalAllocUnicode(s);
plainTextPassword = Marshal.PtrToStringUni(pPassword);
}
finally
{
if (pPassword != IntPtr.Zero)
{
Marshal.FreeHGlobal(pPassword);
}
}
return plainTextPassword;
}
}
}
@@ -0,0 +1,36 @@
# Using the sample credential provider
## Installing the sample
In order to install and run the sample app, you have to register the COM component
Build the EXE, and from an elevated command prompt, change to the bin folder, and run the following commands
```
%windir%\Microsoft.NET\Framework\v4.0.30319\regasm /codebase "Lithnet.CredentialProvider.Sample.net472.x86.dll"
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{c9055c88-03f9-4a12-8e33-1ee75826a4a6}" /f
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{c9055c88-03f9-4a12-8e33-1ee75826a4a6}" /ve /t REG_SZ /f /d "Lithnet.CredentialProvider.Sample.net472.x86"
```
## Disable the sample
To disable the credential provider, run the following command.
```
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{c9055c88-03f9-4a12-8e33-1ee75826a4a6}" /v "Disabled" /t REG_DWORD /f /d 1
```
## Re-enable the sample
To enable the provider again after disabling it, run the following command.
```
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{c9055c88-03f9-4a12-8e33-1ee75826a4a6}" /v "Disabled" /t REG_DWORD /f /d 0
```
## Uninstalling the sample
To remove the credential provider, run the following command.
```
%windir%\Microsoft.NET\Framework\v4.0.30319\regasm /u "Lithnet.CredentialProvider.Sample.net472.x86.dll"
REG DELETE "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{c9055c88-03f9-4a12-8e33-1ee75826a4a6}" /f
```
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<RegisterForComInterop>false</RegisterForComInterop>
<Platform>x86</Platform>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Lithnet.CredentialProvider.Sample.net472.x64\InternalLogger.cs" Link="InternalLogger.cs" />
<Compile Include="..\Lithnet.CredentialProvider.Sample.net472.x64\ControlKeys.cs" Link="ControlKeys.cs" />
<Compile Include="..\Lithnet.CredentialProvider.Sample.net472.x64\TestCredentialProviderTile.cs" Link="TestCredentialProviderTile.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Lithnet.CredentialProvider" Version="1.0.0-beta.25" />
<PackageReference Include="NLog" Version="5.1.1" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.1" />
</ItemGroup>
</Project>
@@ -0,0 +1,73 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Lithnet.CredentialProvider.Samples {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Lithnet.CredentialProvider.Sample.Net472.x64.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap TileIcon {
get {
object obj = ResourceManager.GetObject("TileIcon", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}
@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="TileIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\TileIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

@@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Microsoft.Extensions.Logging;
namespace Lithnet.CredentialProvider.Samples
{
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("Lithnet.CredentialProvider.Sample.net472.x86")]
[Guid("c9055c88-03f9-4a12-8e33-1ee75826a4a6")]
public class TestCredentialProviderNet472x86 : CredentialProviderBase
{
private static readonly ILogger logger = InternalLogger.LoggerFactory.CreateLogger<TestCredentialProviderNet472x86>();
public static void SelfRegister()
{
CredentialProviderRegistrationServices.RegisterCredentialProvider<TestCredentialProviderNet472x86>();
}
protected override ILoggerFactory GetLoggerFactory()
{
return InternalLogger.LoggerFactory;
}
public override IEnumerable<ControlBase> GetControls(UsageScenario cpus)
{
var password = new SecurePasswordTextboxControl(ControlKeys.Password, "Password");
if (cpus == UsageScenario.ChangePassword)
{
var confirmPassword = new SecurePasswordTextboxControl(ControlKeys.ConfirmPassword, "Confirm password");
yield return new TextboxControl(ControlKeys.Username, "Username");
yield return password;
yield return confirmPassword;
yield return new SubmitButtonControl(ControlKeys.ButtonSubmit, "Submit", confirmPassword);
}
else
{
yield return new CredentialProviderLabelControl(ControlKeys.LabelCredentialProvider, "Login with showcase credential provider");
yield return new CredentialProviderLogoControl(ControlKeys.ImageCredentialProvider, "Credential provider logo", Resources.TileIcon);
yield return new CredentialProviderLogoControl(ControlKeys.ImageUserTile, "User tile image", Resources.TileIcon);
yield return new LargeLabelControl(ControlKeys.LabelLargeHeading, "The is our showcase credential provider");
yield return new SmallLabelControl(ControlKeys.LabelSmallHeading, "Let's see what we can do");
yield return new CheckboxControl(ControlKeys.Checkbox, "A checkbox");
yield return new SmallLabelControl(ControlKeys.LabelCheckboxValue, "The check box is currently unchecked");
yield return new CommandLinkControl(ControlKeys.CommandLinkCheckboxValue, "Click this link to change the check box value in code behind");
yield return new ComboboxControl(ControlKeys.Combobox, "Items to choose from:");
yield return new SmallLabelControl(ControlKeys.LabelComboboxSelectedItem, "This is the currently selected item: <none>");
yield return new CommandLinkControl(ControlKeys.CommandLinkComboboxAdd, "Add a random item to the combo box");
yield return new CommandLinkControl(ControlKeys.CommandLinkComboboxRemove, "Remove the last item from the combo box");
yield return new TextboxControl(ControlKeys.Username, "Username");
yield return new CommandLinkControl(ControlKeys.CommandLinkUsername, "Click this link to generate a random username");
yield return password;
yield return new SubmitButtonControl(ControlKeys.ButtonSubmit, "Submit", password);
}
}
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 ShouldIncludeUserTile(CredentialProviderUser user)
{
return true;
}
public override bool ShouldIncludeGenericTile()
{
return true;
}
public override CredentialProviderCredential1Tile CreateGenericTile()
{
return new TestCredentialProviderTile(this);
}
public override CredentialProviderCredential1Tile CreateUserTile(CredentialProviderUser user)
{
return new TestCredentialProviderTile(this, user);
}
}
}
@@ -0,0 +1,36 @@
# Using the sample credential provider
## Installing the sample
In order to install and run the sample app, you have to register the COM component
Build the EXE, and from an elevated command prompt, change to the bin folder, and run the following commands
```
regsvr32 "Lithnet.CredentialProvider.Sample.net6.0.x64.comhost.dll"
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{4cd12d80-9259-4f38-94dc-1828080ad9ff}" /f
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{4cd12d80-9259-4f38-94dc-1828080ad9ff}" /ve /t REG_SZ /f /d "Lithnet.CredentialProvider.Sample.net6.0.x64"
```
## Disable the sample
To disable the credential provider, run the following command.
```
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{4cd12d80-9259-4f38-94dc-1828080ad9ff}" /v "Disabled" /t REG_DWORD /f /d 1
```
## Re-enable the sample
To enable the provider again after disabling it, run the following command.
```
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{4cd12d80-9259-4f38-94dc-1828080ad9ff}" /v "Disabled" /t REG_DWORD /f /d 0
```
## Uninstalling the sample
To remove the credential provider, run the following command.
```
regsvr32 /u "Lithnet.CredentialProvider.Sample.net6.0.x64.comhost.dll"
REG DELETE "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{4cd12d80-9259-4f38-94dc-1828080ad9ff}" /f
```
@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<RegisterForComInterop>false</RegisterForComInterop>
<Platform>x64</Platform>
<EnableComHosting>true</EnableComHosting>
</PropertyGroup>
<ItemGroup>
<None Remove="Resources\TileIcon.png" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\Lithnet.CredentialProvider.Sample.net472.x64\InternalLogger.cs" Link="InternalLogger.cs" />
<Compile Include="..\Lithnet.CredentialProvider.Sample.net472.x64\ControlKeys.cs" Link="ControlKeys.cs" />
<Compile Include="..\Lithnet.CredentialProvider.Sample.net472.x64\TestCredentialProviderTile.cs" Link="TestCredentialProviderTile.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\TileIcon.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Lithnet.CredentialProvider" Version="1.0.0-beta.25" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
<PackageReference Include="NLog" Version="5.1.1" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.1" />
</ItemGroup>
</Project>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -0,0 +1,105 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.Extensions.Logging;
namespace Lithnet.CredentialProvider.Samples
{
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("Lithnet.CredentialProvider.Sample.net6.0.x64")]
[Guid("4cd12d80-9259-4f38-94dc-1828080ad9ff")]
public class TestCredentialProviderNet60x64 : CredentialProviderBase
{
private static readonly ILogger logger = InternalLogger.LoggerFactory.CreateLogger<TestCredentialProviderNet60x64>();
public static void SelfRegister()
{
CredentialProviderRegistrationServices.RegisterCredentialProvider<TestCredentialProviderNet60x64>();
}
protected override ILoggerFactory GetLoggerFactory()
{
return InternalLogger.LoggerFactory;
}
public override IEnumerable<ControlBase> GetControls(UsageScenario cpus)
{
var password = new SecurePasswordTextboxControl(ControlKeys.Password, "Password");
if (cpus == UsageScenario.ChangePassword)
{
var confirmPassword = new SecurePasswordTextboxControl(ControlKeys.ConfirmPassword, "Confirm password");
yield return new TextboxControl(ControlKeys.Username, "Username");
yield return password;
yield return confirmPassword;
yield return new SubmitButtonControl(ControlKeys.ButtonSubmit, "Submit", confirmPassword);
}
else
{
yield return new CredentialProviderLabelControl(ControlKeys.LabelCredentialProvider, "Login with showcase credential provider");
var image = new Bitmap(Assembly.GetExecutingAssembly().GetManifestResourceStream("Lithnet.CredentialProvider.Sample.net6.0.x64.Resources.TileIcon.png"));
yield return new CredentialProviderLogoControl(ControlKeys.ImageCredentialProvider, "Credential provider logo", image);
yield return new CredentialProviderLogoControl(ControlKeys.ImageUserTile, "User tile image", image);
yield return new LargeLabelControl(ControlKeys.LabelLargeHeading, "The is our showcase credential provider");
yield return new SmallLabelControl(ControlKeys.LabelSmallHeading, "Let's see what we can do");
yield return new CheckboxControl(ControlKeys.Checkbox, "A checkbox");
yield return new SmallLabelControl(ControlKeys.LabelCheckboxValue, "The check box is currently unchecked");
yield return new CommandLinkControl(ControlKeys.CommandLinkCheckboxValue, "Click this link to change the check box value in code behind");
yield return new ComboboxControl(ControlKeys.Combobox, "Items to choose from:");
yield return new SmallLabelControl(ControlKeys.LabelComboboxSelectedItem, "This is the currently selected item: <none>");
yield return new CommandLinkControl(ControlKeys.CommandLinkComboboxAdd, "Add a random item to the combo box");
yield return new CommandLinkControl(ControlKeys.CommandLinkComboboxRemove, "Remove the last item from the combo box");
yield return new TextboxControl(ControlKeys.Username, "Username");
yield return new CommandLinkControl(ControlKeys.CommandLinkUsername, "Click this link to generate a random username");
yield return password;
yield return new SubmitButtonControl(ControlKeys.ButtonSubmit, "Submit", password);
}
}
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 ShouldIncludeUserTile(CredentialProviderUser user)
{
return true;
}
public override bool ShouldIncludeGenericTile()
{
return true;
}
public override CredentialProviderCredential1Tile CreateGenericTile()
{
return new TestCredentialProviderTile(this);
}
public override CredentialProviderCredential1Tile CreateUserTile(CredentialProviderUser user)
{
return new TestCredentialProviderTile(this, user);
}
}
}
@@ -0,0 +1,36 @@
# Using the sample credential provider
## Installing the sample
In order to install and run the sample app, you have to register the COM component
Build the EXE, and from an elevated command prompt, change to the bin folder, and run the following commands
```
regsvr32 "Lithnet.CredentialProvider.Sample.net6.0.x86.comhost.dll"
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{90592593-f4d3-4f62-aa83-9cf1f7b590e0}" /f
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{90592593-f4d3-4f62-aa83-9cf1f7b590e0}" /ve /t REG_SZ /f /d "Lithnet.CredentialProvider.Sample.net6.0.x86"
```
## Disable the sample
To disable the credential provider, run the following command.
```
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{90592593-f4d3-4f62-aa83-9cf1f7b590e0}" /v "Disabled" /t REG_DWORD /f /d 1
```
## Re-enable the sample
To enable the provider again after disabling it, run the following command.
```
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{90592593-f4d3-4f62-aa83-9cf1f7b590e0}" /v "Disabled" /t REG_DWORD /f /d 0
```
## Uninstalling the sample
To remove the credential provider, run the following command.
```
regsvr32 /u "Lithnet.CredentialProvider.Sample.net6.0.x86.comhost.dll"
REG DELETE "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{90592593-f4d3-4f62-aa83-9cf1f7b590e0}" /f
```
@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<RegisterForComInterop>false</RegisterForComInterop>
<Platform>x86</Platform>
<EnableComHosting>true</EnableComHosting>
</PropertyGroup>
<ItemGroup>
<None Remove="Resources\TileIcon.png" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\Lithnet.CredentialProvider.Sample.net472.x64\InternalLogger.cs" Link="InternalLogger.cs" />
<Compile Include="..\Lithnet.CredentialProvider.Sample.net472.x64\ControlKeys.cs" Link="ControlKeys.cs" />
<Compile Include="..\Lithnet.CredentialProvider.Sample.net472.x64\TestCredentialProviderTile.cs" Link="TestCredentialProviderTile.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\TileIcon.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Lithnet.CredentialProvider" Version="1.0.0-beta.25" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
<PackageReference Include="NLog" Version="5.1.1" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.1" />
</ItemGroup>
</Project>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.Extensions.Logging;
namespace Lithnet.CredentialProvider.Samples
{
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("Lithnet.CredentialProvider.Sample.net6.0.x86")]
[Guid("90592593-f4d3-4f62-aa83-9cf1f7b590e0")]
public class TestCredentialProviderNet60x86 : CredentialProviderBase
{
private static readonly ILogger logger = InternalLogger.LoggerFactory.CreateLogger<TestCredentialProviderNet60x86>();
public static void SelfRegister()
{
CredentialProviderRegistrationServices.RegisterCredentialProvider<TestCredentialProviderNet60x86>();
}
protected override ILoggerFactory GetLoggerFactory()
{
return InternalLogger.LoggerFactory;
}
public override IEnumerable<ControlBase> GetControls(UsageScenario cpus)
{
var password = new SecurePasswordTextboxControl(ControlKeys.Password, "Password");
if (cpus == UsageScenario.ChangePassword)
{
var confirmPassword = new SecurePasswordTextboxControl(ControlKeys.ConfirmPassword, "Confirm password");
yield return new TextboxControl(ControlKeys.Username, "Username");
yield return password;
yield return confirmPassword;
yield return new SubmitButtonControl(ControlKeys.ButtonSubmit, "Submit", confirmPassword);
}
else
{
var image = new Bitmap(Assembly.GetExecutingAssembly().GetManifestResourceStream("Lithnet.CredentialProvider.Sample.net6.0.x86.Resources.TileIcon.png"));
yield return new CredentialProviderLabelControl(ControlKeys.LabelCredentialProvider, "Login with showcase credential provider");
yield return new CredentialProviderLogoControl(ControlKeys.ImageCredentialProvider, "Credential provider logo", image);
yield return new CredentialProviderLogoControl(ControlKeys.ImageUserTile, "User tile image", image);
yield return new LargeLabelControl(ControlKeys.LabelLargeHeading, "The is our showcase credential provider");
yield return new SmallLabelControl(ControlKeys.LabelSmallHeading, "Let's see what we can do");
yield return new CheckboxControl(ControlKeys.Checkbox, "A checkbox");
yield return new SmallLabelControl(ControlKeys.LabelCheckboxValue, "The check box is currently unchecked");
yield return new CommandLinkControl(ControlKeys.CommandLinkCheckboxValue, "Click this link to change the check box value in code behind");
yield return new ComboboxControl(ControlKeys.Combobox, "Items to choose from:");
yield return new SmallLabelControl(ControlKeys.LabelComboboxSelectedItem, "This is the currently selected item: <none>");
yield return new CommandLinkControl(ControlKeys.CommandLinkComboboxAdd, "Add a random item to the combo box");
yield return new CommandLinkControl(ControlKeys.CommandLinkComboboxRemove, "Remove the last item from the combo box");
yield return new TextboxControl(ControlKeys.Username, "Username");
yield return new CommandLinkControl(ControlKeys.CommandLinkUsername, "Click this link to generate a random username");
yield return password;
yield return new SubmitButtonControl(ControlKeys.ButtonSubmit, "Submit", password);
}
}
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 ShouldIncludeUserTile(CredentialProviderUser user)
{
return true;
}
public override bool ShouldIncludeGenericTile()
{
return true;
}
public override CredentialProviderCredential1Tile CreateGenericTile()
{
return new TestCredentialProviderTile(this);
}
public override CredentialProviderCredential1Tile CreateUserTile(CredentialProviderUser user)
{
return new TestCredentialProviderTile(this, user);
}
}
}
@@ -0,0 +1,60 @@
using System;
using System.Runtime.InteropServices;
namespace Lithnet.CredentialProvider.Samples
{
public static class CredUI
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct CREDUI_INFO
{
public int cbSize;
public IntPtr hwndParent;
public string pszMessageText;
public string pszCaptionText;
public IntPtr hbmBanner;
}
[DllImport("credui.dll", CharSet = CharSet.Auto)]
public static extern int CredUIPromptForWindowsCredentials(
ref CREDUI_INFO uiInfo,
int authError,
ref uint authPackage,
IntPtr InAuthBuffer,
uint InAuthBufferSize,
out IntPtr refOutAuthBuffer,
out uint refOutAuthBufferSize,
ref bool fSave,
uint flags
);
public static void Prompt(string caption, string message)
{
var uiInfo = new CREDUI_INFO()
{
pszCaptionText = caption,
pszMessageText = message
};
uiInfo.cbSize = Marshal.SizeOf(uiInfo);
uint authPackage = 0;
var save = false;
CredUIPromptForWindowsCredentials(
ref uiInfo,
0,
ref authPackage,
IntPtr.Zero,
0,
out IntPtr outCredBuffer,
out uint outCredSize,
ref save,
0
);
Marshal.FreeCoTaskMem(outCredBuffer);
}
}
}
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<RegisterForComInterop>false</RegisterForComInterop>
<Platform>x64</Platform>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
<PackageReference Include="NLog" Version="5.1.1" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.1" />
</ItemGroup>
</Project>
@@ -0,0 +1,44 @@
using System;
using Microsoft.Extensions.Logging;
using NLog;
using NLog.Extensions.Logging;
namespace Lithnet.CredentialProvider.Samples
{
internal static class Program
{
internal static ILoggerFactory LoggerFactory { get; }
static Program()
{
/*
This sample uses NLog to capture trace events from the provider, but you can use any
logging system compatible with Microsoft.Extensions.Logging;
*/
var config = new NLog.Config.LoggingConfiguration();
var logconsole = new NLog.Targets.ConsoleTarget("logconsole");
/*
Add file based logging if required
*/
// var logfile = new NLog.Targets.FileTarget("logfile") { FileName = "c:\\file.txt" };
//config.AddRule(NLog.LogLevel.Trace, NLog.LogLevel.Fatal, logfile);
config.AddRule(NLog.LogLevel.Trace, NLog.LogLevel.Fatal, logconsole);
LogManager.Configuration = config;
Program.LoggerFactory = new NLogLoggerFactory(new NLogLoggerProvider(new NLogProviderOptions() { ReplaceLoggerFactory = true }, LogManager.LogFactory));
}
static void Main(string[] args)
{
CredUI.Prompt("Login with Cred UI", "Select your favorite credential provider");
Console.WriteLine("Done! Press any key to exit");
Console.ReadKey();
}
}
}
@@ -0,0 +1,60 @@
using System;
using System.Runtime.InteropServices;
namespace Lithnet.CredentialProvider.Samples
{
public static class CredUI
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct CREDUI_INFO
{
public int cbSize;
public IntPtr hwndParent;
public string pszMessageText;
public string pszCaptionText;
public IntPtr hbmBanner;
}
[DllImport("credui.dll", CharSet = CharSet.Auto)]
public static extern int CredUIPromptForWindowsCredentials(
ref CREDUI_INFO uiInfo,
int authError,
ref uint authPackage,
IntPtr InAuthBuffer,
uint InAuthBufferSize,
out IntPtr refOutAuthBuffer,
out uint refOutAuthBufferSize,
ref bool fSave,
uint flags
);
public static void Prompt(string caption, string message)
{
var uiInfo = new CREDUI_INFO()
{
pszCaptionText = caption,
pszMessageText = message
};
uiInfo.cbSize = Marshal.SizeOf(uiInfo);
uint authPackage = 0;
var save = false;
CredUIPromptForWindowsCredentials(
ref uiInfo,
0,
ref authPackage,
IntPtr.Zero,
0,
out IntPtr outCredBuffer,
out uint outCredSize,
ref save,
0
);
Marshal.FreeCoTaskMem(outCredBuffer);
}
}
}
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<RegisterForComInterop>false</RegisterForComInterop>
<Platform>x86</Platform>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
<PackageReference Include="NLog" Version="5.1.1" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.1" />
</ItemGroup>
</Project>
@@ -0,0 +1,44 @@
using System;
using Microsoft.Extensions.Logging;
using NLog;
using NLog.Extensions.Logging;
namespace Lithnet.CredentialProvider.Samples
{
internal static class Program
{
internal static ILoggerFactory LoggerFactory { get; }
static Program()
{
/*
This sample uses NLog to capture trace events from the provider, but you can use any
logging system compatible with Microsoft.Extensions.Logging;
*/
var config = new NLog.Config.LoggingConfiguration();
var logconsole = new NLog.Targets.ConsoleTarget("logconsole");
/*
Add file based logging if required
*/
// var logfile = new NLog.Targets.FileTarget("logfile") { FileName = "c:\\file.txt" };
//config.AddRule(NLog.LogLevel.Trace, NLog.LogLevel.Fatal, logfile);
config.AddRule(NLog.LogLevel.Trace, NLog.LogLevel.Fatal, logconsole);
LogManager.Configuration = config;
Program.LoggerFactory = new NLogLoggerFactory(new NLogLoggerProvider(new NLogProviderOptions() { ReplaceLoggerFactory = true }, LogManager.LogFactory));
}
static void Main(string[] args)
{
CredUI.Prompt("Login with Cred UI", "Select your favorite credential provider");
Console.WriteLine("Done! Press any key to exit");
Console.ReadKey();
}
}
}