package org.jboss.seam.security.jaas; import java.io.IOException; import javax.enterprise.context.RequestScoped; import javax.enterprise.inject.spi.BeanManager; import javax.inject.Inject; import javax.inject.Named; import javax.security.auth.Subject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; import org.jboss.solder.logging.Logger; import org.jboss.seam.security.Authenticator; import org.jboss.seam.security.BaseAuthenticator; import org.jboss.seam.security.Credentials; import org.jboss.seam.security.Identity; import org.picketlink.idm.impl.api.PasswordCredential; /** * An authenticator for authenticating with JAAS. The jaasConfigName property * _must_ be configured to point to a valid JAAS configuration name, typically * defined in a file called login-config.xml in the application server. * * @author Shane Bryzak */ public @Named @RequestScoped class JaasAuthenticator extends BaseAuthenticator implements Authenticator { private static final Logger log = Logger.getLogger(JaasAuthenticator.class); @Inject Identity identity; @Inject Credentials credentials; @Inject BeanManager manager; private Subject subject; private String jaasConfigName = null; public JaasAuthenticator() { subject = new Subject(); } public void authenticate() { if (getJaasConfigName() == null) { throw new IllegalStateException("jaasConfigName cannot be null. Please set it to a valid JAAS configuration name."); } try { getLoginContext().login(); setStatus(AuthenticationStatus.SUCCESS); } catch (LoginException e) { setStatus(AuthenticationStatus.FAILURE); log.error("JAAS authentication failed", e); } } protected LoginContext getLoginContext() throws LoginException { return new LoginContext(getJaasConfigName(), subject, createCallbackHandler()); } /** * Creates a callback handler that can handle a standard username/password * callback, using the credentials username and password properties */ public CallbackHandler createCallbackHandler() { return new CallbackHandler() { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof NameCallback) { ((NameCallback) callbacks[i]).setName(credentials.getUsername()); } else if (callbacks[i] instanceof PasswordCallback) { if (credentials.getCredential() instanceof PasswordCredential) { PasswordCredential credential = (PasswordCredential) credentials.getCredential(); ((PasswordCallback) callbacks[i]).setPassword(credential.getValue() != null ? credential.getValue().toCharArray() : null); } } else { log.warn("Unsupported callback " + callbacks[i]); } } } }; } public String getJaasConfigName() { return jaasConfigName; } public void setJaasConfigName(String jaasConfigName) { this.jaasConfigName = jaasConfigName; } public void postAuthenticate() { } }