3D PLM Enterprise Architecture

Single Sign On

Using SSO Client

How to leverage SSO capabilities between VPM Navigator and an external System
Use Case

Abstract

This use case explains how to create a command header to leverage Single Sign On capabilities. This command lets you retrieve credentials for a given custom system while you  are already authenticated within VPM Navigator.


What You Will Learn With This Use Case

This use case illustrates how to use Single Sign On Client within a command to retrieve credentials for a custom System. You will learn how to:

You should also read 

[Top]

The CAAPLMSSOClientTest Use Case

CAAPLMSSOClientTest is a use case of the CAASecuritySSOCClient.edu framework that illustrates PLMSecuritySSOCClient framework capabilities.

[Top]

What Does CAAPLMSSOClientTest Do

CAAPLMSSOClientTest creates a command header whose the graphic representation is a simple Message Box displaying the retrieved credentials. The following picture shows the result of the execution of the command when successful:

Fig.1 The successful command

Here is the sequence diagram of the command. It represents the whole process to access a custom system from CATIA. the last step (accessMySystemWithCredentials method ) is not implemented in this use case.

Fig.2 The Sequence Diagram of the command

Fig.3 The Class Diagram of the CAA Objects

[Top]

How to set up your environment for CAAPLMSSOClientTest

To launch the CAAPLMSSOClientTest use case, you will need to set up the build time environment for two workspaces and activate SSO both in you VPM Navigator and in your Application Server. To activate SSO please refer to the official documentation.

  1. Server Workspace

This workspace will contain all definitions of the credential required to authenticate against your custom system. There will be no code in this workspace only definition files.

Now there is two ways for those definitions to be taken into account by your Application server.

Then you will have to restart your Application Server.

  1. VPM Navigator workspace: 

This workspace will contain all the client code executed by VPM Navigator. You will need to

[Top]

Where to Find the CAAPLMSSOClientTest Code

The CAAAfrEltCountHeader use case is made of several classes mainly located in modules of the CAAApplicationFrame.edu framework:

Windows InstallRootDirectory\CAASecuritySSOCCLient.edu\
Unix InstallRootDirectory/CAASecuritySSOCCLient.edu/

where InstallRootDirectory is the directory where the CAA CD-ROM is installed.

[Top]

Step-by-Step

There are three logical steps in  CAAPLMSSOClientTest :

  1. Creating a CredentialSet file and its NLS for your custom System
  2. Creating Credentials in the SSO Admin Console for your custom system
  3. Creating the Class of the command

[Top]

Creating a CredentialSet file and its NLS for your custom System

In this section, we will explain you how you can leverage SSO capability to enable a command from VPM Navigator to retrieve your own credentials, for your own System.

There are two steps to be achieved :

  1. Defining XML .CredentialSets file for your own System

A .CredentialSets file represents metadata defining which credentials are required to access a system. Once credentialSet file is provided it is automatically recognized and usable from the Single Sign On Administrative console.

A set of Credentials has to be defined for each system you need to retrieve credentials from the SSO Server. To perform it you have to deliver an XML file in the runtime view, following this path: MyWorkspace/MyFramework/CNext/resources/sso/credentials/.

This XML file has to be named with the name of the system and with ‘credentialSet’ extension.

Here is an example of a CredentialSet for MySystem : (MySystem.credentialSet)

<?xml version="1.0" encoding="UTF-8"?>

<SSOCredentialSet applicationType=" MySystem " >

<SSOCredentialDescriptor name="User" type="String" password="false" hidden="false" />

<SSOCredentialDescriptor name="Password" type="String" password="true" hidden="false" />

</SSOCredentialSet:SSOCredentialSet>

 

Description of the XML format 

The root object is SSOCredentialSet. It describes what are the required credentials to let you authenticate against a custom system. it has one required attribute which is applicationType. This attribute must be valuated with the exact name of the file. It is the ID of your system when you want to retrieve credentials.

the root object can embed any number of SSOCredentialDescriptor element. It represents on credential required to authenticate against your system. It has many attribute :

[Top]

  1. Creating NLS names for credentials of your own System (Optional)

