Hello to all,
I'm trying to develop a custom login modul. Now I did as described at http://help.sap.com/saphelp_nw04/helpdata/en/46/3ce9402f3f8031e10000000a1550b0/content.htm
But authentication always fails.
How can I read the provided user? Is it "user_name" or "j_user" as in the http-post?
Is it possible to debug the module? It is deployed as library and I don't know how to debug it.
Please advice
Regards Christian
Next my code:
package de.xy.ume; import java.util.Map; import java.io.IOException; import javax.security.auth.login.LoginException; import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.Callback; import javax.security.auth.callback.UnsupportedCallbackException; import com.sap.engine.interfaces.security.auth.AbstractLoginModule; import com.sap.engine.lib.security.http.HttpGetterCallback; import com.sap.engine.lib.security.http.HttpCallback; import com.sap.engine.lib.security.LoginExceptionDetails; import com.sap.engine.lib.security.Principal; public class FilterUsername extends AbstractLoginModule { // Define the variables that will be used later on: private CallbackHandler callbackHandler = null; private Subject subject = null; private Map sharedState = null; private Map options = null; // This is the name of the user you have created on // the J2EE Engine so you can test the login module private String userName = null; private boolean successful; private boolean nameSet; /** * The method initializes the login module with the * relevant authentication and state information. */ public void initialize( Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) { // This is the only required step for the method super.initialize(subject, callbackHandler, sharedState, options); // Initializing the values of the variables this.callbackHandler = callbackHandler; this.subject = subject; this.sharedState = sharedState; this.options = options; this.successful = false; this.nameSet = false; } /** * Retrieves the user credentials and checks them. This is * the first part of the authentication process. */ public boolean login() throws LoginException { // Retrieve the user credentials via the callback // handler. // In this case we get the user name from the HTTP // request parameters. Callback[] callbacks = new Callback[1]; callbacks[0] = new HttpGetterCallback(); /* The type and the name specify which part of the HTTP request * should be retrieved. For Web container authentication, the * supported types are defined in the interface * com.sap.engine.lib.security.http.HttpCallback. * For programmatical authentication with custom callback * handler the supported types depend on the used callback handler. */ ((HttpGetterCallback) callbacks[0]).setType( HttpCallback.REQUEST_PARAMETER); //((HttpGetterCallback) callbacks[0]).setName("user_name"); ((HttpGetterCallback) callbacks[0]).setName("j_user"); try { callbackHandler.handle(callbacks); } catch (UnsupportedCallbackException e) { return false; } catch (IOException e) { throwUserLoginException(e, LoginExceptionDetails.IO_EXCEPTION); } //Returns an array of all request parameters with name "user_name". String[] requestParameters = (String[]) ((HttpGetterCallback) callbacks[0]).getValue(); if ((requestParameters != null) && requestParameters.length > 0) { userName = requestParameters[0]; } if (userName == null) { throwNewLoginException("No user name provided."); } /* When you know the user name, update the user information * using data from the persistence. The operation must * be done before the user credentials checks. This method also * checks the user name so that if a user with that name does not * exist in the active user store, a * java.lang.SecurityException is thrown. */ try { refreshUserInfo(userName); } catch (SecurityException e) { throwUserLoginException(e); } /* Checks if the given user name starts with the specified * prefix in the login module options. If no prefix is specified, * then all users are trusted. */ /* String prefix = (String) options.get("user_name_prefix"); if ((prefix != null) && !userName.startsWith(prefix)) { throwNewLoginException("The user is not trusted."); } */ /* This is done if the authentication of the login module is * successful. * Only one and exactly one login module from the stack must put * the user name in the shared state. This user name represents * the authenticated user. * For example if the login attempt is successful, method * getRemoteUser() of * the HTTP request will retrieve exactly this name. */ if (sharedState.get(AbstractLoginModule.NAME) == null) { sharedState.put(AbstractLoginModule.NAME, userName); nameSet = true; } successful = true; return true; } /** * Commit the login. This is the second part of the authentication * process. * If a user name has been stored by the login() method, * the user name is added to the subject as a new principal. */ public boolean commit() throws LoginException { if (successful) { /* The principals that are added to the subject should * implement java.security.Principal.You can use the class * com.sap.engine.lib.security.Principal for this purpose. */ Principal principal = new Principal(userName); subject.getPrincipals().add(principal); /* If the login is successful, then the principal corresponding * to the <userName> (the same user name that has been added * to shared state) must be added in the shared state too. * This principal is considered to be the main principal * representing the user. * For example, this principal will be retrieved from method * getUserPrincipal() of the HTTP request. */ if (nameSet) { sharedState.put(AbstractLoginModule.PRINCIPAL, principal); } } else { userName = null; } return true; } /** * Abort the authentication process. */ public boolean abort() throws LoginException { if (successful) { userName = null; successful = false; } return true; } /** * Log out the user. Also removes the principals and * destroys or removes the credentials that were associated * with the user during the commit phase. */ public boolean logout() throws LoginException { // Remove principals and credentials from subject if (successful) { subject.getPrincipals(Principal.class).clear(); successful = false; } return true; } }