use of com.sun.identity.saml2.protocol.Response in project OpenAM by OpenRock.
the class IDPSSOUtil method signResponse.
/**
* Signs SAMLv2 Response.
*
* @param realm the realm name.
* @param idpEntityID the identity provider entity identifier
* @param response the SAMLv2 <code>Response</code>
* @throws <code>SAML2Exception</code> if there is an
* error signing the response.
*/
private static void signResponse(String realm, String idpEntityID, Response response) throws SAML2Exception {
String classMethod = "IDPSSOUtil:signResponse";
KeyProvider kp = KeyUtil.getKeyProviderInstance();
if (kp == null) {
SAML2Utils.debug.error(classMethod + "Unable to get a key provider instance.");
throw new SAML2Exception(SAML2Utils.bundle.getString("nullKeyProvider"));
}
String idpSignCertAlias = SAML2Utils.getSigningCertAlias(realm, idpEntityID, SAML2Constants.IDP_ROLE);
if (idpSignCertAlias == null) {
SAML2Utils.debug.error(classMethod + "Unable to get the hosted IDP signing certificate alias.");
throw new SAML2Exception(SAML2Utils.bundle.getString("missingSigningCertAlias"));
}
String encryptedKeyPass = SAML2Utils.getSigningCertEncryptedKeyPass(realm, idpEntityID, SAML2Constants.IDP_ROLE);
PrivateKey key;
if (encryptedKeyPass == null || encryptedKeyPass.isEmpty()) {
key = kp.getPrivateKey(idpSignCertAlias);
} else {
key = kp.getPrivateKey(idpSignCertAlias, encryptedKeyPass);
}
response.sign(key, kp.getX509Certificate(idpSignCertAlias));
}
use of com.sun.identity.saml2.protocol.Response in project OpenAM by OpenRock.
the class IDPSSOUtil method sendResponseECP.
/**
* This method sends SAML Response back to ECP.
*
* @param request The servlet request.
* @param response The servlet response.
* @param out The print writer for writing out presentation.
* @param idpEntityID the entity id of the identity provider
* @param realm the realm name of the identity provider
* @param acsURL the assertion consumer service <code>URL</code>
* @param res the <code>SAML Response</code> object
* @throws SAML2Exception if the operation is not successful
*/
public static void sendResponseECP(HttpServletRequest request, HttpServletResponse response, PrintWriter out, String idpEntityID, String realm, String acsURL, Response res) throws SAML2Exception {
ECPFactory ecpFactory = ECPFactory.getInstance();
ECPResponse ecpResponse = ecpFactory.createECPResponse();
ecpResponse.setMustUnderstand(Boolean.TRUE);
ecpResponse.setActor(SAML2Constants.SOAP_ACTOR_NEXT);
ecpResponse.setAssertionConsumerServiceURL(acsURL);
String header = ecpResponse.toXMLString(true, true);
String body = res.toXMLString(true, true);
try {
SOAPMessage reply = SOAPCommunicator.getInstance().createSOAPMessage(header, body, false);
String[] logdata = { idpEntityID, realm, acsURL, "" };
if (LogUtil.isAccessLoggable(Level.FINE)) {
logdata[3] = SOAPCommunicator.getInstance().soapMessageToString(reply);
}
LogUtil.access(Level.INFO, LogUtil.SEND_ECP_RESPONSE, logdata, null);
// are generated as part of the save.
if (reply.saveRequired()) {
reply.saveChanges();
}
response.setStatus(HttpServletResponse.SC_OK);
SAML2Utils.putHeaders(reply.getMimeHeaders(), response);
// Write out the message on the response stream
ByteArrayOutputStream stream = new ByteArrayOutputStream();
reply.writeTo(stream);
out.println(stream.toString());
out.flush();
} catch (Exception ex) {
SAML2Utils.debug.error("IDPSSOUtil.sendResponseECP", ex);
String[] data = { idpEntityID, realm, acsURL };
LogUtil.error(Level.INFO, LogUtil.SEND_ECP_RESPONSE_FAILED, data, null);
SAMLUtils.sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "failedToSendECPResponse", ex.getMessage());
return;
}
}
use of com.sun.identity.saml2.protocol.Response in project OpenAM by OpenRock.
the class IDPSSOUtil method getResponse.
/**
* Returns a <code>SAML Response</code> object.
*
* @param request The HTTP request.
* @param session The user's session object.
* @param authnReq The <code>AuthnRequest</code> object.
* @param recipientEntityID The entity ID of the response recipient.
* @param idpEntityID The entity ID of the identity provider.
* @param realm The realm name.
* @param nameIDFormat The <code>NameIDFormat</code>.
* @param acsURL The <code>ACS</code> service <code>url</code>.
* @param affiliationID AffiliationID for IDP initiated SSO.
* @param matchingAuthnContext the <code>AuthnContext</code> used to find authentication type and scheme.
* @return the <code>SAML Response</code> object.
* @throws SAML2Exception if the operation is not successful.
*/
public static Response getResponse(HttpServletRequest request, Object session, AuthnRequest authnReq, String recipientEntityID, String idpEntityID, String idpMetaAlias, String realm, String nameIDFormat, String acsURL, String affiliationID, AuthnContext matchingAuthnContext) throws SAML2Exception {
String classMethod = "IDPSSOUtil.getResponse: ";
Response res = ProtocolFactory.getInstance().createResponse();
Status status = ProtocolFactory.getInstance().createStatus();
if (status == null) {
return null;
}
StatusCode statusCode = ProtocolFactory.getInstance().createStatusCode();
if (statusCode == null) {
return null;
}
try {
List assertionList = new ArrayList();
Assertion assertion = getAssertion(request, session, authnReq, recipientEntityID, idpEntityID, idpMetaAlias, realm, nameIDFormat, acsURL, affiliationID, matchingAuthnContext);
if (assertion == null) {
SAML2Utils.debug.error(classMethod + "Unable to get Assertion.");
return null;
}
assertionList.add(assertion);
res.setAssertion(assertionList);
statusCode.setValue(SAML2Constants.SUCCESS);
} catch (SAML2InvalidNameIDPolicyException se) {
statusCode.setValue(SAML2Constants.REQUESTER);
StatusCode subStatusCode = ProtocolFactory.getInstance().createStatusCode();
subStatusCode.setValue(SAML2Constants.INVALID_NAME_ID_POLICY);
statusCode.setStatusCode(subStatusCode);
status.setStatusMessage(se.getMessage());
}
status.setStatusCode(statusCode);
res.setStatus(status);
if (authnReq != null) {
// sp initiated case, need to set InResponseTo attribute
res.setInResponseTo(authnReq.getID());
}
res.setVersion(SAML2Constants.VERSION_2_0);
res.setIssueInstant(new Date());
res.setID(SAML2Utils.generateID());
// set the idp entity id as the response issuer
Issuer issuer = AssertionFactory.getInstance().createIssuer();
issuer.setValue(idpEntityID);
res.setIssuer(issuer);
res.setDestination(XMLUtils.escapeSpecialCharacters(acsURL));
return res;
}
use of com.sun.identity.saml2.protocol.Response in project OpenAM by OpenRock.
the class IDPSSOUtil method getSubject.
/**
* Returns a <code>SAML Subject</code> object
*
* @param session the user's session
* @param authnReq the <code>AuthnRequest</code> object
* @param acsURL the <code>ACS</code> service <code>url</code>
* @param nameIDFormat the <code>NameIDFormat</code>
* @param realm The realm name
* @param idpEntityID the entity id of the identity provider
* @param recipientEntityID the entity id of the response recipient
* @param effectiveTime the effective time of the assertion
* @param affiliationID affiliationID for IDP initiated SSO
* @return the <code>SAML Subject</code> object
* @throws SAML2Exception if the operation is not successful
*/
private static Subject getSubject(Object session, AuthnRequest authnReq, String acsURL, String nameIDFormat, String realm, String idpEntityID, String recipientEntityID, int effectiveTime, String affiliationID) throws SAML2Exception {
String classMethod = "IDPSSOUtil.getSubject: ";
Subject subject = AssertionFactory.getInstance().createSubject();
boolean ignoreProfile = false;
String userName = null;
try {
userName = sessionProvider.getPrincipalName(session);
ignoreProfile = SAML2Utils.isIgnoreProfileSet(session);
} catch (SessionException se) {
SAML2Utils.debug.error(classMethod + "There was a problem with the session.", se);
throw new SAML2Exception(SAML2Utils.bundle.getString("invalidSSOToken"));
}
// allow create is the default
boolean allowCreate = true;
String remoteEntityID = null;
String spNameQualifier = null;
boolean isAffiliation = false;
if (authnReq != null) {
remoteEntityID = authnReq.getIssuer().getValue();
NameIDPolicy nameIDPolicy = authnReq.getNameIDPolicy();
if (nameIDPolicy != null) {
// this will take care of affiliation
allowCreate = nameIDPolicy.isAllowCreate();
spNameQualifier = nameIDPolicy.getSPNameQualifier();
if (spNameQualifier != null && !spNameQualifier.isEmpty()) {
AffiliationDescriptorType affiDesc = metaManager.getAffiliationDescriptor(realm, spNameQualifier);
if (affiDesc != null) {
if (affiDesc.getAffiliateMember().contains(remoteEntityID)) {
isAffiliation = true;
remoteEntityID = spNameQualifier;
} else {
throw new SAML2Exception(SAML2Utils.bundle.getString("spNotAffiliationMember"));
}
}
} else {
spNameQualifier = recipientEntityID;
}
}
} else {
// IDP initialted SSO
if (affiliationID != null) {
AffiliationDescriptorType affiDesc = metaManager.getAffiliationDescriptor(realm, affiliationID);
if (affiDesc == null) {
throw new SAML2Exception(SAML2Utils.bundle.getString("affiliationNotFound"));
}
if (affiDesc.getAffiliateMember().contains(recipientEntityID)) {
isAffiliation = true;
remoteEntityID = affiliationID;
spNameQualifier = affiliationID;
} else {
throw new SAML2Exception(SAML2Utils.bundle.getString("spNotAffiliationMember"));
}
} else {
remoteEntityID = recipientEntityID;
spNameQualifier = recipientEntityID;
}
}
SPSSODescriptorElement spsso = getSPSSODescriptor(realm, recipientEntityID, classMethod);
if (spsso == null) {
String[] data = { recipientEntityID };
LogUtil.error(Level.INFO, LogUtil.SP_METADATA_ERROR, data, null);
throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
}
IDPSSODescriptorElement idpsso = metaManager.getIDPSSODescriptor(realm, idpEntityID);
if (idpsso == null) {
String[] data = { idpEntityID };
LogUtil.error(Level.INFO, LogUtil.IDP_METADATA_ERROR, data, null);
throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
}
nameIDFormat = SAML2Utils.verifyNameIDFormat(nameIDFormat, spsso, idpsso);
boolean isTransient = SAML2Constants.NAMEID_TRANSIENT_FORMAT.equals(nameIDFormat);
boolean isPersistent = SAML2Constants.PERSISTENT.equals(nameIDFormat);
NameIDInfo nameIDInfo;
NameID nameID = null;
IDPAccountMapper idpAccountMapper = SAML2Utils.getIDPAccountMapper(realm, idpEntityID);
//Use-cases for NameID persistence:
//* persistent NameID -> The NameID MUST be stored
//* transient NameID -> The NameID MUST NOT be stored
//* ignored user profile mode -> The NameID CANNOT be stored
//* for any other cases -> The NameID MAY be stored based on customizable logic
boolean shouldPersistNameID = isPersistent || (!isTransient && !ignoreProfile && idpAccountMapper.shouldPersistNameIDFormat(realm, idpEntityID, remoteEntityID, nameIDFormat));
if (!isTransient) {
String userID;
try {
userID = sessionProvider.getPrincipalName(session);
} catch (SessionException se) {
SAML2Utils.debug.error(classMethod + "Unable to get principal name from the session.", se);
throw new SAML2Exception(SAML2Utils.bundle.getString("invalidSSOToken"));
}
if (isPersistent || shouldPersistNameID) {
nameIDInfo = AccountUtils.getAccountFederation(userID, idpEntityID, remoteEntityID);
if (nameIDInfo != null) {
nameID = nameIDInfo.getNameID();
if (!nameIDFormat.equals(nameID.getFormat())) {
AccountUtils.removeAccountFederation(nameIDInfo, userID);
DoManageNameID.removeIDPFedSession(remoteEntityID, nameID.getValue());
nameID = null;
}
}
}
}
if (nameID == null) {
if (!allowCreate && isPersistent) {
throw new SAML2InvalidNameIDPolicyException(SAML2Utils.bundle.getString("cannotCreateNameID"));
}
nameID = idpAccountMapper.getNameID(session, idpEntityID, spNameQualifier, realm, nameIDFormat);
SAML2Utils.debug.message(classMethod + " shouldPersistNameID = " + shouldPersistNameID);
if (shouldPersistNameID && allowCreate) {
// write federation info into the persistent datastore
if (SAML2Utils.isDualRole(idpEntityID, realm)) {
nameIDInfo = new NameIDInfo(idpEntityID, remoteEntityID, nameID, SAML2Constants.DUAL_ROLE, false);
} else {
nameIDInfo = new NameIDInfo(idpEntityID, remoteEntityID, nameID, SAML2Constants.IDP_ROLE, isAffiliation);
}
AccountUtils.setAccountFederation(nameIDInfo, userName);
}
}
subject.setNameID(nameID);
if (isTransient) {
IDPCache.userIDByTransientNameIDValue.put(nameID.getValue(), userName);
}
String inResponseTo = null;
if (authnReq != null) {
inResponseTo = authnReq.getID();
}
SubjectConfirmation sc = getSubjectConfirmation(inResponseTo, acsURL, effectiveTime);
if (sc == null) {
SAML2Utils.debug.error(classMethod + "Unable to get subject confirmation");
throw new SAML2Exception(SAML2Utils.bundle.getString("noSubjectConfirmation"));
}
List list = new ArrayList();
list.add(sc);
subject.setSubjectConfirmation(list);
return subject;
}
use of com.sun.identity.saml2.protocol.Response in project OpenAM by OpenRock.
the class IDPSSOUtil method sendResponse.
/**
* Sends a response to service provider
*
* @param response the <code>HttpServletResponse</code> object
* @param acsBinding the assertion consumer service binding
* @param spEntityID the entity id of the service provider
* @param idpEntityID the entity id of the identity provider
* @param idpMetaAlias the meta alias of the identity provider
* @param realm the realm name
* @param relayState the relay state
* @param acsURL the assertion consumer service <code>url</code>
* @param res the <code>SAML Response</code> object
* @throws SAML2Exception if the operation is not successful
*/
public static void sendResponse(HttpServletRequest request, HttpServletResponse response, PrintWriter out, String acsBinding, String spEntityID, String idpEntityID, String idpMetaAlias, String realm, String relayState, String acsURL, Response res, Object session) throws SAML2Exception {
String classMethod = "IDPSSOUtil.sendResponse: ";
String nameIDString = SAML2Utils.getNameIDStringFromResponse(res);
Map props = new HashMap();
props.put(LogUtil.NAME_ID, nameIDString);
// send the response back through HTTP POST or Artifact
if (acsBinding.equals(SAML2Constants.HTTP_POST)) {
// 4.1.4.5 POST-Specific Processing Rules (sstc-saml-profiles-errata-2.0-wd-06-diff.pdf)
//If response is not signed and POST binding is used, the assertion(s) MUST be signed.
// encryption is optional based on SP config settings.
boolean signAssertion = true;
// check if response needs to be signed.
boolean signResponse = SAML2Utils.wantPOSTResponseSigned(realm, spEntityID, SAML2Constants.SP_ROLE);
// so will base on wantAssertionsSigned flag
if (signResponse) {
signAssertion = wantAssertionsSigned(spEntityID, realm);
}
signAndEncryptResponseComponents(realm, spEntityID, idpEntityID, res, signAssertion);
if (signResponse) {
signResponse(realm, idpEntityID, res);
}
String resMsg = res.toXMLString(true, true);
if (SAML2Utils.debug.messageEnabled()) {
SAML2Utils.debug.message(classMethod + "SAML Response content :\n" + resMsg);
}
String encodedResMsg = SAML2Utils.encodeForPOST(resMsg);
String[] logdata1 = { spEntityID, idpMetaAlias, resMsg };
LogUtil.access(Level.INFO, LogUtil.POST_RESPONSE, logdata1, session, props);
try {
SAML2Utils.postToTarget(request, response, "SAMLResponse", encodedResMsg, "RelayState", relayState, acsURL);
} catch (SAML2Exception saml2E) {
String[] data = { acsURL };
LogUtil.error(Level.INFO, LogUtil.POST_TO_TARGET_FAILED, data, session, props);
throw saml2E;
}
} else if (acsBinding.equals(SAML2Constants.HTTP_ARTIFACT)) {
IDPSSOUtil.sendResponseArtifact(request, response, idpEntityID, spEntityID, realm, acsURL, relayState, res, session, props);
} else if (acsBinding.equals(SAML2Constants.PAOS)) {
// signing assertion is a must for ECP profile.
// encryption is optional based on SP config settings.
signAndEncryptResponseComponents(realm, spEntityID, idpEntityID, res, true);
IDPSSOUtil.sendResponseECP(request, response, out, idpEntityID, realm, acsURL, res);
} else {
SAML2Utils.debug.error(classMethod + "unsupported return binding.");
throw new SAML2Exception(SAML2Utils.bundle.getString("UnSupportedReturnBinding"));
}
}
Aggregations