Steffo's EcholotOnly technical stuff here. |
|
Sunday Jul 19, 2009
Identity Manager: adding versioning information to your deployment Identity Manager projects using the NetBeans IDE plugin usually face the problem that when deploying the application e.g. idm.war and loading the custom objects in the database repository (e.g. via lh import custom-init-full.xml). If you use Subversion or CVS, there is a quick and easy way to include a revision number with every build. There a two components which need a revision number:
Posted at 07:13AM Jul 19, 2009 by steffo in Identity Systems | Comments[0]
Friday Oct 24, 2008
The easiest OpenSSO install ever
Posted at 09:47AM Oct 24, 2008 by steffo in OpenSSO | Comments[2]
Wednesday May 28, 2008
Cardspace compromised?
My colleague Jörg was listening to the radio when they broadcasted that a weakness in Microsoft's
From a quick look, the attack is rather an application to dynamic pharming (DNS pinning) and general
The "CardSpace" attack again shows that two or three security issues can easily add up to a bigger problem. Posted at 02:14PM May 28, 2008 by steffo in Identity Systems | Comments[0]
Thursday Apr 10, 2008
Vaau, Roles and Identity
The acquisition of Vaau enriches our identity portfolio by a role mining and management tool. Tried to figure out the main differences and areas of application between RBACx and Sun's Identity Manager. First of all, Vaau's RBACx (Sun Role Manager) is more a configurable tool rather than a programmable tool as for example Sun's Identity Manager. Programmable means that the configuration language includes things like IF THEN ELSE, WHILE loops. So Identity Manager can be applied to many areas and programmed as desired. Role Manager is quite static compared to Identity Manager. It has its fixed area of application which is compliance and role management (including role mining). This makes it more a management tool rather than an administration tool. Role Manager can talk to Identity Manager via SPML. So you can drag out all user data from Identity Manager and import it via SPML into Role Manager. Which tool to start with? Apart from that there is no 'one size fits all' when it comes to enterprise apps, I would recommend to start with a privisioning tool which (IDM). First, you need data cleansing
Both tasks can be done with Identity Manager or with Role Manager. However, my personal view is that Identity Manager is more flexible because it accesses data online whereas Role Manager needs a CSV file for data loading if you don't drag out the data via SPML. Compliance tasks and attestation can be implemented in either. Second, role mining is a nice feature when you haven't defined your roles yet. Role mining is not a black art. It uses a covering algorithm to help the role designer in a way a CAD system helps technical designers. The important point here is that the outcome of the mining process is where technology meets business: whether or not a mined role is useful depends on the business. The mined roles can be amended to meet business criteria and then be exported to an identity management system (e.g. Sun's Identity Manager) from where the entitlements can be provisioned to the target systems (RACF, AD, LDAP etc). Overall impression: good tool. But beware it's called Role Manager and not sox.exe or security.exe. Posted at 11:28PM Apr 10, 2008 by steffo in Identity Systems | Comments[0]
Monday Mar 17, 2008
Single Sign On to Google using OpenSSO
Google has a SAML 2 capable single-sign-on service by which you can use Google as a service provider (SP). Google also provides a sample demo application. Rather than using Liberty Alliance's circle-of-trust model, Google uses a peered structure: if Google's SSO service (SP) receives a SAML response, it checks the signature of that request. If the signature is valid, the SAML assertion will be accepted. Trying to use Google's demo code with OpenSSO as an identity provider (IDP) requires some tweaks. Step 1: Making OpenSSO to accept Google's SAML request
<?xml version="1.0" encoding="UTF-8"?>
<AuthnRequest xmlns="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:oasis:names:tc:SAML:2.0:protocol file:/Documentation/Federation-SAML-Liberty/SAML%202.0/XSD/saml-2.0-os-xsd/saml-schema-protocol-2.0.xsd"
ID="<AUTHN_ID>"
Version="2.0"
IssueInstant="<ISSUE_INSTANT>"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
ProviderName="<PROVIDER_NAME>"
ForceAuthn="true"
AssertionConsumerServiceURL="<ACS_URL>">
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion" format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">
google
</Issuer>
<Subject xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<NameID>google</NameID>
</Subject>
</AuthnRequest>
Posted at 01:16PM Mar 17, 2008 by steffo in Identity Systems | Comments[13]
Friday Mar 14, 2008
Identity Manager IDE 8.0 is open-source
The new IDE (https://identitymanageride.dev.java.net) comes as a NetBeans Plugin. Quick tests show that it's stable. Compared to the IDM 7.x IDE,
Posted at 09:51AM Mar 14, 2008 by steffo in Identity Systems | Comments[0]
Wednesday Nov 14, 2007
Leopard (Mac OS 10.5) / Mac OS X 10.4 and Java 6
In case, you're looking for Java 6 on Mac OS X (10.4/10.5): https://connect.apple.com It's the roughly same 'old' build we've seen before:
teufelchen: steffo$ /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/bin/java -version
Posted at 03:18PM Nov 14, 2007 by steffo in Sun | Comments[2]
Monday Nov 05, 2007
Monitoring Identity Manager
Sun Java System Identity Manager has decent JMX capabilities which allows you to
In order to use these features, you only have to enable JMX (disabled by default) via "Configure > Servers" from the HTTPS admin interface. Additionally, you have to 'enable' JMX at the application server level. For Tomcat, you can add the following to the catalina.sh
You can see a bunch of JMX data at e.g. http://localhost:8080/idm/debug/Show_MBeanInfo.jsp. You could also tools like jconsole to set and query JMX attributes. The big question is "How to integrate IDM into a system monitoring tool?" is quite easy to answer since there is a small Java program called 'jmxquery'. Unfortunately I do not know who the author is but all credits go to her or him. What we want to achieve is that IDM‘s status and the resources health check show in our monitoring tool. E.g. with nagios you'll get the following screen
The basic idea is that Nagios calls an external programm like a (modified) version of jmxquery which able to retrieve and set IDM's JMX objects. Three things are sufficient
You can find the modified jmxquery as a NetBeans project file here:
IDM-Nagios.zip
Posted at 01:31PM Nov 05, 2007 by steffo in Identity Systems | Comments[3]
Tuesday Sep 25, 2007
A standalone OpenSSO client
OpenSSO has a server part (deployed behind a /fam URI or similar) and a client part (e.g. a J2EE agent, or the OpenID extension). In any case you have ensure that the AMConfig.properties for each part do correspond w.r.t. encryption keys, agent IDs etc. Since debugging an J2EE agent or even OpenID extension might be unfeasible (at least as a first step), I use a stand-alone client which sources the AMAgent.properties used by e.g. the OpenID extension. The following code is example and works well for OpenSSO, Sun Java System Access Manager (7.0 and 7.1) all deployed in realm mode. To build the JAR, make sure that you include the OpenSSO Client SDK as well as the servlet.jar to your (NetBeans) project.
/*
* OpenSSOConnect.java
*
* Created on November 2, 2006, 11:18 AM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
/**
*
* @author steffo
*/
// OpenSSO installation has a default realm 'init8' as well as an authentication chain 'init8'
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.ChoiceCallback;
import javax.security.auth.callback.ConfirmationCallback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.TextInputCallback;
import javax.security.auth.callback.TextOutputCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import netscape.ldap.util.DN;
import com.iplanet.am.util.SystemProperties;
import com.iplanet.sso.SSOToken;
import com.sun.identity.authentication.AuthContext;
import com.sun.identity.idm.AMIdentity;
import com.sun.identity.idm.AMIdentityRepository;
import com.sun.identity.idm.IdRepoException;
import com.sun.identity.idm.IdSearchControl;
import com.sun.identity.idm.IdSearchOpModifier;
import com.sun.identity.idm.IdSearchResults;
import com.sun.identity.idm.IdType;
import com.sun.identity.idm.IdUtils;
import com.sun.identity.security.AdminTokenAction;
import com.sun.identity.authentication.spi.AuthLoginException;
public class OpenSSOConnect {
public static void main(String[] argv) {
boolean remote = false;
if (argv.length > 0) {
String r = argv[0];
if (r.equalsIgnoreCase("remote")) {
remote = true;
}
}
Properties props = new Properties();
try {
//Point this to the AMConfig.properties, you want to check
FileInputStream amconfig = new FileInputStream("/Users/steffo/Projekte/OpenSSO/OpenID-Provider/src/opensso/extensions/openid/provider/resources/AMConfig.properties");
props.load(amconfig);
} catch (IOException e) {
System.out.println("AMConfig.properties was not found");
}
props.setProperty("com.iplanet.services.debug.level", "message");
props.setProperty("com.iplanet.am.naming.ignoreNamingService", "true");
//remote=true;
if (remote) {
props.setProperty("com.iplanet.am.sdk.package", "com.iplanet.am.sdk.remote");
} else {
props.setProperty(AdminTokenAction.AMADMIN_MODE, "true");
}
System.out.println("Properties set");
SystemProperties.initializeProperties(props);
try {
SSOToken token = getSSOToken();
System.out.println("Getting AMIdentityRepository object");
AMIdentityRepository idrepo = new AMIdentityRepository(token, "init8");
System.out.println("Using TOKEN to get AMIdentity object " + "and read attrs");
AMIdentity tmpId = IdUtils.getIdentity(token);
System.out.println("Calling Attributes getting all attributes: " + tmpId.getAttributes());
} catch (Exception ex) {
ex.printStackTrace();
}
System.exit(0);
}
public static SSOToken getSSOToken() throws Exception {
//We created a user 'steffo' with credenials 'password'
return getSSOToken("init8", "steffo", "password");
}
protected static SSOToken getSSOToken(String org, String uid,
String password) throws Exception {
AuthContext ac = new AuthContext(org);
ac.login(AuthContext.IndexType.SERVICE, "init8");
Callback[] callbacks = null;
if (ac.hasMoreRequirements()) {
callbacks = ac.getRequirements();
if (callbacks != null) {
try {
addLoginCallbackMessage(callbacks, uid, password);
ac.submitRequirements(callbacks);
} catch (Exception e) {
debugMessage("Login failed!!");
debugMessage("--> " + ac.getLoginException().getMessage());
e.printStackTrace();
return null;
}
}
}
if (ac.getStatus() == AuthContext.Status.SUCCESS) {
debugMessage("Login success!!");
} else if (ac.getStatus() == AuthContext.Status.FAILED) {
debugMessage("Login has failed!!");
debugMessage("--> " + ac.getLoginException().getMessage());
} else if( ac.getStatus() == AuthContext.Status.IN_PROGRESS ) {
// This may happen when the password is about to expire and must be reset.
// Analyze the error message to be sure what is going on.
debugMessage( "Login is in progress !" );
//debugMessage("--> " + ac.getLoginException().getMessage());
if( ac.hasMoreRequirements() ) {
callbacks = ac.getRequirements();
if( callbacks != null ) {
debugMessage( "Callbacks for new password will be processed !" );
try {
addNewPasswordCallbackMessage( callbacks, uid, password, "Geheim03" );
ac.submitRequirements( callbacks );
} catch( Exception e ) {
debugMessage( "Login failed while processing new password callbacks." );
debugMessage("--> " + ac.getLoginException().getMessage());
e.printStackTrace();
return null;
}
}
}
if( ac.getStatus() == AuthContext.Status.SUCCESS )
debugMessage( "Login success after switch to new password!" );
else {
debugMessage( "Login failed after switch to new password!" );
debugMessage("--> " + ac.getLoginException().getMessage());
}
}
else {
debugMessage("Unknown status: " + ac.getStatus());
debugMessage("--> " + ac.getLoginException().getMessage());
}
SSOToken token = ac.getSSOToken();
return token;
}
// Get user's inputs and set them to callback array.
static void addLoginCallbackMessage(Callback[] callbacks, String uid,
String password) throws UnsupportedCallbackException {
debugMessage("begin addLoginCallbackMessage()");
int i = 0;
try {
for (i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof TextOutputCallback) {
debugMessage("Got TextOutputCallback");
// Display the message according to the specified type
TextOutputCallback toc = (TextOutputCallback) callbacks[i];
switch (toc.getMessageType()) {
case TextOutputCallback.INFORMATION:
debugMessage(toc.getMessage());
break;
case TextOutputCallback.ERROR:
debugMessage("ERROR: " + toc.getMessage());
break;
case TextOutputCallback.WARNING:
debugMessage("WARNING: " + toc.getMessage());
break;
default:
debugMessage("Unsupported message type: "
+ toc.getMessageType());
}
} else if (callbacks[i] instanceof NameCallback) {
debugMessage("Got NameCallback");
NameCallback nc = (NameCallback) callbacks[i];
nc.setName(uid);
} else if (callbacks[i] instanceof PasswordCallback) {
debugMessage("Got PasswordCallback");
PasswordCallback pc = (PasswordCallback) callbacks[i];
pc.setPassword(new String(password).toCharArray());
} else if (callbacks[i] instanceof TextInputCallback) {
debugMessage("Got TextInputCallback");
// prompt for text input
TextInputCallback tic = (TextInputCallback) callbacks[i];
// ignore the provided defaultValue
System.err.print(tic.getPrompt());
System.err.flush();
tic.setText((new BufferedReader(new InputStreamReader(
System.in))).readLine());
} else if (callbacks[i] instanceof ChoiceCallback) {
debugMessage("Got ChoiceCallback");
// prompt for choice input
ChoiceCallback cc = (ChoiceCallback) callbacks[i];
System.err.print(cc.getPrompt());
String[] strChoices = cc.getChoices();
for (int j = 0; j < strChoices.length; j++) {
System.err
.print("choice[" + j + "] : " + strChoices[j]);
}
System.err.flush();
cc.setSelectedIndex(Integer.parseInt((new BufferedReader(
new InputStreamReader(System.in))).readLine()));
}
}
} catch (Exception e) {
throw new UnsupportedCallbackException(callbacks[i],
"Callback exception: " + e);
}
}
static void addNewPasswordCallbackMessage( Callback[] callbacks,
String uid,
String oldPassword,
String newPassword ) throws UnsupportedCallbackException
{
int pwdCount = 0;
int i = 0;
try {
for (i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof TextOutputCallback) {
debugMessage( "Got TextOutputCallback while setting new password." );
// simply display the message
TextOutputCallback toc = (TextOutputCallback) callbacks[i];
debugMessage(toc.getMessage() + " :" + toc.getMessage() );
} else if (callbacks[i] instanceof NameCallback) {
debugMessage( "Got NameCallback while setting new password - this should not happen !" );
debugMessage( "Maybe you hit the next login module." );
} else if (callbacks[i] instanceof PasswordCallback) {
debugMessage( "Got PasswordCallback while setting new password." );
PasswordCallback pc = (PasswordCallback) callbacks[i];
// set first password callback with value of old password, the others with the new one
if( pwdCount == 0 )
pc.setPassword( new String( oldPassword ).toCharArray() );
else
pc.setPassword( new String( newPassword ).toCharArray() );
pwdCount++;
} else if (callbacks[i] instanceof ConfirmationCallback) {
debugMessage( "Got ConfirmationCallback while setting new password !" );
ConfirmationCallback cc = (ConfirmationCallback) callbacks[i];
// "0" is the index of SUBMIT
cc.setSelectedIndex( 0 );
} else if (callbacks[i] instanceof TextInputCallback) {
debugMessage( "Got TextInputCallback while setting new password - this should not happen !" );
} else if (callbacks[i] instanceof ChoiceCallback) {
debugMessage( "Got ChoiceCallback while setting new password - this should not happen !" );
}
}
} catch( Exception e ) {
throw new UnsupportedCallbackException( callbacks[i], "Callback exception: " + e );
}
}
static void debugMessage(String msg) {
System.out.println(msg);
}
}
Posted at 08:46AM Sep 25, 2007 by steffo in Sun | Comments[3]
Monday Sep 24, 2007
OpenSSO with OpenID (on the Mac featuring Glassfish)
I've been asked for this a couple of times. Building and getting the OpenID extension for OpenSSO running
I assume that you have already downloaded and deployed OpenSSO in the Glassfish application server. Also, you must be able to successfully login to OpenSSO's console as 'amadmin'. Overall Scenario We will setup 4 (HTTP) services:
The 4 components correspond to the ones used by Sun's deployment (as described in Hubert's blog: the relying party (Python client), the OpenID Identifier Server (Apache), OpenID Extension (OpenID Endpoint at 18080), Login (OpenSSO server at 8080). There is no registration component in our example. Users are either created from the OpenSSO console or privioned to an LDAP data source. Step 1. Download and build the OpenID extension First, login to OpenSSO's console and create an account to be used by the OpenID extension (the OpenID extension is an OpenSSO client which tries to authenticate against the OpenSSO server).
Second, checkout the OpenSSO source code via cvs -d :pserver:yourlogin@cvs.dev.java.net:/cvs checkout opensso an save the result in e.g. ~/Projects/OpenSSO/src. Next, dowload the OpenSSO ClientSDK and save the JAR famclientsdk.jar in e.g. ~/Projects/OpenSSO/clientSDK/. The client SDK is needed by the OpenID extension. The OpenID extension is at: opensso/extensions/openid/provider/ in the OpenSSO source tree. You'll also find a build.xml with all the necessary targets there. Now copy the following JARs to opensso/extensions/openid/provider/extlib:
Setup a NetBeans project; I used 'Java Project with existing Ant script'. Make sure you add the above JARs to your NetBeans project. There are two properties files which are crucial
More information can be found the extension's README
AMConfig.properties contains configuration information required by the OpenSSO client SDK (do not mix up this one up with the OpenSSO server configuration file which has the same name but resides somewhere at /etc/OpenSSO or /etc/SUNWam - you've been asked for the exact location during the OpenSSO installation). Make sure that everything in this file is correct. Also check that the debug directity exists and that the naming URL is correct. Here are the keys that work for my setup:
Make sure, that in your setup, the values of the server's and client's AMConfig.properties match. Provider.properties There are only a few keys here.
You can now build the OpenID extension by selecting the target 'war'. I deployed the 'provider.jar' at http://teufelchen.nit8.net:18080/openid. Browse to http://teufelchen.nit8.net:18080/openid and you should see the service end point. Step 2. Configuring your OpenID URL and create a user in OpenSSO The OpenID URL I want to use is: "http://teufelchen.init8.net/steffo". Browsing to this URL should retrieve the document at $DOCROOT/steffo/index.html. I used Apache's standard 'index.html' (the one that gives you the 'Seeing this instead of the website you expected?') and pasted the following between th HEAD tag: <link rel="openid.server" href="http://teufelchen.init8.net:18080/openid/service"/> You also have to create a user in OpenSSO. The ID of that user depends on the OpenID you want to use. If you want to use "http://teufelchen.init8.net/steffo", create a user "steffo". Note that this user might reside in an external LDAP (in which case you have to configure an appropriate authentication module and data source - but that's not required for this sample). Step 3. Download and install the OpenID client Download the Python libs at http://www.openidenabled.com/ . Follow the installation instructions and edit the file 'consumer.py' in the examples directory. Modify the following keys:
You can now start the consumer from the command shell: python consumer.py --port 8001 This sets up an HTTP service. The above command outputs something like:
Server running at:
I put a fake entry to /etc/hosts which assigns 127.0.0.1 the name "openid.init8.net". Direct your browser to this URL. You can now enter your OpenID (e.g. http://teufelchen.init8.net/steffo) into the box. Next, you'll be redirected to OPenSSO's login screen. After successfully entering your credential, you'll see a message like The website http://openid.init8.net:8001/ is requesting confirmation that your OpenID identity is http://teufelchen.init8.net/steffo. Done. Posted at 06:44PM Sep 24, 2007 by steffo in Sun | Comments[1]
Tuesday Jul 10, 2007
Integration of IDM SPE and Access Manager
As announced, the PDF version of the paper (v3) is available on sharespace (login required) and on
Posted at 08:51AM Jul 10, 2007 by steffo in Identity Systems | Comments[0]
Tuesday Jun 26, 2007
Integration of Identity Manager and Access Manager
We have extended the whitepaper that describes how to integerate Sun Java Identity Manager and Sun Java Access Manager in Realm Mode. Also the shortly upcoming version will discuss an approach to Single-Sign On into the Service Provider Edition (SPE) of Identity Manager. Posted at 02:41PM Jun 26, 2007 by steffo in Identity Systems | Comments[6]
Wednesday May 16, 2007
Against 'Least Privilege'
The principle of 'least privilege' (LP) states that a subject should have access to the smallest number of objects necessary to perform some task (p. 242 of Security in Computing, by C. Pfleger, 1997 Prentice Hall). I never questioned this principle until I came in touch with Identity Management. The more I looked on the management side of security rather than on its technical side, I found that in most cases LP leads to systems whose security is more diffcult to manage. These systems are less secure than a system which doesn't follow the LP paradigm. Tales from the field: a company with 5000 employees has 3000 AD groups (I didn't count the RACF groups but there are many). The big question is: how many business roles (e.g. sales rep, developer) do exists in this company (the sales rep role might imply memebership in 10 LDAP groups so the pure amount of LDAP groups doen't say anything about least privilege). The number of business roles vary from company to company. One my customers told me that an an organization having 1000 employees should have at most 50 (five percent!) business roles, otherwise there is no oranizational benefit from a role model. I think if an organization's role amount is ten percent, that's still a good number. I met other customers who do not even have roles but maintain a list of privileges for each individual user (according to LP). To me it seems that LP hinders organizations to achieve a low number of roles which in turn means that it hinders you in defining a proper security management structure. I'm willing to give up LP (and maybe use audit facilities to monitor access rather to prevent access) as a general principle. LP must be questioned under practical aspects and in many cases LP is a requirement that comes from regulations rather than from reality. Posted at 05:20PM May 16, 2007 by steffo in Identity Systems | Comments[0]
Thursday Apr 26, 2007
Identity Manager: Neogent's Rapid Deployment Tool
Sun acquired Neogent a couple of months ago. Neogent has an excellent tool which can ease deployment of IdM at customers. Velocity Identity Deployment Tool (VIDT) is a code generator that is able to generate code on the basis of use-cases. The implementor selects a use-case (e.g. create user) and an actor (e.g. a resource like HR Active Sync) and VIDT generates all the code that is required for a synchronization of the HR resource (e.g. SAP ot PeopleSoft) and IDM. As with every tool VIDT has it's pros and cons. On the pro side we have
And then there's certainly a downside of such a tool: like many tools, it tries to embrace the unexperienced user and loses the professional one. It's like YaST (anyone remembering this?) or Windows network configuration (what the hell is the difference between an office network and a home dial-up access?). Is VIDT really another YaST? Not quite. VIDT has it's own 'logic' but fortunately, all it does it to produce XML files that can be read and modified if needed. Also, IDVT projects can be exported to a CBE structure (if you're not familiar with CBE, check out https://idm-cbe.dev.java.net). This allows a transition from a code base that was generated by a rapid deployment tool to a code base that can be used for a long term (> 6 months) projects. VIDT currently aims at the following project phases or users:
My impression is that VIDT will currently not be used by experienced implementors throughout a longer project. The reason is that an experienced coder is faster using NetBeans or Oxygen than using VIDT. Does that mean that VIDT is useless for larger projects? No. VIDT can be used for rapid prototyping. Moreover, VIDT can be extended to incorporate additional uses cases (e.g. move and rename a user) and it depends on the community to share those new plugins. Posted at 09:06AM Apr 26, 2007 by steffo in Identity Systems | Comments[2]
Saturday Apr 14, 2007
Weird modeling in X.500/LDAP and ActiveDirectory: cn in distinguished names
Over the last years I came across some common issues on the modeling in LDAP and ActiveDirectory, well, more on AD than LDAP. The first issue is on distinguished names. I never understood why so many AD implementation use the cn rather than uid or employeeNumber as part of the distinguished name. The problem is that if there are employees with common common names like 'John Smith' the dn's look like
This might not appear to be a problem from an LDAP perspective, but it is a problem from an identity management perspective. If John Smith gets married to Jane Miller and changes his name the key (dn) must be changed as well. Employee numbers don't change. Moreover, if the entries do not contain a company wide unique attribute at all it is difficult to tell whether 'jsmith5' on UNIX belongs to the same person as 'cn=John Smith 3' on LDAP/AD. When an IDM is deployed, no enterprise infomation system can be anyl longer regarded as an island. Data quality is one major issue in identity management projects and improper naming convention do contribute this this issue. Posted at 12:00AM Apr 14, 2007 by steffo in Identity Systems | Comments[4] |
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||