To display NLS names in the Single Sign On administrative console you may provide an NLS file. The NLS File must be named as follow: SystemName_credentialSet.CATNls where SystemName is the name in the .credentialSet file. It must be delivered in Workspace/$os/resources/msgCatalog/.

The property applicationType.name must be set to the NLS name of your System

Then each credential name must follow this pattern:

SSOCredential.MyCredentialName=”My NLS Message”;

Where MyCredentialName is the name of the credential given in the .CredentialSet file and My NLS Message is the corresponding NLS message to be displayed.

Here is an example of NLS file:

SSOCredential.Password="Password";

applicationType.name="My System";

SSOCredential.User="User Name";

 

Now there is two ways for those definitions to be taken into account by your Application server.

or

Then you will have to restart your Application Server.

[Top]

Creating Credentials in the SSO Admin Console for your custom system

Once you have created your own .credentialSet file you have to administrate those credentials the same way you did for ENOVIA LCA. It means that you have to access the Single Sign On administrative console and create credentials instance for each SSO User you want him to be allowed to access your own System.

Credentials must be created from the SSO Administrative console for a given SSO user and the application MySystem. Go to the URL:

 http://host:port/RootURI/html/SSOAdminConsole.

host: is the host name of your WAS

port: is the listening port of the WAS

RootURI: is the rootURI used to install the EAR on the WAS on WASSetupUI tool.

the following panel appears:

Fig4 : The Single Sign On Adminstrative Console

and click on create. the following panel appears:

Fig5 : The create Credentials Panel

Note: smq is the SSO user, it must exist in you User Repository (LDAP if you are using one to secure your WAS)

[Top]

Creating the Class of the command

Now we will work in the VPM Navigator Workspace.

Creating the header of the command

here is the description of the code of the command which retrieves credentials from the server : TestSSOCAACmd.h

#ifndef TestSSOCAACmd_H
#define TestSSOCAACmd_H
#include "CATStateCommand.h"

#include "CATCommand.h" // for CATStatusChangeRC
#include "CATBoolean.h"

class CATMsgCatalog;

class TestSSOCAACmd : public CATStateCommand
{
public:

//constructor of the command
TestSSOCAACmd ();
virtual ~TestSSOCAACmd (); //destructor of the command

virtual void BuildGraph (); //called when the command is instantiated


private:

//used to retrieve errors when one occurs within the CAASSOClient object
CATUnicodeString HandleError(HRESULT iStatus); r>
//used to Display Msg in a Display Blocked Box
void DisplayMessage(CATUnicodeString &iMessage,int iIsError);
CATMsgCatalog *m_msgCat; //MsgCatalog Object to retrieve NLS msg from TestSSOCAACmd.CATNls int the RTV
};

#endif

As you can see our inherit from a CATStateCommand. We will build our state graph in the BuildGraph() method. This method is called when the command is instantiated. We also define a method to handle Errors from the CAASSOClient Object with the method HandleError. Finally we define a method to display the final message of the command with DisplayMessage() method. We also have one private member with m_msg to handle NLS messages.

Creating the implementation of the command

here is the description of the code of the command which retrieves credentials from the server : TestSSOCAACmd.cpp

#include "TestSSOCAACmd.h"
#include "CATDlgNotify.h"
#include "CATCreateExternalObject.h"
#include "CATApplicationFrame.h"
#include "CATUnicodeString.h"
#include "CATMsgCatalog.h"

#include "PLMSSOClient.h"
#include "PLMSSOCredential.h"
#include "PLMSSOCredentialSet.h"

CATCreateClass(TestSSOCAACmd);

//-------------------------------------------------------------------------
TestSSOCAACmd::TestSSOCAACmd ():CATStateCommand ("TestSSOCAACmd")
{
//Loading Msg Catalog for this Command
m_msgCat = new CATMsgCatalog();
if (m_msgCat != NULL)m_msgCat->LoadMsgCatalog("TestSSOCAACmd");
}

//-------------------------------------------------------------------------
TestSSOCAACmd::~TestSSOCAACmd()
{
if (m_msgCat != NULL)
{
delete m_msgCat;
m_msgCat=NULL;
}br>}

