Cleans up static loggers
Adds test projects for different frameworks and architectures Adds registration tool assembly
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
@@ -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>
|
||||
+73
@@ -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 |
+97
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+192
@@ -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
|
||||
```
|
||||
+20
@@ -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>
|
||||
+73
@@ -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 |
+100
@@ -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
|
||||
```
|
||||
+31
@@ -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 |
+105
@@ -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
|
||||
```
|
||||
+31
@@ -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 |
+104
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user