com.evasion.sam.ServletAuthModule 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
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.evasion.sam;
import com.evasion.sam.jaas.EvasionGroup;
import com.evasion.sam.jaas.EvasionPrincipal;
import java.io.IOException;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
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.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.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.http.HttpSession;
/**
*
* @author sebastien
*/
public abstract class ServletAuthModule implements ServerAuthModule {
public static final String AUTH_TYPE_INFO_KEY = "javax.servlet.http.authType";
public static final String IS_MANDATORY_INFO_KEY = "javax.security.auth.message.MessagePolicy.isMandatory";
protected static final String POLICY_CONTEXT_OPTIONS_KEY = "javax.security.jacc.PolicyContext";
protected static final String SAVED_PRINCIPAL_ATTRIBUTE = "javax.security.auth.message.SavedPrincipals";
protected static final String SAVED_TOKEN_ATTRIBUTE = "com.evasion.SavedToken";
protected static final String REGISTER_WITH_AUTHENTICATOR = "com.sun.web.RealmAdapter.register";
protected static final Class[] SUPPORTED_MESSAGE_TYPES = new Class[]{
javax.servlet.http.HttpServletRequest.class,
javax.servlet.http.HttpServletResponse.class
};
protected static final Logger LOGGER = Logger.getLogger(ServletAuthModule.class.getName());
protected MessagePolicy requestPolicy;
protected MessagePolicy responsePolicy;
protected CallbackHandler handler;
protected Map options;
protected String policyContextID;
private String[] assignedGroups;
protected boolean isMandatory;
protected static final String KEY_EVASION_SAVED_REQUEST_URL = "javax.security.evasion.SavedRequestURL";
@Override
public void initialize(MessagePolicy requestPolicy,
MessagePolicy responsePolicy,
CallbackHandler handler,
Map options) throws AuthException {
this.requestPolicy = requestPolicy;
this.responsePolicy = responsePolicy;
this.isMandatory = requestPolicy.isMandatory();
this.handler = handler;
this.options = options;
if (options == null) {
this.options = new HashMap();
} else {
this.options = options;
}
if (this.options.containsKey(POLICY_CONTEXT_OPTIONS_KEY)) {
policyContextID = (String) this.options.get(POLICY_CONTEXT_OPTIONS_KEY);
} else {
policyContextID = null;
}
}
@Override
public Class[] getSupportedMessageTypes() {
return SUPPORTED_MESSAGE_TYPES.clone();
}
@Override
public AuthStatus secureResponse(MessageInfo messageInfo,
Subject serviceSubject) throws AuthException {
boolean wrapped = false;
HttpServletRequest r = (HttpServletRequest) messageInfo.getRequestMessage();
while (r instanceof HttpServletRequestWrapper) {
r = (HttpServletRequest) ((HttpServletRequestWrapper) r).getRequest();
wrapped = true;
}
if (wrapped) {
messageInfo.setRequestMessage(r);
}
wrapped = false;
HttpServletResponse s = (HttpServletResponse) messageInfo.getResponseMessage();
while (s instanceof HttpServletResponseWrapper) {
s = (HttpServletResponse) ((HttpServletResponseWrapper) s).getResponse();
wrapped = true;
}
if (wrapped) {
messageInfo.setResponseMessage(s);
}
return AuthStatus.SEND_SUCCESS;
}
@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();
}
protected AuthStatus sendFailureMessage(HttpServletResponse response,
int status, String message) {
try {
response.setStatus(status);
response.sendError(status, message);
} catch (IOException ex) {
// status code has been set, and proper AuthStatus will be returned
LOGGER.log(Level.WARNING, "jmac.servlet_failed_sending_failure", ex);
} finally {
return AuthStatus.SEND_FAILURE;
}
}
protected AuthStatus respondWithRedirect(HttpServletResponse response,
String url) throws AuthException {
try {
// @TODO confirmer l'utilisation du header et du status
response.addHeader("Pragma", "No-Cache");
response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
response.sendRedirect(response.encodeRedirectURL(url));
} catch (IOException ioe) {
LOGGER.log(Level.WARNING, "jmac.servlet_redirect_failed", ioe);
AuthException ae = new AuthException();
ae.initCause(ioe);
throw ae;
}
return AuthStatus.SEND_CONTINUE;
}
protected boolean addGroups(String[] groupNames, Subject clientSubject) {
if (groupNames != null && groupNames.length > 0) {
GroupPrincipalCallback gPCB =
new GroupPrincipalCallback(clientSubject, groupNames);
try {
handler.handle(new Callback[]{gPCB});
return true;
} catch (Exception e) {
// should not happen
LOGGER.log(Level.WARNING, "jmac.failed_to_assign_groups", e);
}
}
return false;
}
protected boolean setCallerPrincipal(EvasionPrincipal userPrincipal, Subject clientSubject) {
boolean rvalue = true;
CallerPrincipalCallback callerPrincipalCallback = new CallerPrincipalCallback(clientSubject, userPrincipal);
try {
handler.handle(new Callback[]{callerPrincipalCallback});
LOGGER.log(Level.FINE, "jmac.caller_principal:" + callerPrincipalCallback.getName() + " "
+ callerPrincipalCallback.getPrincipal());
} catch (Exception e) {
// should not happen
LOGGER.log(Level.WARNING, "jmac.failed_to_set_caller", e);
rvalue = false;
}
return rvalue;
}
protected Principal setCallerPrincipal(Subject clientSubject) throws Exception{
boolean assignGroups = true;
List groups = new ArrayList();
Principal userPrincipal = null;
for (Principal p : clientSubject.getPrincipals()) {
String tmp = p.getName();
LOGGER.fine("Principal utilisé: " + tmp);
if (p instanceof EvasionGroup && "Roles".equals(tmp)) {
EvasionGroup evasionGroup = (EvasionGroup) p;
for (Principal grp : Collections.list(evasionGroup.members())) {
groups.add(grp.getName());
LOGGER.fine("Groupe associe: " + 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;
}
handler.handle((assignGroups ? new Callback[]{
callerPrincipalCallback,
new GroupPrincipalCallback(callerPrincipalCallback.getSubject(),
assignedGroups)} : new Callback[]{callerPrincipalCallback}));
LOGGER.log(Level.FINE, "jmac.caller_principal:" + callerPrincipalCallback.getName() + " "
+ callerPrincipalCallback.getPrincipal());
return userPrincipal;
}
protected void debugToken(String message, byte[] bytes) {
if (LOGGER.isLoggable(Level.FINE)) {
StringBuffer sb = new StringBuffer();
sb.append("\n");
sb.append("bytes: ");
boolean first = true;
for (byte b : bytes) {
int i = b;
if (first) {
sb.append(i);
first = false;
} else {
sb.append(", ").append(i);
}
}
LOGGER.log(Level.FINE, message, sb);
}
}
protected void debugRequest(HttpServletRequest request) {
if (LOGGER.isLoggable(Level.FINER) || LOGGER.isLoggable(Level.FINEST)) {
StringBuffer sb = new StringBuffer();
sb.append("\n");
sb.append("Request: " + request.getRequestURL() + "\n");
sb.append("UserPrincipal: " + request.getUserPrincipal() + "\n");
sb.append("AuthType: " + request.getAuthType() + "\n");
sb.append("Headers:" + "\n");
Enumeration names = request.getHeaderNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
sb.append("\t" + name + "\t" + request.getHeader(name) + "\n");
}
LOGGER.log(Level.FINER, "jmac.servlet_request " + sb.toString());
}
}
protected void debugSession(HttpSession session) {
if (session == null) {
LOGGER.log(Level.FINER, "Session is null");
} else {
if (LOGGER.isLoggable(Level.FINER) || LOGGER.isLoggable(Level.FINEST)) {
StringBuffer sb = new StringBuffer();
sb.append("\n");
sb.append("Session: \n");
Enumeration attr = session.getAttributeNames();
String attributName;
while (attr.hasMoreElements()) {
attributName = attr.nextElement();
sb.append("\t" + attributName + "\t" + session.getAttribute(attributName) + "\n");
}
LOGGER.log(Level.FINER, "Session elements " + 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
*/
protected String getSavedRequestURL(HttpSession session) {
return (String) session.getAttribute(KEY_EVASION_SAVED_REQUEST_URL);
}
/**
* 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
*/
protected 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ête url=" + sb.toString());
}
}
/**
* 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 savePrincipals(HttpServletRequest request, Subject s) {
HttpSession session = request.getSession(true);
session.setAttribute(SAVED_PRINCIPAL_ATTRIBUTE, s.getPrincipals());
}
protected void clearPrincipals(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null) {
session.removeAttribute(SAVED_PRINCIPAL_ATTRIBUTE);
}
}
/**
*
* @param request
* @return null si non identifié; enmpty si echec d'authen, sinon le token
*/
protected String getToken(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null) {
Object result = session.getAttribute(SAVED_TOKEN_ATTRIBUTE);
if (result != null) {
return (String) result;
}
}
return null;
}
protected static void saveTokenId(HttpServletRequest request, String tokenId) {
HttpSession session = request.getSession(true);
session.setAttribute(SAVED_TOKEN_ATTRIBUTE, tokenId);
}
protected static boolean restorePrincipals(HttpServletRequest request, Subject s) {
HttpSession session = request.getSession(false);
if (session != null) {
Set principals =
(Set) session.getAttribute(SAVED_PRINCIPAL_ATTRIBUTE);
if (principals != null) {
//session.removeAttribute(SAVED_PRINCIPAL_ATTRIBUTE);
s.getPrincipals().addAll(principals);
return true;
}
}
return false;
}
protected String getServerName(MessageInfo messageInfo) {
return ((HttpServletRequest) messageInfo.getRequestMessage()).getServerName();
}
protected String getContextPath(MessageInfo messageInfo) {
return ((HttpServletRequest) messageInfo.getRequestMessage()).getContextPath();
}
}