//-------------------------------------------------------------------------
void TestSSOCAACmd::BuildGraph()
{
CATUnicodeString texte; //text to be display in the Pop-up
HRESULT hr = E_FAIL;

//create the SSO Client Object
PLMSSOClient sso;

CATBoolean activated = FALSE;

// Test if the SSO Has been activated in the RuntimeView
hr = sso.IsSSOActivated(activated);br>
// if it fails display the error message and exits
if (FAILED(hr))
{
texte = HandleError(hr);
DisplayMessage(texte,TRUE);
return;
}

//IF SSO is not activated no need to go further
if (!activated)
{
if (m_msgCat)texte=(m_msgCat->GetCatalogMsg ("NotActivated")).BuildMessage();
DisplayMessage(texte,TRUE);
return;
}
	//prepare the display of the SSO Activated message
if (m_msgCat)texte = texte +(m_msgCat->GetCatalogMsg ("Activated")).BuildMessage()+"\n";

CATBoolean authenticated=FALSE;
//Test if the End User is Authenticated on the SSO Server
hr = sso.IsAlreadyAuthenticated(authenticated);

//if an error occurs display the error Message and exit
if (FAILED(hr))
{
texte = HandleError(hr);
DisplayMessage(texte,TRUE);
return;
}

//if the user is not authenticated Display the message and exit
	if (!authenticated)
{
if (m_msgCat)texte = texte +(m_msgCat->GetCatalogMsg ("NotAuhtenticated")).BuildMessage()+"\n";
DisplayMessage(texte,TRUE);
return;
}
//prepare the display of the SSO authenticated message
if (m_msgCat)texte = texte +(m_msgCat->GetCatalogMsg ("Auhtenticated")).BuildMessage()+"\n";

//Try to retrieve the Authenticated User
CATUnicodeString user;
hr = sso.GetAuthenticatedUsername(user);

//If fails display the error and exit
if (FAILED(hr))
{
CATUnicodeString temp;
if (m_msgCat)temp=(m_msgCat->GetCatalogMsg ("ErrorSSOUser")).BuildMessage();
texte =texte + temp+"\n"+HandleError(hr);
DisplayMessage(texte,TRUE);
return;
}

//prepare the display of the retrieved SSO User
if (m_msgCat)texte = texte +(m_msgCat->GetCatalogMsg ("SSOUser")).BuildMessage()+user+"\n";


//Retrieving Credentials for the authenticated user
PLMSSOCredentialSet credentialSet;
hr = sso.GetCredentialSetForApplication("MySystem","",credentialSet);

//if an error occurs display the error Message and exit
if (FAILED(hr))
{
CATUnicodeString tmp;
if (m_msgCat)tmp = (m_msgCat->GetCatalogMsg ("GetCredentialError")).BuildMessage()+"\n";

texte = tmp+HandleError(hr);
DisplayMessage(texte,TRUE);
return;
}

//Prepare the display of the credentials well retrieve status
if (m_msgCat)texte = texte +(m_msgCat->GetCatalogMsg ("CredentialsOK")).BuildMessage()+"\n";

//Do a loop to retrieve and Display all credentials
int size = credentialSet.Size();
for (int k=1;k<=size;k++)
{
CATUnicodeString credentialValue;
CATUnicodeString credentialName;

hr = credentialSet[k].GetCredentialValue(credentialValue);

// if fails while retrieving credential value
if (FAILED(hr))
{
texte =texte + HandleError(hr)+"\n";
DisplayMessage(texte,TRUE);
return;
}

//retrieve the name of the credential
hr = credentialSet[k].GetCredentialName(credentialName);

//if it fails while retrieving credential value
if (FAILED(hr))
{
texte =texte + HandleError(hr)+"\n";
DisplayMessage(texte,TRUE);
return;
}
//prepare the Display of the credential name : value
texte = texte +credentialName+" : "+credentialValue + "\n";
}
//display the info Message
DisplayMessage(texte,FALSE);
}

