package auth.impl.callbacks;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.core.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import play.data.DynamicForm;
import play.data.Form;
import play.mvc.Http;
import play.mvc.Http.Context;
import auth.utils.SAMLUtils;
public class AuthnResponseCallback extends HeadlessCallback {
private static Logger logger = LoggerFactory.getLogger(AuthnResponseCallback.class);
private static final String SAML_RESPONSE = "SAMLResponse";
private static final String RELAY_STATE = "RelayState";
private String errMsg = null;
private Map<String,String> attrs = new HashMap<String, String>(); // output attributes
private SAMLUtils samlUtils;
private boolean processed = false;
private String relayState = null;
/**
* @param samlUtils
* @param attrs2
*/
public AuthnResponseCallback(SAMLUtils samlUtils) {
this.samlUtils = samlUtils;
}
public String getAttribute(String attrNm) {
return attrs.get(attrNm);
}
public boolean isResponseProcessed() {
return processed;
}
public String getRelayState() {
return relayState;
}
/* (non-Javadoc)
* @see auth.impl.callbacks.IHeadlessCallback#process()
*/
@Override
public void process() {
Context.current.set(getOriginalContext());
Http.Request req = getOriginalRequest();
DynamicForm frm = Form.form().bindFromRequest();
String samlResponse = null;
if (req.queryString().get(SAML_RESPONSE) != null) {
samlResponse = req.queryString().get(SAML_RESPONSE)[0];
} else {
samlResponse = frm.get(SAML_RESPONSE);
}
//String relayState = null;
if (req.queryString().get(RELAY_STATE) != null) {
relayState = req.queryString().get(RELAY_STATE)[0];
} else {
relayState = frm.get(RELAY_STATE);
}
if (samlResponse == null || relayState == null) return;
Response resp = samlUtils.decodeSAMLResponse(samlResponse);
List<Assertion> assertions = samlUtils.decodeAssertions(resp);
Subject subject = null;
if (assertions.size() != 1) {
errMsg = "FAILURE! Expected 1 assertion back; received: " + assertions.size();
logger.warn(errMsg);
return;
}
// I expect only one assertion here actually
Assertion a = assertions.get(0);
subject = a.getSubject();
if (subject == null) {
errMsg = "FAILURE! Subject is not present in assertion!";
logger.warn(errMsg);
return;
}
if (!samlUtils.processConditions(a.getConditions())) {
errMsg = "FAILURE! User does not match IdP conditions!";
logger.warn(errMsg);
return;
}
String username = subject.getNameID().getValue();
logger.info("User '" + username + "' successfully authenticated by IdP!");
attrs.putAll(samlUtils.getAttributeValue(resp, username));
if (attrs.isEmpty()) {
errMsg = "FAILURE! Could not find value for attribute username!";
logger.warn(errMsg);
return;
}
logger.debug("Attributes: " + attrs);
processed = true;
}
}