Implement the Java Authentication API Interface

Creating the custom authentication scheme includes implementing the following procedures:
sm1252sp1
Creating the custom authentication scheme includes implementing the following procedures:
Query Procedure
When the custom authentication scheme loads into memory,
CA Single Sign-On
calls the query method 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 method reads a constant value that specifies what information the authentication scheme requires. The method passes back the appropriate information in the designated output parameter. When the call to the query method completes successfully,
CA Single Sign-On
has the appropriate information about the authentication scheme.
Example: Query procedure
 /**
     * Returns information about the authentication scheme.
     *
     * @param parameter - The parameter string as specified for the authentication scheme.
     * @param secret - The secret string as specified for the authentication scheme.
     * @param request - The request code, SMAUTH_QUERY_DESCRIPTION or SMAUTH_QUERY_CREDENTIALS_REQ.
     * @param response - Holds methods by which query() returns the requested information.
     * @return: If successful, returns SMAUTH_SUCCESS; otherwise, returns SMAUTH_FAILURE.
     */
 
    public SmAuthStatus
    query(String parameter,
          String secret,
          SmAuthQueryCode request,
          SmAuthQueryResponse response)
    {
        if (null == response)
        {
            return SmAuthStatus.SMAUTH_FAILURE;
        }
 
        if (SmAuthQueryCode.SMAUTH_QUERY_DESCRIPTION == request)
        {
            response.setResponseBuffer(SCHEME_DESCRIPTION);
            response.setResponseCode(SCHEME_VERSION);
        }
        else if (SmAuthQueryCode.SMAUTH_QUERY_CREDENTIALS_REQ == request)
        {
            response.setResponseCode(SmAuthQueryResponse.SMAUTH_CRED_BASIC);
        }
        else
        {
            return SmAuthStatus.SMAUTH_FAILURE;
        }
 
        return SmAuthStatus.SMAUTH_SUCCESS;
    }
Initialization Procedure
To initialize your custom authentication scheme, implement the init() method. The calling sequence specifies two input parameters. You can use one or both of these parameters as best suits your implementation.
Example: Initialization procedure
/**
     * @param parameter - The parameter string as specified for the authentication scheme.
     * @param secret - The secret string as specified for the authentication scheme.
     * @return: If successful returns SMAUTH_SUCCESS, otherwise returns SMAUTH_FAILURE
     */
 
    public SmAuthStatus
    init(String parameter,
         String secret)
    {
        return SmAuthStatus.SMAUTH_SUCCESS;
    }
User Authentication Procedure
The authentication process includes two phases—user disambiguation and user authentication. During each phase, the user authentication procedure is called as follows:
  • During disambiguation,
    CA Single Sign-On
    calls the procedure once per directory where disambiguation occurred.
  • During authentication,
    CA Single Sign-On
    calls the procedure once per user found in the directory.
User authentication includes the following steps:
  1. User login
    The user supplies a login ID (such as jsmith) for authentication purposes.
  2. User Disambiguation
    User disambiguation is the process of locating a user in the user store, such as an LDAP user directory or an ODBC database. Either
    CA Single Sign-On
    or 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 is constructed based on the supplied login ID. For example, if the login ID is jsmith, the DN used to search the user store can possibly be constructed as follows:
    uid=jsmith,ou=marketing,o=myorg.org
    An 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 can apply to different users who have different passwords.
  3. Authentication
    The custom authentication scheme compares the known credentials of each disambiguated user with the credentials supplied during login. For example, the scheme can compare the hash of the supplied password against the hash in the user store.
