Sample Custom LoginModule
The following code defines a sample custom login module CelmExampleUsernamePasswordLoginModule class:
CelmExampleUsernamePasswordLoginModule Sample Class
package com.example.security.authentication.provider.celm; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.LoginException; import org.opensaml.xml.util.XMLHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import com.tibco.asg.security.provider.celm.CelmAbstractLoginModule; /** * CelmExampleUsernamePasswordLoginModule is an example LoginModule * to demonstrate how to extend CelmExampleUsernamePasswordLoginModule. * */ public class CelmExampleUsernamePasswordLoginModule extends CelmAbstractLoginModule { private static Logger logger = LoggerFactory.getLogger(CelmExampleUsernamePasswordLoginModule.class); private String authorizedUsername = null; private String authorizedPassword = null; private String authorizedRole = null; /** * Perform initialize. * <p> * This method is called when login() in initialize is called. * * @param subject the Subject for authentication. * @param callbackHandler the callback handler to provide authentication * variables like username/password, etc. * @param sharedState * @param options a map contains the options from properties file. */ @Override public void initialize(Subject subject, CallbackHandler callbackHandler, final Map<String, ?> sharedState, final Map<String, ?> options) { super.initialize(subject, callbackHandler, sharedState, options); authorizedUsername = (String)options.get("com.tibco.asg.security.provider.celm.authorizedUsername"); authorizedPassword = (String)options.get("com.tibco.asg.security.provider.celm.authorizedPassword"); authorizedRole = (String)options.get("com.tibco.asg.security.provider.celm.authorizedRole"); } /** * Perform login. * <p> * This method is called when login() in LoginModule is called. * */ @Override public boolean doLogin() throws LoginException { if (getMessageElement() != null) extractUsernamePassword(getMessageElement().getOwnerDocument()); return authenticateUsernamePassword(getUsername(), getPassword()); } /** * Perform commit. * <p> * This method is called when commit() in LoginModule is called. * */ @Override public boolean doCommit() throws LoginException { return true; } /** * Perform cleanup. * <p> * This method is called when cleanup() in LoginModule is called. * */ @Override public void doCleanUp() throws LoginException { super.doCleanUp(); } // // The methods below are example to show: // 1. How to username/password can be extracted from SOAP header. // 2. AUthenticat the user. // private static final String WSSE_NS = "http://schemas.xmlsoap.org/ws/2002/04/secext"; private static final String USERNAME = "Username"; private static final String PASSWORD = "Password"; /** * Extract username and password from the request. * * This example extract the username and password from the document. * It is expecting the username and password is from a element with * a specific namespace. * * This example does not handle and valid replay attack. * * @param document * @return * @throws LoginException */ private void extractUsernamePassword(Document document) throws LoginException { try { NodeList nl = null; nl = document.getElementsByTagNameNS(WSSE_NS, USERNAME); if (nl.getLength() != 0) { // save the username setUsername(nl.item(0).getFirstChild().getNodeValue()); } nl = document.getElementsByTagNameNS(WSSE_NS, PASSWORD); if (nl.getLength() != 0) { // save the password setPassword(nl.item(0).getFirstChild().getNodeValue()); } } catch (Exception e) { logger.error("Unable to extract username/password from request", e); } } /** * Authenticate the given username and password. * * This example validate the username/password against the username/password * extracted from the properties file in the * {@link #initialize(Subject, CallbackHandler, Map, Map)} method above. * * Note that name identifier should be set if username is authenticated. * The name identifier is used for the Subject's NameIdentifier when * building the SAML assertion. * * There may be other way to validate the username/password, for example, * look up password for the user in database. * * @param username username to verify. * @param password password to verify. * @throws LoginException throw if authentication failed. */ private boolean authenticateUsernamePassword(String username, String password) throws LoginException { if (authorizedUsername == null && authorizedPassword == null) throw new LoginException("Invalid credentials"); if (username.equals(authorizedUsername) && password.equals(authorizedPassword)) { this.setNameIdentifier(username); this.setRoles(extractRoles(username)); return true; } throw new LoginException("Invalid credentials"); } /** * Extract roles for the given user. * * This example adds the role extracted from the properties file. * * There may be other way to get the roles for the authenticate user, * for example, look up the roles for the user in database. * * @param username user whos roleas to be extracted * @return set of roles for the specified user. */ private Set<String> extractRoles(String username) { HashSet<String> roleSet = new HashSet<String>(); if (authorizedRole != null) roleSet.add(authorizedRole); return roleSet; } }
Copyright © Cloud Software Group, Inc. All rights reserved.