package com.evasion.sam;
import com.evasion.sam.ejb.JNDIClient;
import com.evasion.sam.ejb.JaasEjb;
import com.evasion.sam.jaas.EvasionPrincipal;
import java.io.IOException;
import java.security.Principal;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.security.auth.message.AuthException;
import javax.security.auth.message.AuthStatus;
import javax.security.auth.message.MessageInfo;
import javax.security.auth.message.MessagePolicy;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
*
*
* @author nasradu8
*/
public class SAM extends ServletAuthModule {
private static final Logger LOGGER = Logger.getLogger(SAM.class.getName());
private static final String PARAM_EJB_JNDI = "EJB-jndi";
private static final String PARAM_PROVIDER_URL = "provider-url";
private String lcName = null;
private JaasEjb loginEJB = null;
private LoginContext lc = null;
private MyCBH cbh = null;
@Override
public void initialize(MessagePolicy requestPolicy, MessagePolicy responsePolicy, CallbackHandler handler, Map options) throws AuthException {
LOGGER.finer("Init SAM");
super.initialize(requestPolicy, responsePolicy, handler, options);
String jndi = (String) options.get(PARAM_EJB_JNDI);
String providerUrl = (String) options.get(PARAM_PROVIDER_URL);
LOGGER.finer("SAM mandatory : " + requestPolicy.isMandatory());
if (this.options != null) {
this.lcName = (String) options.get("javax.security.auth.login.LoginContext");
LOGGER.fine("Login Context Name:" + this.lcName);
}
try {
getLc();
JNDIClient ejbClient = new JNDIClient(providerUrl);
loginEJB = (JaasEjb) ejbClient.lookup(jndi);
} catch (LoginException ex) {
LOGGER.severe("Exception d'init SAM" + ex.toString());
AuthException ae = new AuthException();
ae.initCause(ex);
throw ae;
}
}
@Override
public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject) throws AuthException {
AuthStatus result = AuthStatus.FAILURE;
HttpServletRequest request = (HttpServletRequest) messageInfo.getRequestMessage();
HttpServletResponse response = (HttpServletResponse) (messageInfo.getResponseMessage());
String jeVeux = request.getRequestURL().toString();
String loginURI = request.getContextPath() + "/login.xhtml";
try {
debugRequest(request);
// Get our session ...
HttpSession session = request.getSession(false);
debugSession(session);
LOGGER.fine("Client Subject UserPrincipal " + clientSubject.getPrincipals(EvasionPrincipal.class));
// Traitement d'une demande de validation de formulaire
if (jeVeux.endsWith(Constants.PATH_SECURITY_CHECK)) {
//Callback Handler requires the request in order to get username and password.
cbh.setRequest(request);
lc.login();
LOGGER.fine("Traitement du formulaire d'authentification");
Subject subject = lc.getSubject();
savePrincipals(request, subject);
saveTokenId(request, "success");
String urlDestination = getSavedRequestURL(session);
if (urlDestination == null) {
urlDestination = response.encodeRedirectURL(request.getContextPath() + "/");
}
redirect(urlDestination, response);
result = AuthStatus.SEND_SUCCESS;
} else if (jeVeux.endsWith(Constants.PATH_SECURITY_LOGOUT)) {
LOGGER.fine("Traitement d'une demande de deconnexion");
String urlDestination = response.encodeRedirectURL(request.getContextPath() + "/");
if (session != null) {
session.invalidate();
}
redirect(urlDestination, response);
result = AuthStatus.SEND_SUCCESS;
} else {
// Récupération du token
String token = getToken(request);
LOGGER.fine("Token map: " + token);
// Redirection vers la page de login
if (isMandatory) {
clearSavedRequestURLs(request);
if (token == null || token.isEmpty()) {
LOGGER.fine("redirection vers la page de login");
saveLoginBackToURL(request, session);
redirect(loginURI, response);
result = AuthStatus.SEND_CONTINUE;
}
}
if (restorePrincipals(request, clientSubject)) {
LOGGER.fine("acces page avec authentification");
Principal userPrincipal = setCallerPrincipal(clientSubject);
messageInfo.getMap().put(REGISTER_WITH_AUTHENTICATOR, true);
messageInfo.getMap().put(AUTH_TYPE_INFO_KEY, "EvasionSAM");
loginEJB.postLogin(userPrincipal.getName());
}
result = AuthStatus.SUCCESS;
}
if (result == AuthStatus.SEND_FAILURE) {
request.getSession().setAttribute("EVASION_AUTH", false);
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
}
} catch (LoginException ex) {
LOGGER.severe("Login Exception!!! : " + ex.getMessage());
((HttpSession) request.getSession()).setAttribute(Constants.EVASION_LAST_EXCEPTION_KEY, Constants.BAD_CREDENTIAL_EXCEPTION);
redirect(loginURI, response);
result = AuthStatus.SEND_CONTINUE;
} catch (Exception ex) {
LOGGER.log(Level.SEVERE, "ERROR SAM!!!", ex);
try {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (IOException ex1) {
Logger.getLogger(SAM.class.getName()).log(Level.SEVERE, null, ex1);
}
result = AuthStatus.SEND_FAILURE;
}
LOGGER.finer("ValidateRequest result: " + result);
return result;
}
void redirect(String url, HttpServletResponse response)
throws AuthException {
try {
LOGGER.finer("redirecting_to " + url);
response.setHeader("Location", url);
response.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT);
} catch (Exception e) {
LOGGER.warning("error_redirecting_to " + url);
AuthException ae = new AuthException();
ae.initCause(e);
throw ae;
}
}
@Override
public void cleanSubject(MessageInfo messageInfo, Subject subject) throws AuthException {
super.cleanSubject(messageInfo, subject);
try {
lc.logout();
} catch (LoginException ex) {
AuthException ae = new AuthException();
ae.initCause(ex);
throw ae;
}
}
private LoginContext getLc() throws LoginException {
if (lc == null) {
cbh = new MyCBH();
lc = new LoginContext((lcName != null) ? lcName : getClass().getName(), cbh);
}
return lc;
}
}