Example: User Authentication Procedure
/**
     * SiteMinder invokes this method to authenticate user credentials.
     *
     * @param parameter - The parameter string as specified for the authentication scheme.
     * @param secret - The secret string as specified for the authentication scheme.
     * @param challengeReason - The reason for the original authentication challenge, or 0 if unknown.
     * @param context - Contains request context and methods to return message buffers.
     *
     * @return: an SmAuthenticationResult object.
     */
 
    public SmAuthenticationResult
    authenticate(String parameter,
                 String secret,
                 int challengeReason,
                 SmAuthenticationContext context)
    {
        // cannot do authentication without the authentication context
        if (null == context)
        {
            return
                new SmAuthenticationResult(SmAuthStatus.SMAUTH_NO_USER_CONTEXT, SmAuthenticationResult.REASON_NONE);
        }
 
        // If the scheme is designed not to disambiguate users, it should return SmAuthApi_NoUserContext.
        UserContext theUserContext = context.getUserContext();
 
        if ((null == theUserContext) || !theUserContext.isUserContext())
        {
            return
                new SmAuthenticationResult(SmAuthStatus.SMAUTH_NO_USER_CONTEXT, SmAuthenticationResult.REASON_NONE);
        }
 
        // Reject the user if the password is not entered.
        UserCredentialsContext theUserCredentialsContext = context.getUserCredentialsContext();
 
        if (null == theUserCredentialsContext)
        {
            return
                new SmAuthenticationResult(SmAuthStatus.SMAUTH_REJECT, SmAuthenticationResult.REASON_NONE);
        }
 
        String thePassword = theUserCredentialsContext.getPassword();
 
        if (thePassword.length() <= 0)
        {
            return
                new SmAuthenticationResult(SmAuthStatus.SMAUTH_REJECT, SmAuthenticationResult.REASON_NONE);
        }
 
        // Check if the user account is disabled.
        try
        {
            if (0 != Integer.parseInt(theUserContext.getProp("disabled")))
            {
                context.setUserText("User account is disabled.");
 
                return
                    new SmAuthenticationResult(SmAuthStatus.SMAUTH_REJECT, SmAuthenticationResult.REASON_USER_DISABLED);
            }
        }
        catch (NumberFormatException exc)
        {
            // Do nothing -- the user is not disabled
        }
 
        // authenticate the user
        String authUserText;
 
        try
        {
            authUserText = theUserContext.authenticateUser(thePassword);
        }
        catch (Throwable exc)
        {
            // insure subsequent code knows the authentication attempt failed
            authUserText = null;
        }
 
        if (null == authUserText)
        {
            context.setErrorText("Unable to authenticate user " + theUserContext.getUserName());
 
            return
                new SmAuthenticationResult(SmAuthStatus.SMAUTH_REJECT, SmAuthenticationResult.REASON_NONE);
        }
 
        // Set the time stamp of the user's last authentication.
        // For demonstration purposes, we will store the last login
        // in the "PIN" user property as a printable date&time string.
 
        String timeString = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.MEDIUM).format(new Date());
 
        // put single quotes around the string if the user directory is "ODBC:"
        String theNameSpace = theUserContext.getDirNameSpace();
 
        if ((theNameSpace != null) && theNameSpace.equals("ODBC:"))
        {
            timeString = "'" + timeString + "'" ;
        }
 
        if (0 != theUserContext.setProp("pin", timeString))
        {
            context.setUserText("Failed to set the time stamp for user's profile attribute " + parameter);
        }
 
        // If a parameter is supplied, set it as app specific data
        if (parameter != null)
        {
            try
            {
                APIContext apiContext = context.getAPIContext();
                AppSpecificContext appContext = apiContext.getAppSpecificContext();
                appContext.setData(parameter.getBytes());
            }
            catch (NullPointerException exc)
            {
                context.setUserText("Failed to modify application specific context");
            }
            catch (SmJavaApiException exc)
            {
                context.setUserText("Failed to modify application specific context");
            }
        }
 
        return
            new SmAuthenticationResult(SmAuthStatus.SMAUTH_ACCEPT, SmAuthenticationResult.REASON_NONE);
    }
}
Release Procedure
CA Single Sign-On
calls the release procedure to perform any rundown operations the scheme requires.
CA Single Sign-On
calls the 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
/**
     * @param parameter - The parameter string as specified for the authentication scheme.
     * @param secret - The secret string as specified for the authentication scheme.
     * @return: If successful returns SMAUTH_SUCCESS, otherwise returns SMAUTH_FAILURE
     */
 
    public SmAuthStatus
    release(String parameter,
            String secret)
    {
        return SmAuthStatus.SMAUTH_SUCCESS;
    }