use of org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException in project OpenAM by OpenRock.
the class SAML2 method handleReturnFromRedirect.
/**
* Once we're back from the ACS, we need to validate that we have not errored during the proxying process.
* Then we detect if we need to perform a local linking authentication chain, or if the user is already
* locally linked, we need to look up the already-linked username.
*/
private int handleReturnFromRedirect(final int state, final HttpServletRequest request, final String spName, final HttpServletResponse response) throws AuthLoginException {
//first make sure to delete the cookie
removeCookiesForRedirects(request, response);
if (Boolean.parseBoolean(request.getParameter(SAML2Proxy.ERROR_PARAM_KEY))) {
return handleRedirectError(request);
}
final String key;
if (request.getParameter("jsonContent") != null) {
key = JsonValueBuilder.toJsonValue(request.getParameter("jsonContent")).get("responsekey").asString();
} else {
key = request.getParameter(SAML2Proxy.RESPONSE_KEY);
}
final String username;
SAML2ResponseData data = null;
if (!StringUtils.isBlank(key)) {
data = (SAML2ResponseData) SAML2Store.getTokenFromStore(key);
}
if (data == null && SAML2FailoverUtils.isSAML2FailoverEnabled() && !StringUtils.isBlank(key)) {
try {
data = (SAML2ResponseData) SAML2FailoverUtils.retrieveSAML2Token(key);
} catch (SAML2TokenRepositoryException e) {
return processError(bundle.getString("samlFailoverError"), "SAML2.handleReturnFromRedirect : Error reading from failover map.", e);
}
}
if (data == null) {
return processError(bundle.getString("localLinkError"), "SAML2 :: handleReturnFromRedirect() : " + "Unable to perform local linking - response data key not found");
}
storageKey = key;
assertionSubject = data.getSubject();
authnAssertion = data.getAssertion();
sessionIndex = data.getSessionIndex();
respInfo = data.getResponseInfo();
try {
//you're already linked or we auto looked up user
username = SPACSUtils.getPrincipalWithoutLogin(assertionSubject, authnAssertion, realm, spName, metaManager, entityName, storageKey);
if (SAML2PluginsUtils.isDynamicProfile(realm)) {
String spEntityId = SPSSOFederate.getSPEntityId(metaAlias);
if (shouldPersistNameID(spEntityId)) {
NameIDInfo info = new NameIDInfo(spEntityId, entityName, getNameId(), SAML2Constants.SP_ROLE, false);
setUserAttributes(AccountUtils.convertToAttributes(info, null));
}
}
if (username != null) {
principal = new SAML2Principal(username);
return success(authnAssertion, getNameId(), username);
}
} catch (SAML2Exception e) {
return processError(e, null, "SAML2.handleReturnFromRedirect : Unable to perform user lookup.");
}
if (StringUtils.isBlank(localChain)) {
return processError(bundle.getString("localLinkError"), "SAML2 :: handleReturnFromRedirect() : " + "Unable to perform local linking - local auth chain not found.");
}
//generate a sub-login context, owned by this module, and start login sequence to it
authenticationContext = new AuthContext(realm);
authenticationContext.login(AuthContext.IndexType.SERVICE, localChain, null, null, null, null);
return injectCallbacks(null, state);
}
use of org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException in project OpenAM by OpenRock.
the class SAML2PostAuthenticationPlugin method onLoginSuccess.
/**
* If enabled, performs the first-stage of SLO - by recording the currently logged in user.
* The information relating to a remote user is stored alongside their local information, and upon
* active-logout is used to trigger a call to the IdP requesting their logout.
*
* @param requestParamsMap map containing <code>HttpServletRequest</code>
* parameters
* @param request <code>HttpServletRequest</code> object.
* @param response <code>HttpServletResponse</code> object.
* @param ssoToken authenticated user's single sign token.
*/
@Override
public void onLoginSuccess(Map requestParamsMap, HttpServletRequest request, HttpServletResponse response, SSOToken ssoToken) {
try {
final String metaAlias = ssoToken.getProperty(SAML2Constants.METAALIAS);
final String sessionIndex = ssoToken.getProperty(SAML2Constants.SESSION_INDEX);
final String spEntityId = ssoToken.getProperty(SAML2Constants.SPENTITYID);
final String idpEntityId = ssoToken.getProperty(SAML2Constants.IDPENTITYID);
final String nameIdXML = ssoToken.getProperty(SAML2Constants.NAMEID);
final NameID nameId = new NameIDImplWithoutSPNameQualifier(nameIdXML);
final boolean isTransient = Boolean.parseBoolean(ssoToken.getProperty(Constants.IS_TRANSIENT));
final String requestId = ssoToken.getProperty(Constants.REQUEST_ID);
final SessionProvider sessionProvider = SessionManager.getProvider();
final NameIDInfo info = new NameIDInfo(spEntityId, idpEntityId, nameId, SAML2Constants.SP_ROLE, false);
final String ssOutEnabled = ssoToken.getProperty(SAML2Constants.SINGLE_LOGOUT);
final String cacheKey = ssoToken.getProperty(Constants.CACHE_KEY);
final String realm = DNMapper.orgNameToRealmName(ssoToken.getProperty(com.sun.identity.shared.Constants.ORGANIZATION));
SAML2ResponseData data = (SAML2ResponseData) SAML2Store.getTokenFromStore(cacheKey);
if (data == null && SAML2FailoverUtils.isSAML2FailoverEnabled()) {
data = (SAML2ResponseData) SAML2FailoverUtils.retrieveSAML2Token(cacheKey);
}
if (data == null) {
throw new SAML2Exception("Unable to retrieve response map from data cache.");
}
if (Boolean.parseBoolean(ssOutEnabled)) {
setupSingleLogOut(ssoToken, metaAlias, sessionIndex, spEntityId, idpEntityId, nameId);
}
configureIdpInitSLO(sessionProvider, ssoToken, sessionIndex, metaAlias, info, isTransient, requestId);
configurePostSSO(spEntityId, realm, request, response, ssoToken, sessionProvider, data.getResponseInfo(), cacheKey);
clearSession(ssoToken);
} catch (SAML2Exception | SessionException | SSOException | SAML2TokenRepositoryException e) {
//debug warning and fall through
DEBUG.warning("Error saving SAML assertion information in memory. SLO not configured for this session.", e);
}
}
use of org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException in project OpenAM by OpenRock.
the class SAML2CTSPersistentStore method saveSAML2Token.
/**
* {@inheritDoc}
*/
@Override
public void saveSAML2Token(String primaryKey, String secondaryKey, Object samlObj, long expirationTime) throws SAML2TokenRepositoryException {
// Save the SAML2 Token.
try {
// Perform the Save of the Token to the Token Repository.
SAMLToken samlToken = new SAMLToken(primaryKey, secondaryKey, expirationTime, samlObj);
Token token = tokenAdapter.toToken(samlToken);
persistentStore.createAsync(token);
} catch (CoreTokenException e) {
debug.error("SAML2CTSPersistentStore.saveSAML2Token(): failed to save SAML2 " + "token using primary key:" + primaryKey, e);
throw new SAML2TokenRepositoryException(e.getMessage(), e);
}
}
use of org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException in project OpenAM by OpenRock.
the class AssertionIDRequestUtil method processAssertionIDRequest.
/**
* This method processes the <code>AssertionIDRequest</code> coming
* from a requester.
*
* @param assertionIDRequest the <code>AssertionIDRequest</code> object
* @param request the <code>HttpServletRequest</code> object
* @param response the <code>HttpServletResponse</code> object
* @param samlAuthorityEntityID entity ID of SAML authority
* @param role the role of SAML authority
* @param realm the realm of SAML authority
* @return the <code>Response</code> object
* @exception SAML2Exception if the operation is not successful
*/
public static Response processAssertionIDRequest(AssertionIDRequest assertionIDRequest, HttpServletRequest request, HttpServletResponse response, String samlAuthorityEntityID, String role, String realm) throws SAML2Exception {
try {
verifyAssertionIDRequest(assertionIDRequest, samlAuthorityEntityID, role, realm);
} catch (SAML2Exception se) {
SAML2Utils.debug.error("AssertionIDRequestUtil." + "processAssertionIDRequest:", se);
return SAML2Utils.getErrorResponse(assertionIDRequest, SAML2Constants.REQUESTER, null, se.getMessage(), samlAuthorityEntityID);
}
Issuer issuer = assertionIDRequest.getIssuer();
String spEntityID = issuer.getValue();
RoleDescriptorType roled = null;
try {
if (SAML2Constants.IDP_ROLE.equals(role)) {
roled = metaManager.getIDPSSODescriptor(realm, samlAuthorityEntityID);
} else if (SAML2Constants.AUTHN_AUTH_ROLE.equals(role)) {
roled = metaManager.getAuthnAuthorityDescriptor(realm, samlAuthorityEntityID);
} else if (SAML2Constants.ATTR_AUTH_ROLE.equals(role)) {
roled = metaManager.getAttributeAuthorityDescriptor(realm, samlAuthorityEntityID);
}
} catch (SAML2MetaException sme) {
SAML2Utils.debug.error("AssertionIDRequestUtil." + "processAssertionIDRequest:", sme);
return SAML2Utils.getErrorResponse(assertionIDRequest, SAML2Constants.RESPONDER, null, sme.getMessage(), samlAuthorityEntityID);
}
if (roled == null) {
return SAML2Utils.getErrorResponse(assertionIDRequest, SAML2Constants.REQUESTER, null, SAML2Utils.bundle.getString("samlAuthorityNotFound"), samlAuthorityEntityID);
}
List returnAssertions = null;
List assertionIDRefs = assertionIDRequest.getAssertionIDRefs();
for (Iterator iter = assertionIDRefs.iterator(); iter.hasNext(); ) {
AssertionIDRef assertionIDRef = (AssertionIDRef) iter.next();
String assertionID = assertionIDRef.getValue();
Assertion assertion = (Assertion) IDPCache.assertionByIDCache.get(assertionID);
if ((assertion == null) && (SAML2FailoverUtils.isSAML2FailoverEnabled())) {
if (SAML2Utils.debug.messageEnabled()) {
SAML2Utils.debug.message("AssertionIDRequestUtil.processAssertionIDRequest: " + "reading assertion from the SAML2 Token Repository using assertionID:" + assertionID);
}
String assertionStr = null;
try {
assertionStr = (String) SAML2FailoverUtils.retrieveSAML2Token(assertionID);
} catch (SAML2TokenRepositoryException se) {
SAML2Utils.debug.error("AssertionIDRequestUtil.processAssertionIDRequest: " + "There was a problem reading assertion from the SAML2 Token Repository using assertionID:" + assertionID, se);
}
if (assertionStr != null) {
assertion = AssertionFactory.getInstance().createAssertion(assertionStr);
}
}
if ((assertion != null) && (assertion.isTimeValid())) {
if (returnAssertions == null) {
returnAssertions = new ArrayList();
}
returnAssertions.add(assertion);
}
}
ProtocolFactory protocolFactory = ProtocolFactory.getInstance();
Response samlResp = protocolFactory.createResponse();
samlResp.setAssertion(returnAssertions);
samlResp.setID(SAML2Utils.generateID());
samlResp.setInResponseTo(assertionIDRequest.getID());
samlResp.setVersion(SAML2Constants.VERSION_2_0);
samlResp.setIssueInstant(new Date());
Status status = protocolFactory.createStatus();
StatusCode statusCode = protocolFactory.createStatusCode();
statusCode.setValue(SAML2Constants.SUCCESS);
status.setStatusCode(statusCode);
samlResp.setStatus(status);
Issuer respIssuer = AssertionFactory.getInstance().createIssuer();
respIssuer.setValue(samlAuthorityEntityID);
samlResp.setIssuer(respIssuer);
signResponse(samlResp, samlAuthorityEntityID, role, realm, false);
return samlResp;
}
use of org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException in project OpenAM by OpenRock.
the class IDPSingleLogout method sendLastResponse.
private static boolean sendLastResponse(IDPSession idpSession, LogoutResponse logoutRes, HttpServletRequest request, HttpServletResponse response, String idpSessionIndex, Object session, String realm, String idpEntityID, String relayState) throws SAML2Exception, SessionException, SAML2MetaException {
String binding;
//resetting the binding to the original value so the response is sent back with the correct binding
binding = idpSession.getOriginatingLogoutRequestBinding();
String originatingRequestID = idpSession.getOriginatingLogoutRequestID();
String originatingLogoutSPEntityID = idpSession.getOriginatingLogoutSPEntityID();
if (originatingRequestID == null) {
// this is IDP initiated SLO
if (idpSession.getLogoutAll()) {
String userID = sessionProvider.getPrincipalName(idpSession.getSession());
destroyAllTokenForUser(userID, request, response);
} else {
IDPCache.idpSessionsByIndices.remove(idpSessionIndex);
if (agent != null && agent.isRunning() && saml2Svc != null) {
saml2Svc.setIdpSessionCount((long) IDPCache.idpSessionsByIndices.size());
}
try {
if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
SAML2FailoverUtils.deleteSAML2Token(idpSessionIndex);
}
} catch (SAML2TokenRepositoryException se) {
debug.error("IDPSingleLogout.sendLastResponse: Error while deleting token from " + "SAML2 Token Repository for idpSessionIndex:" + idpSessionIndex, se);
}
IDPCache.authnContextCache.remove(idpSessionIndex);
if (!MultiProtocolUtils.isMultipleProtocolSession(idpSession.getSession(), SingleLogoutManager.SAML2)) {
sessionProvider.invalidateSession(idpSession.getSession(), request, response);
} else {
MultiProtocolUtils.removeFederationProtocol(idpSession.getSession(), SingleLogoutManager.SAML2);
// call Multi-Federation protocol SingleLogoutManager
SingleLogoutManager sloManager = SingleLogoutManager.getInstance();
Set<Object> set = new HashSet<Object>(1);
set.add(session);
SessionProvider provider = SessionManager.getProvider();
String uid = provider.getPrincipalName(session);
debug.message("IDPSingleLogout.sendLastResponse: MP/Http");
int retStatus = SingleLogoutManager.LOGOUT_SUCCEEDED_STATUS;
try {
retStatus = sloManager.doIDPSingleLogout(set, uid, request, response, false, true, SingleLogoutManager.SAML2, realm, idpEntityID, originatingLogoutSPEntityID, relayState, null, null, getLogoutStatus(logoutRes));
} catch (SAML2Exception ex) {
throw ex;
} catch (Exception ex) {
debug.error("IDPSIngleLogout.sendLastResponse: MP/IDP initiated HTTP", ex);
throw new SAML2Exception(ex.getMessage());
}
if (retStatus == SingleLogoutManager.LOGOUT_REDIRECTED_STATUS) {
return true;
}
}
}
debug.message("IDP initiated SLO Success");
return false;
}
List<SingleLogoutServiceElement> slosList = getSPSLOServiceEndpoints(realm, originatingLogoutSPEntityID);
String location = LogoutUtil.getSLOResponseServiceLocation(slosList, binding);
if (location == null || location.isEmpty()) {
location = LogoutUtil.getSLOServiceLocation(slosList, binding);
if (location == null || location.length() == 0) {
debug.error("Unable to find the IDP's single logout response service with the HTTP-Redirect binding");
throw new SAML2Exception(SAML2Utils.bundle.getString("sloResponseServiceLocationNotfound"));
} else {
if (debug.messageEnabled()) {
debug.message("SP's single logout response service location = " + location);
}
}
} else {
if (debug.messageEnabled()) {
debug.message("IDP's single logout response service location = " + location);
}
}
Status status = destroyTokenAndGenerateStatus(idpSessionIndex, idpSession.getSession(), request, response, true);
//here we are providing null for remote entity, because it's an unused variable in the method...
logoutRes = LogoutUtil.generateResponse(status, originatingRequestID, SAML2Utils.createIssuer(idpEntityID), realm, SAML2Constants.IDP_ROLE, null);
if (logoutRes != null) {
logoutRes.setDestination(XMLUtils.escapeSpecialCharacters(location));
IDPCache.idpSessionsByIndices.remove(idpSessionIndex);
if (agent != null && agent.isRunning() && saml2Svc != null) {
saml2Svc.setIdpSessionCount((long) IDPCache.idpSessionsByIndices.size());
}
try {
if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
SAML2FailoverUtils.deleteSAML2Token(idpSessionIndex);
}
} catch (SAML2TokenRepositoryException se) {
debug.error("IDPSingleLogout.sendLastResponse: Error while deleting token from " + "SAML2 Token Repository for idpSessionIndex:" + idpSessionIndex, se);
}
IDPCache.authnContextCache.remove(idpSessionIndex);
// call multi-federation protocol processing
// this is the SP initiated HTTP binding case
boolean isMultiProtocolSession = false;
int retStatus = SingleLogoutManager.LOGOUT_SUCCEEDED_STATUS;
try {
SessionProvider provider = SessionManager.getProvider();
session = idpSession.getSession();
if (session != null && provider.isValid(session) && MultiProtocolUtils.isMultipleProtocolSession(session, SingleLogoutManager.SAML2)) {
isMultiProtocolSession = true;
// call Multi-Federation protocol SingleLogoutManager
SingleLogoutManager sloManager = SingleLogoutManager.getInstance();
Set set = new HashSet();
set.add(session);
String uid = provider.getPrincipalName(session);
debug.message("IDPSingleLogout.sendLastResponse: MP/Http");
retStatus = sloManager.doIDPSingleLogout(set, uid, request, response, false, true, SingleLogoutManager.SAML2, realm, idpEntityID, originatingLogoutSPEntityID, relayState, null, logoutRes.toXMLString(), getLogoutStatus(logoutRes));
}
} catch (SessionException e) {
// ignore as session might not be valid
debug.message("IDPSingleLogout.sendLastResponse: session", e);
} catch (Exception e) {
debug.message("IDPSingleLogout.sendLastResponse: MP2", e);
retStatus = SingleLogoutManager.LOGOUT_FAILED_STATUS;
}
if (!isMultiProtocolSession || (retStatus != SingleLogoutManager.LOGOUT_REDIRECTED_STATUS)) {
logoutRes = updateLogoutResponse(logoutRes, retStatus);
LogoutUtil.sendSLOResponse(response, request, logoutRes, location, relayState, realm, idpEntityID, SAML2Constants.IDP_ROLE, originatingLogoutSPEntityID, binding);
return true;
} else {
return false;
}
}
IDPCache.idpSessionsByIndices.remove(idpSessionIndex);
if (agent != null && agent.isRunning() && saml2Svc != null) {
saml2Svc.setIdpSessionCount((long) IDPCache.idpSessionsByIndices.size());
}
try {
if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
SAML2FailoverUtils.deleteSAML2Token(idpSessionIndex);
}
} catch (SAML2TokenRepositoryException se) {
debug.error("IDPSingleLogout.sendLastResponse: Error while deleting token from " + "SAML2 Token Repository for idpSessionIndex:" + idpSessionIndex, se);
}
IDPCache.authnContextCache.remove(idpSessionIndex);
return false;
}
Aggregations