void TestSSOCAACmd::DisplayMessage(CATUnicodeString& iMsg,int iIsError)
{
CATApplicationFrame* applicationFrame=CATApplicationFrame::GetFrame();

//exits if no applicationFrame found
if (applicationFrame == NULL) return;

CATDlgStyle style =CATDlgNfyOK|CATDlgWndModal;
CATUnicodeString title;

if (iIsError)
{
//retrieve the NLS title of the Display Error Box
if (m_msgCat != NULL)title=(m_msgCat->GetCatalogMsg ("TitleError")).BuildMessage();
//Set the style of the pop-up to an Error Box
style = style |CATDlgNfyError;
}
else
{
//retrieve the NLS title of the Display Info Box
if (m_msgCat != NULL)title=(m_msgCat->GetCatalogMsg ("TitleInfo")).BuildMessage();
}
//create the message Box
CATDlgNotify *notif = new CATDlgNotify(applicationFrame->GetApplicationDocument(),"Notif",style );
 
	//display the Message
notif->DisplayBlocked(iMsg,title);

//ask for destruction of the box
notif->RequestDelayedDestruction();
}

//----------------------------------------------------------------------------
CATUnicodeString TestSSOCAACmd::HandleError(HRESULT iStatus)
{

CATUnicodeString message="";
//Retrieving the Last Error
CATError * pOccurringError = CATError::CATGetLastError(iStatus);
if (pOccurringError != 0)
{
//retrieve the NLS Message of the CATError
message = pOccurringError->GetNLSMessage();
//free the memory of the CATError
pOccurringError->Release();
pOccurringError = NULL;
}
return message;
}
 
 

The Constructor and destrutors

#include "TestSSOCAACmd.h"
#include "CATDlgNotify.h"
#include "CATCreateExternalObject.h"
#include "CATApplicationFrame.h"
#include "CATUnicodeString.h"
#include "CATMsgCatalog.h"

#include "PLMSSOClient.h"
#include "PLMSSOCredential.h"
#include "PLMSSOCredentialSet.h"

CATCreateClass(TestSSOCAACmd);

//-------------------------------------------------------------------------
TestSSOCAACmd::TestSSOCAACmd ():CATStateCommand ("TestSSOCAACmd")
{
//Loading Msg Catalog for this Command
m_msgCat = new CATMsgCatalog();
if (m_msgCat != NULL)m_msgCat->LoadMsgCatalog("TestSSOCAACmd");
}

//-------------------------------------------------------------------------
TestSSOCAACmd::~TestSSOCAACmd()
{
if (m_msgCat != NULL)
{
delete m_msgCat;
m_msgCat=NULL;
}
}
...
here we load abd free the MessageCatalog for our command

The BuildGraph() Method : getting PLMSSOClient Object and testing environment

...
	HRESULT hr = E_FAIL;

//create the SSO Client Object
PLMSSOClient sso;

CATBoolean activated = FALSE;

// Test if the SSO Has been activated in the RuntimeView
hr = sso.IsSSOActivated(activated);br>
// if it fails display the error message and exits
if (FAILED(hr))
{
texte = HandleError(hr);
DisplayMessage(texte,TRUE);
return;
}

//IF SSO is not activated no need to go further
if (!activated)
{
if (m_msgCat)texte=(m_msgCat->GetCatalogMsg ("NotActivated")).BuildMessage();
DisplayMessage(texte,TRUE);
return;
}
	//prepare the display of the SSO Activated message
if (m_msgCat)texte = texte +(m_msgCat->GetCatalogMsg ("Activated")).BuildMessage()+"\n";

 
...
here we create our PLMSSOClient Object. It is the object which let us retrieve credentials without having to authenticate once more. Now we have that object we have to check if the SSO has been activated with the method IsSSOActivated() . If not there is no need to go further as the SSO will not be able to retrieve credentials. if there is an error or if it is not activated we display the error and return form the BuildGraph() method

The BuildGraph() Method : Testing if the user is already authenticated

...
	CATBoolean authenticated=FALSE;
//Test if the End User is Authenticated on the SSO Server
hr = sso.IsAlreadyAuthenticated(authenticated);

//if an error occurs display the error Message and exit
if (FAILED(hr))
{
texte = HandleError(hr);
DisplayMessage(texte,TRUE);
return;
}

