ClientCertificateLoginModulepublic class ClientCertificateLoginModule extends Object implements LoginModule This LoginModule authenticates users with X509 certificates.
If testUser successfully authenticates itself,
a PrincipalImpl with the testUser's username
is added to the Subject.
This LoginModule recognizes the debug option.
If set to true in the login Configuration,
debug messages will be output to the output stream, System.out. |
Fields Summary |
---|
private static Logger | _logger | private static com.sun.enterprise.util.LocalStringManagerImpl | localStrings | private static KeyStore | ks | private Subject | subject | private CallbackHandler | callbackHandler | private Map | sharedState | private Map | options | private boolean | debug | private boolean | succeeded | private boolean | commitSucceeded | private String | alias | private X509Certificate | certificate | private com.sun.enterprise.deployment.PrincipalImpl | userPrincipal |
Methods Summary |
---|
public boolean | abort() This method is called if the LoginContext's
overall authentication failed.
(the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
did not succeed).
If this LoginModule's own authentication attempt
succeeded (checked by retrieving the private state saved by the
login and commit methods),
then this method cleans up any state that was originally saved.
if (succeeded == false) {
return false;
} else if (succeeded == true && commitSucceeded == false) {
// login succeeded but overall authentication failed
succeeded = false;
alias = null;
userPrincipal = null;
} else {
// overall authentication succeeded and commit succeeded,
// but someone else's commit failed
logout();
}
return true;
| public boolean | commit() This method is called if the LoginContext's
overall authentication succeeded
(the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
succeeded).
If this LoginModule's own authentication attempt
succeeded (checked by retrieving the private state saved by the
login method), then this method associates a
PrincipalImpl
with the Subject located in the
LoginModule . If this LoginModule's own
authentication attempted failed, then this method removes
any state that was originally saved.
if (succeeded == false) {
return false;
} else {
// add a Principal (authenticated identity)
// to the Subject
// assume the user we authenticated is the PrincipalImpl
userPrincipal = new PrincipalImpl(alias);
if (!subject.getPrincipals().contains(userPrincipal)){
subject.getPrincipals().add(userPrincipal);
}
if (debug) {
if(_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE,"\t\t[ClientCertificateLoginModule] " +
"added PrincipalImpl to Subject");
}
}
Ssl ssl = new Ssl();
ssl.setCertNickname(this.alias);
SSLUtils.setAppclientSsl(ssl);
String realm = LoginContextDriver.CERT_REALMNAME;
X509Certificate[] certChain = new X509Certificate[1];
certChain[0] = certificate;
X509CertificateCredential pc =
new X509CertificateCredential(certChain, alias, realm);
if(!subject.getPrivateCredentials().contains(pc)) {
subject.getPrivateCredentials().add(pc);
}
commitSucceeded = true;
return true;
}
| private void | init()Initialize the key store.
try {
if(ks == null) {
SSLUtils.initStoresAtStartup();
}
} catch(Exception e) {
_logger.log(Level.SEVERE,"java_security.initkeystore_exception",e);
}
| public void | initialize(javax.security.auth.Subject subject, javax.security.auth.callback.CallbackHandler callbackHandler, java.util.Map sharedState, java.util.Map options)Initialize this LoginModule .
this.subject = subject;
this.callbackHandler = callbackHandler;
this.sharedState = sharedState;
this.options = options;
// initialize any configured options
debug = "true".equalsIgnoreCase((String)options.get("debug"));
init();
| public boolean | login()Authenticate the user by prompting for a username and password.
// prompt for a username and password
if (callbackHandler == null){
throw new LoginException("Error: no CallbackHandler available " +
"to garner authentication information from the user");
}
try {
String[] as = new String[ks.size()];
String[] aliasString = new String[ks.size()];
Enumeration aliases = ks.aliases();
for(int i = 0; i < ks.size(); i++) {
aliasString[i] = (String) aliases.nextElement();
as[i] = ((X509Certificate)ks.getCertificate(aliasString[i])).getSubjectDN().getName();
}
Callback[] callbacks = new Callback[1];
callbacks[0] = new ChoiceCallback(localStrings.getLocalString("login.certificate", "Choose from list of certificates: "), as, 0, false);
callbackHandler.handle(callbacks);
String[] choices = ((ChoiceCallback)callbacks[0]).getChoices();
int[] idx = ((ChoiceCallback)callbacks[0]).getSelectedIndexes();
if (choices == null) {
// figure out
}
if (idx == null) {
throw new LoginException ("No certificate selected!");
} else if (idx[0] == -1){
throw new LoginException ("Incorrect keystore password");
}
// print debugging information
if (debug) {
if(_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE,"\t\t[ClientCertificateLoginModule] " +
"user entered certificate: ");
for (int i = 0; i < idx.length; i++){
_logger.log(Level.FINE,aliasString[idx[i]]);
}
}
}
// the authenticate method previously picked out the
// wrong alias.
// since we allow only 1 choice the first element in idx
// idx[0] should have the selected index.
this.alias = aliasString[idx[0]];
certificate = (X509Certificate) ks.getCertificate(alias);
// the authenticate should always return a true.
if (debug){
if(_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE,"\t\t[ClientCertificateLoginModule] " +
"authentication succeeded");
}
}
succeeded = true;
return true;
} catch (java.io.IOException ioe) {
throw new LoginException(ioe.toString());
} catch (UnsupportedCallbackException uce) {
throw new LoginException("Error: " + uce.getCallback().toString() +
" not available to garner authentication information " +
"from the user");
} catch (Exception e) {
throw new LoginException(e.toString());
}
| public boolean | logout()Logout the user.
This method removes the PrincipalImpl
that was added by the commit method.
// unset the alias
SSLUtils.setAppclientSsl(null);
subject.getPrincipals().remove(userPrincipal);
succeeded = false;
succeeded = commitSucceeded;
alias = null;
userPrincipal = null;
return true;
| public static void | setKeyStore(java.security.KeyStore keyStore)
ks = keyStore;
|
|