/**
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* See the License for the specific language governing
* permission and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at opensso/legal/CDDLv1.0.txt.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* $Id: FSSSOAndFedHandler.java,v 1.12 2009/11/04 00:06:11 exu Exp $
*
* Portions Copyrighted 2015 ForgeRock AS.
*/
/**
* Base class for <code>IDP</code> side handler that handles single sign on
* and federation requests.
*/
public abstract class FSSSOAndFedHandler {
static {
try {
"com.sun.identity.federation.proxyfinder");
if ((proxyFinderClass != null) &&
{
if (proxyClass instanceof FSRealmIDPProxy) {
} else if (proxyClass instanceof FSIDPProxy) {
}
}
}
}
/**
* Sets meta alias of the host identity provider.
* @param metaAlias meta alias of the provider.
*/
try {
} catch (FSAccountMgmtException e) {
"FSSSOAndFedHandler: couldn't obtain account manager:", e);
}
}
/**
* Sets host identity provider's entity ID.
* @param hostedEntityId entity ID to be set
* @see #getHostedEntityId()
*/
this.hostedEntityId = hostedEntityId;
}
/**
* Sets host identity provider's meta descriptor.
* @param hostedDesc hosted meta descriptor to be set
*/
this.hostedDesc = hostedDesc;
}
/**
* Sets host identity provider's extended meta.
* @param hostedConfig host identity provider's extended meta to be set
*/
this.hostedConfig = hostedConfig;
}
/**
* Gets hosted provider id.
* @return hosted provider id.
* @see #setHostedEntityId(String)
*/
return hostedEntityId;
}
/**
* Gets the realm under which the entity resides.
* @return the realm under which the entity resides.
* @see #setRealm(String)
*/
return realm;
}
/**
* Sets the realm under which the entity resides.
* @param realm The realm under which the entity resides.
* @see #getRealm()
*/
}
/**
* Default constructor.
*/
protected FSSSOAndFedHandler() {
}
/**
* Constructor.
* @param request <code>HttpServletRequest</code> object
* @param response <code>HttpServletResponse</code> object
* @param authnRequest authentication request
* @param spDescriptor <code>SP</code>'s provider descriptor
* @param spConfig <code>SP</code>'s provider extended meta
* @param spEntityId <code>SP</code>'s entity id
* @param relayState where to go after single sign on is done
* @param ssoToken token of the user to be single sign-oned
*/
public FSSSOAndFedHandler(
{
this.relayState = relayState;
this.authnRequest = authnRequest;
this.spDescriptor = spDescriptor;
this.spEntityId = spEntityId;
}
/**
* Constructor.
* @param request <code>HttpServletRequest</code> object
* @param response <code>HttpServletResponse</code> object
* @param authnRequest authentication request
* @param spDescriptor <code>SP</code>'s provider descriptor
* @param spConfig <code>SP</code>'s extended meta
* @param spEntityId <code>SP</code>'s entity id
* @param relayState where to go after single sign on is done
*/
public FSSSOAndFedHandler(
{
this.authnRequest = authnRequest;
this.spDescriptor = spDescriptor;
this.spEntityId = spEntityId;
this.relayState = relayState;
}
/**
* Constructor.
* @param request <code>HttpServletRequest</code> object
* @param response <code>HttpServletResponse</code> object
*/
public FSSSOAndFedHandler(
{
}
/**
* Handles authentication request.
* @param authnRequest <code>FSAuthnRequest</code> object
* @return <code>true</code> if the request is handled successfully;
* <code>false</code> otherwise.
*/
{
if (authenticationContextClassRef == null) {
authenticationContextClassRef = new ArrayList();
}
}
boolean authenticated = true;
try {
"FSSSOAndFedHandler.processPreAuthnSSO: "
+ "session is null. User is not authenticated.");
}
authenticated = false;
"FSSSOAndFedHandler.processPreAuthnSSO: "
+ "session is not valid. User is not authenticated.");
}
authenticated = false;
} else {
if (ssoSession != null) {
if (currentAuthnContextRef != null){
+ "processPreAuthnSSO: User has an existing "
+ "valid session with authnContext: "
}
} else {
+ "processPreAuthnSSO: User's authentication"
+ " context information not found using "
+ "default authentication context");
}
}
} else {
+ "PreAuthnSSO: User's authenticated session "
+ "information is not present in FSSessionManager. "
+ "using default authentication context");
}
}
authenticated = true;
}
if (authenticated) {
// add a listener. TODO : more than one listeners could be
// added in case of multiple SPs
try {
new FSTokenListener(metaAlias));
} catch (Exception e) {
"FSSSOAndFedHandler.processPreAuthnSSO: " +
"Couldn't add listener to session:", e);
}
}
}
} catch(SessionException se) {
+ "SSOException Occured: User does not have session " +
se.getMessage());
authenticated = false;
}
//Initiate proxying
if (!authenticated) {
try {
if (preferredIDP != null) {
"PreAuthnSSO:IDP to be proxied" + preferredIDP);
}
return true;
}
//else continue for the local authentication.
}
} catch (FSRedirectException re) {
"FSSSOAndFedHandle.processPreAuthnSSO:"
+ "Redirecting for the proxy handling.");
}
return true;
"Exception occured while processing for the proxy.", ex);
return false;
}
}
try {
+ "User's authentication status: " + authenticated);
}
if (authnRequest.getIsPassive()){
if (authnRequest.getForceAuthn()){
+ "IDP is passive can't force authentication.");
}
return false;
} else {
if (authenticated){
if (authenticationContextClassRef != null){
authType);
} else {
+ "processPreAuthnSSO: User's "
+ "authentication context is default");
}
authType);
}
if (authnResult == null) {
return false;
}
// When it's not null.,
// we should show the login page
// may be it'asking for higher auth context.
return true;
} else {
+ "processPreAuthnSSO: User's "
+ "authentication "
+ "context is evaluated to be valid");
}
return processPostAuthnSSO(authnRequest);
}
} else {
"FSSSOAndFedHandler.processPreAuthnSSO: " +
"IDP is passive and user is not authenticated");
}
noFedStatus = new Status(
new StatusCode("samlp:Responder",
"AuthnRequestProcessingFailed"),
null);
return false;
}
}
} else {
+ "processPreAuthnSSO: AuthnRequest is active");
}
if (authnRequest.getForceAuthn()){
if (authenticationContextClassRef != null){
authType);
} else {
}
if (authnResult == null ||
{
"FSSSOAndFedHandler.processPreAuthnSSO:"
+ "AuthnDecision engine failed to take a "
+ "authn decision");
}
return false;
} else {
try {
} catch (SessionException ssoe) {
"FSSSOAndFedHandler.processPreAuthnSSO:" +
"Unable to invalidate the sso session.");
}
}
"FSSSOAndFedHandler.processPreAuthnSSO: "
+ "AuthnDecision engine returned: "
+ loginURL);
}
}
response.flushBuffer ();
return true;
} else {
if (authenticated){
if (authenticationContextClassRef != null){
authType);
} else {
+ "processPreAuthnSSO: User's "
+ "authentication "
+ "context is default");
}
authType);
}
if (authnResult == null){
return false;
+ "processPreAuthnSSO: User's "
+ "authentication "
+ "context is evaluated to be valid");
}
return processPostAuthnSSO(authnRequest);
return false;
} else {
"FSSSOAndFedHandler.processPreAuthnSSO"
+ ": AuthnDecision engine returned: "
+ loginURL);
}
}
return true;
} else {
+ "processPreAuthnSSO: AuthnRequest is active");
}
//redirect for authentication authnContextRef
if (authenticationContextClassRef != null){
authType);
} else {
+ "processPreAuthnSSO: User's "
+ "authentication "
+ "context is default");
}
authType);
}
if (authnResult == null ||
{
"FSSSOAndFedHandler. processPreAuthnSSO: "
+ " AuthnDecision engine"
+ " failed to take a decision");
}
noFedStatus = new Status(
new StatusCode("samlp:Responder",
"AuthnRequestProcessingFailed"),
null);
return false;
} else {
"FSSSOAndFedHandler.processPreAuthnSSO: "
+ "AuthnDecision engine returned: "
+ loginURL);
}
}
return true;
}
}
}
} catch(Exception e){
+ "Exception occured");
return processPostAuthnSSO(authnRequest);
}
}
/**
* Generates local login url.
* @param loginUrl authentication base url
* @param authnContext requested <code>AuthnContextRef</code>
* @return local login url with appropriate parameters
*/
)
{
try {
return null;
}
//create return url
} else {
}
authnRequest.getRequestID()));
//create goto url
} else {
}
//create redirect url
} else {
}
//will change
//request.getSession(true)
// .setAttribute(IFSConstants.AUTHN_CONTEXT, authnContext);
}
return redirectUrl.toString();
} catch(Exception e){
"FSSSOAndFedHandler.formatLoginURL: Exception: " ,e);
return null;
}
}
/**
* Handles authentication request after local login.
* @param authnRequest <code>FSAuthnRequest</code> object
* @return <code>true</code> if the request is handled successfully;
* <code>false</code> otherwise.
*/
try {
}
+ "session is not valid.");
return false;
} else {
"FSSSOAndFedHandler.processPostAuthnSSO: "
+ "session is valid.");
}
}
} catch(SessionException se) {
return false;
}
//save session
try {
"FSSSOAndFedHandler.processPostAuthnSSO: "
+ "UserID of the principal in the session: " + userID
+ "sessionID of the session: " + sessionID);
}
} catch(SessionException ex){
+ "SessionException occured. "
+ "Principal information not found in the session: ", ex);
return false;
}
+ "An existing SSO session found with ID:"
+ session.getSessionID());
}
new FSSessionPartner(spEntityId, false));
} else {
+ "No existing SSO session found. "
+ "Entering a new session to the session manager with ID: "
+ sessionID);
}
new FSSessionPartner(spEntityId, false));
}
// check for federation
if (authnRequest.getFederate() ||
{
+ "Accountfederation failed");
return false;
} else {
"AuthnSSO: Opaque handle not found");
return false;
}
}
}
}
return doSingleSignOn(ssoToken,
spNI,
idpNI);
} else {
}
}
{
"FSSSOAndFedHandler.createAuthnResponse: Called");
try {
null,
+ "CHECK1: " + hostedEntityId);
}
} catch(FSException se) {
"FSSSOAndFedHandler.createAuthnResponse: FSException: ", se);
return null;
} catch(SAMLException se) {
+ "SAMLException: ", se);
return null;
} catch (SessionException se) {
+ "SessionException: ", se);
return null;
}
// sign AuthnResponse
return authnResponse;
}
protected boolean doSingleSignOn(
{
return false;
}
protected boolean doSingleSignOn(
{
try {
if (affiliationID != null) {
}
+ "Initiating SSO for user with ID: " + userID);
}
if (accountInfo == null) {
"FSSSOAndFedHandler.doSingleSignOn: Account Federation "
+ "Information not found for user with ID: "
+ userID);
noFedStatus = new Status(
new StatusCode("samlp:Responder",
null);
return false;
}
if (accountInfo != null &&
{
// Check if this is 6.2
localNI = new NameIdentifier(
}
accountInfo = new FSAccountFedInfo(
}
}
+ "NameIdentifier not found");
return false;
}
} else {
}
}
} else {
}
}
} catch(Exception e){
+ "Exception during Single Sign-On:", e);
return false;
}
}
{
boolean isAffiliationFed = false;
if (affiliationID != null) {
try {
} catch (Exception e) {
"Federation:Error in checking for the affiliation:", e);
}
}
}
try {
if (isAffiliationFed) {
return existActInfo;
}
}
// Check if there is an existing fed info
return existActInfo;
}
if (opaqueHandle == null){
+ "Could not generate handle");
return null;
}
+ "Generated handle: " + opaqueHandle);
}
if (isAffiliationFed) {
}
if (authnRequest.getMinorVersion() ==
{
if (nameIDPolicy == null ||
{
} else {
}
}
if (isAffiliationFed) {
accountInfo.setAffiliation(true);
} else {
fedKey = new FSAccountFedInfoKey(
}
} else {
session.setOneTime(true);
}
return accountInfo;
+ "Exception when doing account federation", ex);
return null;
}
}
protected void returnErrorResponse() {
}
/**
* Processes <code>SAML</code> request.
* @param samlRequest <code>FSSAMLRequest</code> object
* @return generated <code>FSResponse</code> object
*/
+ "Call should not resolve here, abstract class.");
return null;
}
/**
* Processes authentication request.
* @param authnRequest authentication request
* @param bPostAuthn <code>true</code> indicates it's post authentication;
* <code>false</code> indicates it's pre authentication.
*/
public void processAuthnRequest(
boolean bPostAuthn
)
{
this.authnRequest = authnRequest;
try {
if (!metaManager.isTrustedProvider(
{
"FSSSOAndFedHandler.processAuthnRequest: "
+ "RemoteProvider is not trusted");
"AuthnRequestProcessingFailed");
null,
return;
}
if (bPostAuthn){
if (processPostAuthnSSO(authnRequest)){
+ "processAuthnRequest: AuthnRequest Processing "
+ "successful");
}
return;
} else {
"FSSSOAndFedHandler.processAuthnRequest: "
+ "AuthnRequest Processing failed");
}
"AuthnRequestProcessingFailed");
if (noFedStatus != null) {
} else {
}
null,
return;
}
} else {
boolean authnRequestSigned =
"FSSSOAndFedHandler.processAuthnRequest: "
+ "ProviderID : " + spEntityId
+ " AuthnRequestSigned :this is for testing "
}
if (FSServiceUtils.isSigningOn()){
if (authnRequestSigned){
//verify request signature
if (!verifyRequestSignature(authnRequest)){
+ "processAuthnRequest: "
+ "AuthnRequest Signature Verification Failed");
"signatureVerificationFailed");
new StatusCode("samlp:Responder",
new StatusCode(
"lib:UnsignedAuthnRequest", null)),
null);
null,
return;
} else {
"FSSSOAndFedHandler. processAuthnRequest"
+ ": AuthnRequest Signature Verified");
}
}
}
}
if (processPreAuthnSSO(authnRequest)){
"FSSSOAndFedHandler.processAuthnRequest: "
+ "AuthnRequest Processing successful");
}
return;
} else {
"FSSSOAndFedHandler.processAuthnRequest: "
+ "AuthnRequest Processing failed");
}
"AuthnRequestProcessingFailed") };
"AuthnRequestProcessingFailed");
if (noFedStatus != null) {
}
null,
return;
}
}
} catch(Exception e){
+ "Exception Occured: " + e.getMessage()
try {
null,
"FSSSOAndFedHandler.processAuthnRequest: "
+ "Exception Occured: ", ex);
}
}
}
}
protected void sendAuthnResponse(
)
{
+ "Call should not resolve here. error");
}
/**
* Sets remote <code>SP</code> provider descriptor.
* @param spDescriptor remote <code>SP</code> provider descriptor.
* @see #getProvider()
*/
this.spDescriptor = spDescriptor;
}
/**
* Returns remote <code>SP</code> provider descriptor.
*
* @return remote <code>SP</code> provider descriptor
*/
return spDescriptor;
}
"FSSSOAndFedHandler.verifyRequestSignature: Called");
try {
spDescriptor, spEntityId, false);
"FSSSOAndFedHandler.verifyRequestSignature: "
+ "couldn't obtain this site's cert.");
}
}
"FSSSOAndFedHandler.verifyRequestSignature: "
+ "Request is sent by GET" );
}
{
return false;
}
} else {
"FSSSOAndFedHandler.signAndReturnQueryString: "
+ "Invalid signature algorithim");
return false;
}
"Signature: queryString:" + queryString);
}
"FSSSOAndFedHandler.verifyRequestSignature: "
}
"FSSSOAndFedHandler.verifyRequestSignature: "
+ "String to be verified: " + newQueryString);
}
cert);
} else {
"FSSSOAndFedHandler.verifyRequestSignature: "
+ "Request is sent by POST ");
}
} else if (minorVersion ==
{
} else {
return false;
}
}
} catch(Exception e){
+ "Exception occured while verifying SP's signature:", e);
return false;
}
}
/**
* Removes meta alias from request parameters.
* @param request <code>HttpServletRequest</code> object
* @return parameter string which doesn't contain meta alias
*/
while (paramEnum.hasMoreElements()) {
"FSSSOAndFedHandler.cleanMetaAlias: found metaAlias");
} else {
} else {
}
}
}
+ " returning with " + returnString);
}
return returnString;
}
/**
* Sends a new AuthnRequest to the authenticating provider.
* @param authnRequest original AuthnRequest sent by the service provider.
* @param preferredIDP IDP to be proxied.
* @exception FSException for any federation failure.
* @exception IOException if there is a failure in redirection.
*/
protected void sendProxyAuthnRequest (
) throws FSException, IOException
{
}
try {
"FSSSOAndFedHandler.sendProxyAuthnRequest: Single " +
"Sign-on service is not found for the proxying IDP");
return;
}
} catch (Exception e) {
"FSSSOAndFedHandler.sendProxyAuthnRequest:",e);
return;
}
if (FSServiceUtils.isSigningOn()) {
if (localDescriptor.isAuthnRequestsSigned()) {
}
}
} else {
}
"SSO URL to be redirected" + redirectURL);
}
}
/**
* Checks if the identity provider is configured for proxying the
* authentication requests for a requesting service provider.
* @param authnRequest Authentication Request.
* @return <code>true</code> if the IDP is configured for proxying.
* @exception FSException for any failure.
*/
throws FSException
{
if (authnRequest.getMinorVersion() !=
{
return false;
}
return false;
}
return true;
} else {
return false;
}
}
/**
* Gets the preferred IDP Id to be proxied. This method makes use of an
* SPI to determine the preffered IDP.
* @param authnRequest original Authn Request.
* @return String preferred IDP to be proxied.
*/
throws FSRedirectException
{
if (realmProxyFinder != null) {
return realmProxyFinder.getPreferredIDP(
} else {
return proxyFinder.getPreferredIDP(
}
}
/**
* Constructs new authentication request by using the original request
* that is sent by the service provider to the proxying IDP.
* @param origRequest Original Authn Request
* @return FSAuthnRequest new authn request.
* @exception FSException for failure in creating new authn request.
*/
) throws FSException
{
// New Authentication request should only be a single sign-on request.
try {
false,
if (proxyCount > 0 ) {
}
}
return newRequest;
"Error in creating new authn request.", ex);
throw new FSException(ex);
}
}
}