com.evasion.sam.SAM Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of evasion-sam-modul Show documentation
Show all versions of evasion-sam-modul Show documentation
API de l'application modulaire evasion-en-ligne
package com.evasion.sam;
import com.evasion.sam.ejb.JNDIClient;
import com.evasion.sam.ejb.JaasEjb;
import com.evasion.sam.jaas.EvasionGroup;
import com.evasion.sam.jaas.EvasionPrincipal;
import java.io.IOException;
import java.security.Principal;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.Configuration;
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.security.auth.message.callback.CallerPrincipalCallback;
import javax.security.auth.message.callback.GroupPrincipalCallback;
import javax.security.auth.message.module.ServerAuthModule;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.transaction.UserTransaction;
/**
*
*
* @author nasradu8
*/
public class SAM implements ServerAuthModule {
private static final Logger LOGGER = Logger.getLogger(SAM.class.getName());
private static final String SAVED_SUBJECT = "Saved_Subject";
private static final String USER_NAME = "userName";
private static final String KEY_EVASION_SAVED_REQUEST_URL = "javax.security.evasion.SavedRequestURL";
private CallbackHandler handler;
private Config config = new Config();
protected static final Class[] SUPPORTED_MESSAGE_TYPES = new Class[]{
javax.servlet.http.HttpServletRequest.class,
javax.servlet.http.HttpServletResponse.class
};
private String lcName = null;
private JaasEjb loginEJB = null;
private LoginContext lc = null;
private MyCBH cbh = null;
JNDIClient ejbClient = null;
private String loginURI;
@Override
public void initialize(MessagePolicy requestPolicy, MessagePolicy responsePolicy, CallbackHandler handler, Map options) throws AuthException {
LOGGER.finer("Init SAM");
config.setJndi((String) options.get(Config.PARAM_EJB_JNDI));
config.setProviderUrl((String) options.get(Config.PARAM_PROVIDER_URL));
config.setDigestAlgorithm((String) options.get(Config.PARAM_DIGEST_ALGORITHM));
LOGGER.log(Level.FINER, "SAM mandatory : {0}", requestPolicy.isMandatory());
this.loginURI = (String) options.get(Constants.LOGIN_URL);
this.handler = handler;
if (options != null) {
this.lcName = (String) options.get(Constants.LOGIN_CONTEXT_IMPL);
LOGGER.log(Level.FINE, "Login Context Name:{0}", this.lcName);
}
try {
getLc();
ejbClient = new JNDIClient(config.getProviderUrl());
loginEJB = (JaasEjb) ejbClient.lookup(config.getJndi());
} catch (LoginException ex) {
LOGGER.log(Level.SEVERE, "Exception d''init SAM{0}", ex.toString());
AuthException ae = new AuthException();
ae.initCause(ex);
throw ae;
}
}
@Override
public Class[] getSupportedMessageTypes() {
return SUPPORTED_MESSAGE_TYPES.clone();
}
@Override
public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject) throws AuthException {
HttpServletRequest request = (HttpServletRequest) messageInfo.getRequestMessage();
HttpServletResponse response = (HttpServletResponse) (messageInfo.getResponseMessage());
LOGGER.log(Level.FINER, "ValidateRequest: {0}", request.getRequestURL().toString());
// Vérification si authentification déjà validé
HttpSession session = request.getSession(true);
if (request.getRequestURI().contains(Constants.PATH_SECURITY_LOGOUT)) {
LOGGER.finer("Logout request.");
response.setHeader("Location", response.encodeRedirectURL(request.getContextPath() + "/"));
response.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT);
session.invalidate();
return AuthStatus.SEND_SUCCESS;
}
Subject savedClientSubject = (Subject) session.getAttribute(SAVED_SUBJECT);
if (savedClientSubject != null) {
clientSubject.getPrincipals().addAll(savedClientSubject.getPrincipals());
clientSubject.getPublicCredentials().addAll(savedClientSubject.getPublicCredentials());
clientSubject.getPrivateCredentials().addAll(savedClientSubject.getPrivateCredentials());
return AuthStatus.SUCCESS;
}
if (!isMandatory(messageInfo) && !request.getRequestURI().contains(Constants.PATH_SECURITY_CHECK)) {
return AuthStatus.SUCCESS;
}
// See if the username / password has been passed in...
String username = request.getParameter("j_username");
String password = request.getParameter("j_password");
String backward = request.getParameter("j_backward");
LOGGER.log(Level.FINE, "Form param: {0} {1} {2}", new Object[]{username, password, request.getMethod()});
if ((username == null) || (password == null)) { // @TODO à remettre || !request.getMethod().equalsIgnoreCase("post")) {
// Not passed in, show the login page...
//RequestDispatcher rd = request.getRequestDispatcher(this.loginURI);
try {
response.setHeader("Location", response.encodeRedirectURL(request.getContextPath() + this.loginURI));
response.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT);
// rd.forward(request, response);
} catch (Exception ex) {
AuthException ae = new AuthException();
ae.initCause(ex);
throw ae;
}
return AuthStatus.SEND_CONTINUE;
}
// Check to see if successfull
try {
cbh.setRequest(request);
lc.login();
LOGGER.fine("Traitement du formulaire d'authentification");
clientSubject = lc.getSubject();
Principal userPrincipal = setCallerPrincipal(clientSubject);
// recreate the session
Map map = new HashMap();
Enumeration names = session.getAttributeNames();
while (names.hasMoreElements()) {
String key = names.nextElement();
map.put(key, session.getAttribute(key));
}
session.invalidate();
session = request.getSession(true);
for (String key : map.keySet()) {
session.setAttribute(key, map.get(key));
}
// Save the Subject...
session.setAttribute(SAVED_SUBJECT, clientSubject);
// Save the userName
session.setAttribute(USER_NAME, username);
try {
// Redirect...
if (getSavedRequestURL(session) != null) {
response.sendRedirect(response.encodeRedirectURL(getSavedRequestURL(session)));
} else if (backward != null) {
response.sendRedirect(response.encodeRedirectURL(backward));
} else {
response.sendRedirect(response.encodeRedirectURL(request.getContextPath() + "/"));
}
} catch (Exception ex) {
AuthException ae = new AuthException();
ae.initCause(ex);
throw ae;
}
/*
* if ((new Date().getTime() - ((EvasionPrincipal)
* userPrincipal).getLastLogin().getTime()) > 86400) {
* UserTransaction tx = ejbClient.getTransaction(); if (tx != null)
* { LOGGER.log(Level.FINE, "UserTransaction status
* {0}",tx.getStatus()); tx.begin(); try {
* loginEJB.postLogin(userPrincipal.getName()); } finally {
* tx.commit(); tx = null; } } }
*/
saveLoginBackToURL(request, session);
// Continue...
return AuthStatus.SEND_CONTINUE;
} catch (LoginException le) {
LOGGER.log(Level.SEVERE, "ERROR SAM!!!", le);
RequestDispatcher rd = request.getRequestDispatcher(this.loginURI);
try {
rd.forward(request, response);
} catch (Exception ex) {
AuthException ae = new AuthException();
ae.initCause(ex);
throw ae;
}
return AuthStatus.SEND_FAILURE;
} 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);
}
return AuthStatus.SEND_FAILURE;
}
}
private Principal setCallerPrincipal(Subject clientSubject) throws AuthException {
boolean assignGroups = true;
List groups = new ArrayList();
Principal userPrincipal = null;
String[] assignedGroups = null;
for (Principal p : clientSubject.getPrincipals()) {
String tmp = p.getName();
LOGGER.log(Level.FINE, "Principal utilis\u00e9: {0}", tmp);
if (p instanceof EvasionGroup && "Roles".equals(tmp)) {
EvasionGroup evasionGroup = (EvasionGroup) p;
for (Principal grp : Collections.list(evasionGroup.members())) {
groups.add(grp.getName());
LOGGER.log(Level.FINE, "Groupe associe: {0}", grp.getName());
}
assignedGroups = new String[groups.size()];
assignedGroups = groups.toArray(assignedGroups);
} else {
userPrincipal = p;
}
}
CallerPrincipalCallback callerPrincipalCallback = new CallerPrincipalCallback(clientSubject, userPrincipal);
if (callerPrincipalCallback.getName() == null && callerPrincipalCallback.getPrincipal() == null) {
assignGroups = false;
}
try {
handler.handle((assignGroups ? new Callback[]{
callerPrincipalCallback,
new GroupPrincipalCallback(callerPrincipalCallback.getSubject(),
assignedGroups)} : new Callback[]{callerPrincipalCallback}));
LOGGER.log(Level.FINE, "jmac.caller_principal:{0} {1}", new Object[]{callerPrincipalCallback.getName(), callerPrincipalCallback.getPrincipal()});
} catch (Exception ex) {
LOGGER.log(Level.SEVERE, "ERROR SAM!!!", ex);
AuthException ae = new AuthException();
ae.initCause(ex);
throw ae;
}
return userPrincipal;
}
@Override
public void cleanSubject(MessageInfo messageInfo, Subject subject) throws AuthException {
HttpServletRequest request = (HttpServletRequest) messageInfo.getRequestMessage();
clearSavedRequestURLs(request);
clearPrincipals(request);
//Remove Principals from Subject.
subject.getPrincipals().clear();
subject.getPrivateCredentials().clear();
subject.getPublicCredentials().clear();
try {
lc.logout();
} catch (LoginException ex) {
AuthException ae = new AuthException();
ae.initCause(ex);
throw ae;
}
}
/**
* Remove saved request URLs from session to avoid mixing up resources from
* previous operations (logins, logouts) with the current one.
*
* @param session Our current session
*/
protected void clearSavedRequestURLs(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null) {
session.removeAttribute(KEY_EVASION_SAVED_REQUEST_URL);
}
}
protected void clearPrincipals(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null) {
session.removeAttribute(SAVED_SUBJECT);
}
}
/**
*
*/
protected boolean isMandatory(MessageInfo messageInfo) {
return Boolean.valueOf((String) messageInfo.getMap().get(
"javax.security.auth.message.MessagePolicy.isMandatory"));
}
private LoginContext getLc() throws LoginException {
if (lc == null) {
cbh = new MyCBH();
lc = new LoginContext((lcName != null) ? lcName : getClass().getName(), null, cbh, config);
}
return lc;
}
/**
* Saves the original request URL into our session.
*
* @param request The request to be saved
* @param session The session to contain the saved information
* @throws IOException
*/
private void saveLoginBackToURL(HttpServletRequest request, HttpSession session) {
if (session != null) {
StringBuilder sb = new StringBuilder(request.getRequestURI());
if (request.getQueryString() != null) {
sb.append('?');
sb.append(request.getQueryString());
}
session.setAttribute(KEY_EVASION_SAVED_REQUEST_URL, sb.toString());
LOGGER.log(Level.FINE, "Sauvegarde de la requ\u00eate url={0}", sb.toString());
}
}
/**
* Return the request URI (with the corresponding query string, if any) from
* the saved request so that we can redirect to it.
*
* @param session Our current session
*/
private String getSavedRequestURL(HttpSession session) {
return (String) session.getAttribute(KEY_EVASION_SAVED_REQUEST_URL);
}
/**
*
*/
@Override
public AuthStatus secureResponse(MessageInfo messageInfo, Subject serviceSubject) throws AuthException {
return AuthStatus.SUCCESS;
}
}