Implement the Authentication Interface
Contents
casso1283
Creating the custom authentication scheme includes implementing the following procedures:
- A query procedure
- An initialization procedure
- A user authentication procedure
- A release procedure
Query Procedure
When the custom authentication scheme loads into memory,
SiteMinder
calls the query procedure to garnish the following pieces of information:- The version and description of the authentication scheme.
- The kind of credentials that are required for user authentication.
- (Optional) A URL that specifies where to retrieve this information.
The query function reads a constant value that specifies what information the authentication scheme requires. The function passes back the appropriate information in the designated output parameter. When the call to the query function completes successfully,
SiteMinder
has the appropriate information about the authentication scheme.Example: Query Procedure
/*// SmAuthQuery:// SiteMinder calls this function to request scheme information.// The function returns a description of the scheme, or credentials that are// required for the authentication.//// PARAMETERS:// [in] lpszParam: Parameter string specified in the authentication scheme.// [in] lpszSharedSecret: Shared secret string specified in the authentication scheme.// [in] Sm_AuthApi_QueryCode_t: Request code is any one of the following// 1. Sm_AuthApi_QueryDescription - Request description of the scheme.// 2. Sm_AuthApi_QueryCredentialsReq - Request the credentials required by the// scheme and where to obtain them.// [out] lpszStatusBuffer: Buffer for a character string response.// [out] lpnStatusCode: Buffer for a numeric response.//// RETURNS:// Any one of the following Sm_AuthApi_Status_t values:// Sm_AuthApi_Success// Sm_AuthApi_Failure*/Sm_AuthApi_Status_t SM_EXTERN SmAuthQuery (const char* lpszParam, /* parameter (null-terminated) */const char* lpszSharedSecret, /* shared secret (null-terminated) */const Sm_AuthApi_QueryCode_t nCode, /* query code */char* lpszStatusBuffer, /* status buffer to hold the null-terminated string */int* lpnStatusCode) /* status code */{strcpy (lpszStatusBuffer, "");switch (nCode){case Sm_AuthApi_QueryDescription:strcpy (lpszStatusBuffer, SCHEME_DESCRIPTION);*lpnStatusCode = SCHEME_VERSION;break;case Sm_AuthApi_QueryCredentialsReq:*lpnStatusCode = Sm_AuthApi_Cred_Basic;break;default:return Sm_AuthApi_Failure;}return Sm_AuthApi_Success;}
Initialization Procedure
To initialize your custom authentication scheme, implement the SmAuthInit() function. The calling sequence specifies two input parameters. You can use one or both of these parameters as best suits your implementation.
Example: Initialization Procedure
C++
// SmAuthInit:// PARAMETERS:// [in] lpszServerParam: Parameter string as specified for the authentication scheme.// [in] lpszSharedSecret: Shared secret string specified in the authentication scheme.//// RETURNS:// Any one of the following Sm_AuthApi_Status_t values:// Sm_AuthApi_Success// Sm_Authapi_Failure (scheme will not be loaded)*/Sm_AuthApi_Status_t SM_EXTERN SmAuthInit (const char * lpszServerParam, /* server parameter */const char * lpszSharedSecret) /* server shared secret */{return Sm_AuthApi_Success;}
User Authentication Procedure
The authentication process includes the following steps:
- User login. The user supplies a login ID (such as jsmith) for authentication purposes.
- Disambiguation phase. User disambiguation is the process of locating a user in the user store, such as an LDAP user directory or an ODBC database. EitherSiteMinderor the custom authentication scheme can look up the user in the user store.Before the lookup operation can begin, a complete DN or a search expression must be constructed based upon the supplied login ID. For example, if the login ID is jsmith, the DN used to search the user store might be constructed as follows:uid=jsmith,ou=marketing,o=myorg.orgAn LDAP search expression can also be used to search an LDAP user directory, and a SQL query is used to search an ODBC database—for example:(&(objectclass=inetOrgPerson)(uid=jsmith))select Name from SmUser where Name = 'jsmith'Multiple results are possible, given that the LDAP DN or the ID stored in the ODBC database might apply to different users who have different passwords.
- Authentication phase. The custom authentication scheme compares the known credentials of each disambiguated user with the credentials supplied during login—for example, by comparing the hash of the supplied password against the hash in the user store.
SiteMinder
calls SmAuthenticate() at the beginning of the user disambiguation phase. Either SiteMinder
or the custom authentication scheme can disambiguate the user. The authentication scheme indicates whether it has performed the disambiguation through one of the following return codes:- Sm_AuthApi_NoUserContextThe authentication scheme asksSiteMinderto disambiguate the user.When this code is returned, the authentication scheme leaves the parameter lpszUserMsg empty.SiteMindergets the login ID from the Agent, constructs the DN or search expression based on the login ID and the information defined in theSiteMinderUser Directory Properties dialog box, and disambiguates the user by looking up the user in the user store.
- Sm_AuthApi_SuccessThe authentication scheme asksSiteMinderto disambiguate the user.The authentication scheme puts the login ID into lpszUserMsg.SiteMinderuses that value to construct the DN or search expression and disambiguate the user in the user store. This approach gives the authentication scheme the opportunity to modify the login ID beforeSiteMinderdisambiguates the user.If the authentication scheme leaves lpszUserMsg empty,SiteMinderuses the login ID provided by the Agent (the same behavior as with return code SmAuthApi_NoUserContext).
- Sm_AuthApi_SuccessUserDNThe authentication scheme disambiguates the user by constructing the complete DN or search expression and looking up the user in the user store. The authentication scheme passes the user’s complete DN or ODBC database ID toSiteMinderin lpszUserMsg. Only one DN or database ID can be passed in lpszUserMsg.
- Sm_AuthApi_SuccessUserFilterSiteMinderdisambiguates the user based upon a standard LDAP search filter that the authentication scheme constructs and passes in lpszUserMsg. WhenSiteMinderis passed this return code, it ignores the Start and End field values configured for the user directory.
- Sm_AuthApi_AttemptThe user cannot be found in the directory.
- Sm_AuthApi_FailureThe error text is returned in lpszUserMsg.
During the user authentication phase,
SiteMinder
calls SmAuthenticate() again after the user context has been established during disambiguation. The function returns one of the following return codes:- Sm_AuthApi_AcceptThe user is authenticated.
- Sm_AuthApi_RejectThe user is not authenticated.
- Sm_AuthApi_ChallengeThe user is challenged. The scheme should store the challenge to be presented to the user in lpszUserMsg. Also, a reason code must be supplied in the SM_MAKEAUTH_STATUSVALUE macro. For information about the reason code, see Returns.
- Sm_AuthApi_FailureThe error text is returned in lpszUserMsg.
Example: User Authentication Procedure
Sm_AuthApi_Status_t SM_EXTERN SmAuthenticate (const Sm_Api_Context_t*lpApiContext,// The structure that provides API contextconst Sm_Api_UserContext_t*lpUserContext,// The structure that allows access to user propertiesconst Sm_AuthApi_UserCredentials_t*lpUserCredentials,// The user credentialsunsigned char bChallengeResponse,// Boolean indicating whether this is the response to a challengeconst char* lpszServerParam,// The parameter to be passed to the serverconst char* lpszSharedSecret,// The shared secret to be passed to the serverconst int nBytesUserMsg,// Maximum size of the user message bufferchar* lpszUserMsg,// Output buffer to hold the null-terminated user messageconst int nBytesErrMsg,// Maximum size of the error bufferchar* lpszErrMsg)// Output buffer to hold the null-terminated error message{if (!lpUserContext->bIsUserContext)return Sm_AuthApi_NoUserContext;return (0 == lpUserContext->fAuthenticate (lpUserContext->lpParam,lpUserCredentials->lpszPassword,nBytesUserMsg,lpszUserMsg,nBytesErrMsg,lpszErrMsg) ? Sm_AuthApi_Accept : Sm_AuthApi_Reject);}
Release Procedure
To perform any rundown operations the scheme requires,
SiteMinder
calls the release procedure once for each authorization scheme instance. The scheme releases all its resources at this time. The calling sequence specifies two input parameters. You can use one or both of these parameters as best suits your implementation.Example: Release Procedure
C++
// SmAuthRelease:// PARAMETERS:// [in] lpszServerParam: Parameter string as specified for the authentication scheme.// [in] lpszSharedSecret: Shared secret string specified in the authentication scheme.//// RETURNS:// Any one of the following Sm_AuthApi_Status_t values:// Sm_AuthApi_Success// Sm_Authapi_Failure*/Sm_AuthApi_Status_t SM_EXTERN SmAuthRelease (const char * lpszServerParam, /* server parameter */const char * lpszSharedSecret) /* server shared secret */{return Sm_AuthApi_Success;}