How to: Implement Password Extensions
This topic contains code examples that show how to implement a password extension. The examples assume that the connected data source uses an XML file to set passwords.
Note
For clarity, the passwords are exposed in the example. We recommend that you modify the examples so that the passwords are encrypted and not exposed.
The examples have the following members:
A constructor that initializes global variables.
A BeginConnectionToServer function that initializes an XmlTextWriter object and writes the root element. This function assumes that the XML file Sample_password.xml exists in the MaData folder.
An EndConnectionToServer function that writes the last element and then closes the XmlTextWriter object.
A GetConnectionSecurityLevel function that returns the connection security level. In this example, the connection is not secure.
A SetPassword function that writes the new password of the CSEntry object.
A ChangePassword function that writes the old and new passwords of the CSEntry object.
A RequireChangePasswordOnNextLogin function that throws an EntryPointNotImplementedException exception. Although this function is not used in Forefront Identity Manager Synchronization Service 2010, the server still requires an implementation.
A module function in the Visual Basic example or a structure function in the C# example, whose members are used to manage the XML node names. These names are used when generating the XML file.
The following Visual Basic example shows an implementation of a password extension.
Imports System
Imports System.IO
Imports System.Xml
Imports System.Text
Imports System.Collections.Specialized
Imports Microsoft.MetadirectoryServices
Namespace SamplePasswordManagement
'
' This sample writes to an XML file when the SetPassword and
' ChangePassword methods are invoked on the interface.
'
Public Class SampleMAPasswordManagement
Implements IMAPasswordManagement
'
' Constructor
'
Public Sub New()
m_xmlWriterExport = Nothing
m_encoding = UnicodeEncoding.Unicode
End Sub
Public Sub BeginConnectionToServer(ByVal connectTo As String, _
ByVal user As String, _
ByVal password As String) _
Implements IMAPasswordManagement.BeginConnectionToServer
'
' NOTE: The connectTo, user, and password attributes are not
' used in the sample. You would use these attributes if
' you were to connect to a data source that requires them.
'
m_xmlWriterExport = New XmlTextWriter(MAUtils.MAFolder & "\sample_password.xml", m_encoding)
m_xmlWriterExport.WriteStartElement(Nodes.Root)
End Sub
Public Sub EndConnectionToServer() _
Implements IMAPasswordManagement.EndConnectionToServer
If Nothing <> m_xmlWriterExport Then
m_xmlWriterExport.WriteEndElement()
m_xmlWriterExport.Close()
End If
End Sub
Public Function GetConnectionSecurityLevel() As ConnectionSecurityLevel _
Implements IMAPasswordManagement.GetConnectionSecurityLevel
Return ConnectionSecurityLevel.NotSecure
End Function
Public Sub SetPassword(ByVal csentry As CSEntry, ByVal NewPassword As String) _
Implements IMAPasswordManagement.SetPassword
m_xmlWriterExport.WriteStartElement(Nodes.Object)
m_xmlWriterExport.WriteElementString(Nodes.Name, csentry.DN.ToString())
m_xmlWriterExport.WriteElementString(Nodes.Operation, "SetPassword")
m_xmlWriterExport.WriteElementString(Nodes.NewPassword, NewPassword)
m_xmlWriterExport.WriteEndElement()
End Sub
Public Sub ChangePassword(ByVal csentry As CSEntry, _
ByVal OldPassword As String, _
ByVal NewPassword As String) _
Implements IMAPasswordManagement.ChangePassword
m_xmlWriterExport.WriteStartElement(Nodes.Object)
m_xmlWriterExport.WriteElementString(Nodes.Name, csentry.DN.ToString())
m_xmlWriterExport.WriteElementString(Nodes.Operation, "ChangePassword")
m_xmlWriterExport.WriteElementString(Nodes.OldPassword, OldPassword)
m_xmlWriterExport.WriteElementString(Nodes.NewPassword, NewPassword)
m_xmlWriterExport.WriteEndElement()
End Sub
Public Sub RequireChangePasswordOnNextLogin(ByVal csentry As CSEntry, _
ByVal fRequireChangePasswordOnNextLogin As Boolean) _
Implements IMAPasswordManagement.RequireChangePasswordOnNextLogin
Throw New EntryPointNotImplementedException
End Sub
'
' Members
'
Private m_xmlWriterExport As XmlTextWriter
Private m_encoding As Encoding
End Class
Module Nodes
Public Const Root As String = "sample-passwords"
Public Const [Object] As String = "object"
Public Const Name As String = "name"
Public Const Operation As String = "operation"
Public Const OldPassword As String = "old-password"
Public Const NewPassword As String = "new-password"
Public Const ObjectClass As String = "objectclass"
End Module
End Namespace 'SamplePasswordManagement
The following C# example shows an implementation of a password extension.
using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Collections.Specialized;
using Microsoft.MetadirectoryServices;
namespace SamplePasswordManagement
{
//
// This sample writes to a XML file when the SetPassword and
// ChangePasssword methods are invoked on the interface.
//
public class SampleMAPasswordManagement : IMAPasswordManagement
{
//
// Constructor
//
public SampleMAPasswordManagement()
{
m_xmlWriterExport = null;
m_encoding = UnicodeEncoding.Unicode;
}
public void BeginConnectionToServer(
string connectTo,
string user,
string password
)
{
//
// NOTE: The connectTo, user, and password attributes are not
// used in the sample. You would use these attributes if
// you were to connect to a data source that requires them.
//
m_xmlWriterExport = new XmlTextWriter(
MAUtils.MAFolder +
@"\sample_password.xml",
m_encoding
);
m_xmlWriterExport.WriteStartElement(Nodes.Root);
}
public void EndConnectionToServer()
{
if (null != m_xmlWriterExport)
{
m_xmlWriterExport.WriteEndElement();
m_xmlWriterExport.Close();
}
}
public ConnectionSecurityLevel GetConnectionSecurityLevel()
{
return ConnectionSecurityLevel.NotSecure;
}
public void SetPassword(
CSEntry csentry,
string NewPassword
)
{
m_xmlWriterExport.WriteStartElement(Nodes.Object);
m_xmlWriterExport.WriteElementString(
Nodes.Name,
csentry.DN.ToString()
);
m_xmlWriterExport.WriteElementString(
Nodes.Operation,
"SetPassword"
);
m_xmlWriterExport.WriteElementString(
Nodes.NewPassword,
NewPassword
);
m_xmlWriterExport.WriteEndElement();
}
public void ChangePassword(
CSEntry csentry,
string OldPassword,
string NewPassword
)
{
m_xmlWriterExport.WriteStartElement(Nodes.Object);
m_xmlWriterExport.WriteElementString(
Nodes.Name,
csentry.DN.ToString()
);
m_xmlWriterExport.WriteElementString(
Nodes.Operation,
"ChangePassword"
);
m_xmlWriterExport.WriteElementString(
Nodes.OldPassword,
OldPassword
);
m_xmlWriterExport.WriteElementString(
Nodes.NewPassword,
NewPassword
);
m_xmlWriterExport.WriteEndElement();
}
public void RequireChangePasswordOnNextLogin(
CSEntry csentry,
bool fRequireChangePasswordOnNextLogin
)
{
throw new EntryPointNotImplementedException();
}
//
// Members
//
XmlTextWriter m_xmlWriterExport;
Encoding m_encoding;
}
struct Nodes
{
public const string Root = "sample-passwords";
public const string Object = "object";
public const string Name = "name";
public const string Operation = "operation";
public const string OldPassword = "old-password";
public const string NewPassword = "new-password";
public const string ObjectClass = "objectclass";
}
}
See Also
Reference
XmlTextWriter
IMAPasswordManagement
EntryPointNotImplementedException
BeginConnectionToServer
ChangePassword
EndConnectionToServer
GetConnectionSecurityLevel
RequireChangePasswordOnNextLogin
SetPassword
Concepts
Using Password Extensions
Best Practices for Password Extensions