//if the user is not authenticated Display the message and exit
	if (!authenticated)
{
if (m_msgCat)texte = texte +(m_msgCat->GetCatalogMsg ("NotAuhtenticated")).BuildMessage()+"\n";
DisplayMessage(texte,TRUE);
return;
}
//prepare the display of the SSO authenticated message
if (m_msgCat)texte = texte +(m_msgCat->GetCatalogMsg ("Auhtenticated")).BuildMessage()+"\n";
...

 If the end user has not yet identify itself with the logon panel of ENOVIA the whole command will fail. So we have to check it first. So we can do it using IsAlreadyAuthenticated() method. Once again if false or if the method fails we display the ad-hoc message and exit

 The BuildGraph() Method : Retrieving authenticated User name
...

//Try to retrieve the Authenticated User
CATUnicodeString user;
hr = sso.GetAuthenticatedUsername(user);

//If fails display the error and exit
if (FAILED(hr))
{
CATUnicodeString temp;
if (m_msgCat)temp=(m_msgCat->GetCatalogMsg ("ErrorSSOUser")).BuildMessage();
texte =texte + temp+"\n"+HandleError(hr);
DisplayMessage(texte,TRUE);
return;
}

//prepare the display of the retrieved SSO User
if (m_msgCat)texte = texte +(m_msgCat->GetCatalogMsg ("SSOUser")).BuildMessage()+user+"\n";
...

We can retrieve the Single Sign On username with the method GetAuthenticatedUseranme().

The BuildGraph() Method : retrieving credentials

...
	//Retrieving Credentials for the authenticated user
PLMSSOCredentialSet credentialSet;
hr = sso.GetCredentialSetForApplication("MySystem","",credentialSet);

//if an error occurs display the error Message and exit
if (FAILED(hr))
{
CATUnicodeString tmp;
if (m_msgCat)tmp = (m_msgCat->GetCatalogMsg ("GetCredentialError")).BuildMessage()+"\n";

texte = tmp+HandleError(hr);
DisplayMessage(texte,TRUE);
return;
}

//Prepare the display of the credentials well retrieve status
if (m_msgCat)texte = texte +(m_msgCat->GetCatalogMsg ("CredentialsOK")).BuildMessage()+"\n";

...

Here is how to retrieve credentials for the authenticated user form the SSO Server. We use the GetCredentialSetForApplication method to do that. There are two inputs arguments. The first one is the name of the system you are interested on (on our case we want to retrieve credentials for MySystem ). The second argument is the name of the instance of the credentials you want to retrieve for that user. Within the SSO Administrative console you have provided a name of instance while creating credentials for that user and that system. As you can create multiples instance of credentials per user, it is that you name you have to give as a second argument. If you give a blank string (as we did in our example) it returns the default instance. This instance is returned within the PLMSSOCredentialSet object.

The BuildGraph() Method : using the retrieved credentials:

...	
	//Do a loop to retrieve and Display all credentials
int size = credentialSet.Size();
for (int k=1;k<=size;k++)
{
CATUnicodeString credentialValue;
CATUnicodeString credentialName;

hr = credentialSet[k].GetCredentialValue(credentialValue);

// if fails while retrieving credential value
if (FAILED(hr))
{
texte =texte + HandleError(hr)+"\n";
DisplayMessage(texte,TRUE);
return;
}

//retrieve the name of the credential
hr = credentialSet[k].GetCredentialName(credentialName);

//if it fails while retrieving credential value
if (FAILED(hr))
{
texte =texte + HandleError(hr)+"\n";
DisplayMessage(texte,TRUE);
return;
}
//prepare the Display of the credential name : value
texte = texte +credentialName+" : "+credentialValue + "\n";
}
//display the info Message
DisplayMessage(texte,FALSE);
}...

Here is how to retrieve credentials name and value from a PLMSSOCredentialSet object. The PLMSSOCredentialSet can be seen as a container of credentials for a given System and for a given user. So you can get each member as an array item with credentialSet[k]. At that point you have a PLMSSOCredential Object. On that object you can retrieve its name with GetCredentialName() method and its value with GetCredentialValue()

[Top]

Testing the Use Case

[Top]

 


In Short

This use case has explained how to create credentialSet definition for a custom system. how to create credentials for that system and how to retrieve them from VPM Navigator

[Top]


History

Version: 1 [Mar 2006]Document created
[Top]

Copyright © 2006, Dassault Systèmes. All rights reserved.