Search in sources :

Example 1 with AuthenticationRequestCacheEntry

use of org.wso2.carbon.identity.application.authentication.framework.cache.AuthenticationRequestCacheEntry in project carbon-identity-framework by wso2.

the class FrameworkUtils method getCommonAuthReqWithParams.

/**
 * Builds the wrapper, wrapping incoming request and information take from cache entry.
 *
 * @param request    Original request coming to authentication framework
 * @param cacheEntry Cache entry from the cache, which is added from calling servlets
 * @return
 */
public static HttpServletRequest getCommonAuthReqWithParams(HttpServletRequest request, AuthenticationRequestCacheEntry cacheEntry) {
    // add this functionality as a constructor
    Map<String, String[]> modifiableParameters = new TreeMap<String, String[]>();
    if (cacheEntry != null) {
        AuthenticationRequest authenticationRequest = cacheEntry.getAuthenticationRequest();
        if (!authenticationRequest.getRequestQueryParams().isEmpty()) {
            modifiableParameters.putAll(authenticationRequest.getRequestQueryParams());
        }
        // Adding field variables to wrapper
        if (authenticationRequest.getType() != null) {
            modifiableParameters.put(FrameworkConstants.RequestParams.TYPE, new String[] { authenticationRequest.getType() });
        }
        if (authenticationRequest.getCommonAuthCallerPath() != null) {
            modifiableParameters.put(FrameworkConstants.RequestParams.CALLER_PATH, new String[] { authenticationRequest.getCommonAuthCallerPath() });
        }
        if (authenticationRequest.getRelyingParty() != null) {
            modifiableParameters.put(FrameworkConstants.RequestParams.ISSUER, new String[] { authenticationRequest.getRelyingParty() });
        }
        if (authenticationRequest.getTenantDomain() != null && !IdentityTenantUtil.isTenantQualifiedUrlsEnabled()) {
            modifiableParameters.put(FrameworkConstants.RequestParams.TENANT_DOMAIN, new String[] { authenticationRequest.getTenantDomain() });
        }
        modifiableParameters.put(FrameworkConstants.RequestParams.FORCE_AUTHENTICATE, new String[] { String.valueOf(authenticationRequest.getForceAuth()) });
        modifiableParameters.put(FrameworkConstants.RequestParams.PASSIVE_AUTHENTICATION, new String[] { String.valueOf(authenticationRequest.getPassiveAuth()) });
        if (log.isDebugEnabled()) {
            StringBuilder queryStringBuilder = new StringBuilder("");
            for (Map.Entry<String, String[]> entry : modifiableParameters.entrySet()) {
                StringBuilder paramValueBuilder = new StringBuilder("");
                String[] paramValueArr = entry.getValue();
                if (paramValueArr != null) {
                    for (String paramValue : paramValueArr) {
                        paramValueBuilder.append("{").append(paramValue).append("}");
                    }
                }
                queryStringBuilder.append("\n").append(entry.getKey() + "=" + paramValueBuilder.toString());
            }
            log.debug("\nInbound Request parameters: " + queryStringBuilder.toString());
        }
        return new AuthenticationFrameworkWrapper(request, modifiableParameters, authenticationRequest.getRequestHeaders());
    }
    return request;
}
Also used : TreeMap(java.util.TreeMap) AuthenticationRequest(org.wso2.carbon.identity.application.authentication.framework.model.AuthenticationRequest) Map(java.util.Map) TreeMap(java.util.TreeMap) HashMap(java.util.HashMap) AuthenticationFrameworkWrapper(org.wso2.carbon.identity.application.authentication.framework.model.AuthenticationFrameworkWrapper)

Example 2 with AuthenticationRequestCacheEntry

use of org.wso2.carbon.identity.application.authentication.framework.cache.AuthenticationRequestCacheEntry in project carbon-identity-framework by wso2.

the class IdentityProcessor method buildResponseForFrameworkLogout.

/**
 * Get IdentityResponseBuilder for framework logout
 *
 * @param context IdentityMessageContext
 * @return IdentityResponseBuilder
 */
protected FrameworkLogoutResponse.FrameworkLogoutResponseBuilder buildResponseForFrameworkLogout(IdentityMessageContext context) {
    IdentityRequest identityRequest = context.getRequest();
    Map<String, String[]> parameterMap = identityRequest.getParameterMap();
    AuthenticationRequest authenticationRequest = new AuthenticationRequest();
    authenticationRequest.appendRequestQueryParams(parameterMap);
    Set<Map.Entry<String, String>> headers = new HashMap(identityRequest.getHeaderMap()).entrySet();
    for (Map.Entry<String, String> header : headers) {
        authenticationRequest.addHeader(header.getKey(), header.getValue());
    }
    authenticationRequest.setTenantDomain(identityRequest.getTenantDomain());
    authenticationRequest.setRelyingParty(getRelyingPartyId(context));
    authenticationRequest.setType(getType(context));
    try {
        authenticationRequest.setCommonAuthCallerPath(URLEncoder.encode(getTenantQualifiedCallbackPath(context), StandardCharsets.UTF_8.name()));
    } catch (UnsupportedEncodingException e) {
        throw FrameworkRuntimeException.error("Error occurred while URL encoding callback path " + getTenantQualifiedCallbackPath(context), e);
    }
    authenticationRequest.addRequestQueryParam(FrameworkConstants.RequestParams.LOGOUT, new String[] { "true" });
    AuthenticationRequestCacheEntry authRequest = new AuthenticationRequestCacheEntry(authenticationRequest);
    String sessionDataKey = UUIDGenerator.generateUUID();
    authRequest.setValidityPeriod(TimeUnit.MINUTES.toNanos(IdentityUtil.getOperationCleanUpTimeout()));
    FrameworkUtils.addAuthenticationRequestToCache(sessionDataKey, authRequest);
    InboundUtil.addContextToCache(sessionDataKey, context);
    FrameworkLogoutResponse.FrameworkLogoutResponseBuilder responseBuilder = new FrameworkLogoutResponse.FrameworkLogoutResponseBuilder(context);
    responseBuilder.setAuthName(getType(context));
    responseBuilder.setContextKey(sessionDataKey);
    responseBuilder.setCallbackPath(getTenantQualifiedCallbackPath(context));
    responseBuilder.setRelyingParty(getRelyingPartyId(context));
    // type parameter is using since framework checking it, but future it'll use AUTH_NAME
    responseBuilder.setAuthType(getType(context));
    String commonAuthURL = IdentityUtil.getServerURL(FrameworkConstants.COMMONAUTH, true, true);
    responseBuilder.setRedirectURL(commonAuthURL);
    return responseBuilder;
}
Also used : HashMap(java.util.HashMap) UnsupportedEncodingException(java.io.UnsupportedEncodingException) AuthenticationRequestCacheEntry(org.wso2.carbon.identity.application.authentication.framework.cache.AuthenticationRequestCacheEntry) AuthenticationRequestCacheEntry(org.wso2.carbon.identity.application.authentication.framework.cache.AuthenticationRequestCacheEntry) AuthenticationResultCacheEntry(org.wso2.carbon.identity.application.authentication.framework.cache.AuthenticationResultCacheEntry) AuthenticationRequest(org.wso2.carbon.identity.application.authentication.framework.model.AuthenticationRequest) HashMap(java.util.HashMap) Map(java.util.Map)

Example 3 with AuthenticationRequestCacheEntry

use of org.wso2.carbon.identity.application.authentication.framework.cache.AuthenticationRequestCacheEntry in project carbon-identity-framework by wso2.

the class FrameworkUtils method addAuthenticationRequestToCache.

/**
 * To add authentication request cache entry to cache.
 *
 * @param key          cache entry key
 * @param authReqEntry AuthenticationReqCache Entry.
 */
public static void addAuthenticationRequestToCache(String key, AuthenticationRequestCacheEntry authReqEntry) {
    AuthenticationRequestCacheKey cacheKey = new AuthenticationRequestCacheKey(key);
    AuthenticationRequestCache.getInstance().addToCache(cacheKey, authReqEntry);
}
Also used : AuthenticationRequestCacheKey(org.wso2.carbon.identity.application.authentication.framework.cache.AuthenticationRequestCacheKey)

Example 4 with AuthenticationRequestCacheEntry

use of org.wso2.carbon.identity.application.authentication.framework.cache.AuthenticationRequestCacheEntry in project carbon-identity-framework by wso2.

the class IdentityProcessor method buildResponseForFrameworkLogin.

/**
 * Get IdentityResponseBuilder for framework login
 *
 * @param context IdentityMessageContext
 * @return IdentityResponseBuilder
 */
protected FrameworkLoginResponse.FrameworkLoginResponseBuilder buildResponseForFrameworkLogin(IdentityMessageContext context) {
    IdentityRequest identityRequest = context.getRequest();
    Map<String, String[]> parameterMap = identityRequest.getParameterMap();
    AuthenticationRequest authenticationRequest = new AuthenticationRequest();
    authenticationRequest.appendRequestQueryParams(parameterMap);
    Set<Map.Entry<String, String>> headers = new HashMap(identityRequest.getHeaderMap()).entrySet();
    for (Map.Entry<String, String> header : headers) {
        authenticationRequest.addHeader(header.getKey(), header.getValue());
    }
    authenticationRequest.setTenantDomain(identityRequest.getTenantDomain());
    authenticationRequest.setRelyingParty(getRelyingPartyId(context));
    authenticationRequest.setType(getType(context));
    authenticationRequest.setPassiveAuth(Boolean.parseBoolean(String.valueOf(context.getParameter(InboundConstants.PASSIVE_AUTH))));
    authenticationRequest.setForceAuth(Boolean.parseBoolean(String.valueOf(context.getParameter(InboundConstants.FORCE_AUTH))));
    try {
        authenticationRequest.setCommonAuthCallerPath(URLEncoder.encode(getTenantQualifiedCallbackPath(context), StandardCharsets.UTF_8.name()));
    } catch (UnsupportedEncodingException e) {
        throw FrameworkRuntimeException.error("Error occurred while URL encoding callback path " + getTenantQualifiedCallbackPath(context), e);
    }
    AuthenticationRequestCacheEntry authRequest = new AuthenticationRequestCacheEntry(authenticationRequest);
    String sessionDataKey = UUIDGenerator.generateUUID();
    authRequest.setValidityPeriod(TimeUnit.MINUTES.toNanos(IdentityUtil.getOperationCleanUpTimeout()));
    FrameworkUtils.addAuthenticationRequestToCache(sessionDataKey, authRequest);
    InboundUtil.addContextToCache(sessionDataKey, context);
    FrameworkLoginResponse.FrameworkLoginResponseBuilder responseBuilder = new FrameworkLoginResponse.FrameworkLoginResponseBuilder(context);
    responseBuilder.setAuthName(getType(context));
    responseBuilder.setContextKey(sessionDataKey);
    responseBuilder.setCallbackPath(getTenantQualifiedCallbackPath(context));
    responseBuilder.setRelyingParty(getRelyingPartyId(context));
    // type parameter is using since framework checking it, but future it'll use AUTH_NAME
    responseBuilder.setAuthType(getType(context));
    String commonAuthURL = IdentityUtil.getServerURL(FrameworkConstants.COMMONAUTH, true, true);
    responseBuilder.setRedirectURL(commonAuthURL);
    return responseBuilder;
}
Also used : HashMap(java.util.HashMap) UnsupportedEncodingException(java.io.UnsupportedEncodingException) AuthenticationRequestCacheEntry(org.wso2.carbon.identity.application.authentication.framework.cache.AuthenticationRequestCacheEntry) AuthenticationRequestCacheEntry(org.wso2.carbon.identity.application.authentication.framework.cache.AuthenticationRequestCacheEntry) AuthenticationResultCacheEntry(org.wso2.carbon.identity.application.authentication.framework.cache.AuthenticationResultCacheEntry) AuthenticationRequest(org.wso2.carbon.identity.application.authentication.framework.model.AuthenticationRequest) HashMap(java.util.HashMap) Map(java.util.Map)

Example 5 with AuthenticationRequestCacheEntry

use of org.wso2.carbon.identity.application.authentication.framework.cache.AuthenticationRequestCacheEntry in project carbon-identity-framework by wso2.

the class DefaultRequestCoordinator method handle.

@Override
public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException {
    CommonAuthResponseWrapper responseWrapper = null;
    if (response instanceof CommonAuthResponseWrapper) {
        responseWrapper = (CommonAuthResponseWrapper) response;
    } else {
        responseWrapper = new CommonAuthResponseWrapper(response);
        responseWrapper.setWrappedByFramework(true);
    }
    AuthenticationContext context = null;
    String sessionDataKey = request.getParameter("sessionDataKey");
    try {
        AuthenticationRequestCacheEntry authRequest = null;
        boolean returning = false;
        // TODO: use a different mechanism to determine the flow start.
        if (request.getParameter("type") != null) {
            // handles common auth logout request.
            if (sessionDataKey != null) {
                if (log.isDebugEnabled()) {
                    log.debug("Retrieving authentication request from cache for the sessionDataKey: " + sessionDataKey);
                }
                authRequest = getAuthenticationRequest(request, sessionDataKey);
                if (authRequest == null) {
                    // authRequest is not retrieved from the cache.
                    if (log.isDebugEnabled()) {
                        log.debug("No authentication request found in the cache for sessionDataKey: " + sessionDataKey);
                    }
                    if (isCommonAuthLogoutRequest(request)) {
                        if (log.isDebugEnabled()) {
                            log.debug("Ignoring the invalid sessionDataKey: " + sessionDataKey + " in the " + "CommonAuthLogout request.");
                        }
                    } else {
                        throw new FrameworkException("Invalid authentication request with sessionDataKey: " + sessionDataKey);
                    }
                }
            } else if (!isCommonAuthLogoutRequest(request)) {
                // sessionDataKey is null and not a common auth logout request
                if (log.isDebugEnabled()) {
                    log.debug("Session data key is null in the request and not a logout request.");
                }
                FrameworkUtils.sendToRetryPage(request, response, context);
            }
            // if there is a cache entry, wrap the original request with params in cache entry
            if (authRequest != null) {
                request = FrameworkUtils.getCommonAuthReqWithParams(request, authRequest);
            }
            context = initializeFlow(request, responseWrapper);
            context.initializeAnalyticsData();
        } else {
            returning = true;
            context = FrameworkUtils.getContextData(request);
            associateTransientRequestData(request, responseWrapper, context);
        }
        if (context != null) {
            if (StringUtils.isNotBlank(context.getServiceProviderName())) {
                MDC.put(SERVICE_PROVIDER_QUERY_KEY, context.getServiceProviderName());
            }
            // different threads.
            synchronized (context) {
                if (!context.isActiveInAThread()) {
                    // Marks this context is active in a thread. We only allow at a single instance, a context
                    // to be active in only a single thread. In other words, same context cannot active in two
                    // different threads at the same time.
                    context.setActiveInAThread(true);
                    if (log.isDebugEnabled()) {
                        log.debug("Context id: " + context.getContextIdentifier() + " is active in the thread " + "with id: " + Thread.currentThread().getId());
                    }
                } else {
                    log.error("Same context is currently in used by a different thread. Possible double submit.");
                    if (log.isDebugEnabled()) {
                        log.debug("Same context is currently in used by a different thread. Possible double submit." + "\n" + "Context id: " + context.getContextIdentifier() + "\n" + "Originating address: " + request.getRemoteAddr() + "\n" + "Request Headers: " + getHeaderString(request) + "\n" + "Thread Id: " + Thread.currentThread().getId());
                    }
                    FrameworkUtils.sendToRetryPage(request, responseWrapper, context);
                    return;
                }
            }
            /*
                If
                 Request specify to restart the flow again from first step by passing `restart_flow`.
                 OR
                 Identifier first request received and current step does not contains any flow handler.
                    (To handle browser back with only with identifier-first and basic)
                */
            if (isBackToFirstStepRequest(request) || (isIdentifierFirstRequest(request) && !isFlowHandlerInCurrentStepCanHandleRequest(context, request))) {
                if (isCompletedStepsAreFlowHandlersOnly(context)) {
                    // authenticated authenticator, then we reset the current step to 1.
                    if (log.isDebugEnabled()) {
                        log.debug("Restarting the authentication flow from step 1 for  " + context.getContextIdentifier());
                    }
                    context.setCurrentStep(0);
                    context.setProperty(BACK_TO_FIRST_STEP, true);
                    Map<String, String> runtimeParams = context.getAuthenticatorParams(FrameworkConstants.JSAttributes.JS_COMMON_OPTIONS);
                    runtimeParams.put(FrameworkConstants.JSAttributes.JS_OPTIONS_USERNAME, null);
                    FrameworkUtils.resetAuthenticationContext(context);
                    returning = false;
                    // IDF should be the first step.
                    context.getCurrentAuthenticatedIdPs().clear();
                } else {
                    // If the incoming request is restart and the completed steps have authenticators as the
                    // authenticated authenticator, then we redirect to retry page.
                    String msg = "Restarting the authentication flow failed because there is/are authenticator/s " + "available in the completed steps for  " + context.getContextIdentifier();
                    if (log.isDebugEnabled()) {
                        log.debug(msg);
                    }
                    throw new MisconfigurationException(msg);
                }
            }
            setSPAttributeToRequest(request, context);
            context.setReturning(returning);
            // if this is the flow start, store the original request in the context
            if (!context.isReturning() && authRequest != null) {
                context.setAuthenticationRequest(authRequest.getAuthenticationRequest());
            }
            if (!context.isLogoutRequest()) {
                FrameworkUtils.getAuthenticationRequestHandler().handle(request, responseWrapper, context);
            } else {
                FrameworkUtils.getLogoutRequestHandler().handle(request, responseWrapper, context);
            }
        } else {
            if (log.isDebugEnabled()) {
                String key = request.getParameter("sessionDataKey");
                if (key == null) {
                    log.debug("Session data key is null in the request");
                } else {
                    log.debug("Session data key  :  " + key);
                }
            }
            String userAgent = request.getHeader("User-Agent");
            String referer = request.getHeader("Referer");
            String message = "Requested client: " + request.getRemoteAddr() + ", URI :" + request.getMethod() + ":" + request.getRequestURI() + ", User-Agent: " + userAgent + " , Referer: " + referer;
            log.error("Context does not exist. Probably due to invalidated cache. " + message);
            FrameworkUtils.sendToRetryPage(request, responseWrapper, context);
        }
    } catch (JsFailureException e) {
        if (log.isDebugEnabled()) {
            log.debug("Script initiated Exception occured.", e);
        }
        publishAuthenticationFailure(request, context, context.getSequenceConfig().getAuthenticatedUser(), e.getErrorCode());
        if (log.isDebugEnabled()) {
            log.debug("User will be redirected to retry page or the error page provided by script.");
        }
    } catch (MisconfigurationException e) {
        FrameworkUtils.sendToRetryPage(request, responseWrapper, context, "misconfiguration.error", "something.went.wrong.contact.admin");
    } catch (PostAuthenticationFailedException e) {
        if (log.isDebugEnabled()) {
            log.debug("Error occurred while evaluating post authentication", e);
        }
        FrameworkUtils.removeCookie(request, responseWrapper, FrameworkUtils.getPASTRCookieName(context.getContextIdentifier()));
        publishAuthenticationFailure(request, context, context.getSequenceConfig().getAuthenticatedUser(), e.getErrorCode());
        FrameworkUtils.sendToRetryPage(request, responseWrapper, context, "authentication.attempt.failed", "authorization.failed");
    } catch (Throwable e) {
        if ((e instanceof FrameworkException) && (NONCE_ERROR_CODE.equals(((FrameworkException) e).getErrorCode()))) {
            if (log.isDebugEnabled()) {
                log.debug(e.getMessage(), e);
            }
            FrameworkUtils.sendToRetryPage(request, response, context, "suspicious.authentication.attempts", "suspicious.authentication.attempts.description");
        } else {
            log.error("Exception in Authentication Framework", e);
            FrameworkUtils.sendToRetryPage(request, responseWrapper, context);
        }
    } finally {
        UserCoreUtil.setDomainInThreadLocal(null);
        if (context != null) {
            // Mark this context left the thread. Now another thread can use this context.
            context.setActiveInAThread(false);
            if (log.isDebugEnabled()) {
                log.debug("Context id: " + context.getContextIdentifier() + " left the thread with id: " + Thread.currentThread().getId());
            }
            // If flow is not about to conclude.
            if (!LoginContextManagementUtil.isPostAuthenticationExtensionCompleted(context) || context.isLogoutRequest()) {
                // Persist the context.
                FrameworkUtils.addAuthenticationContextToCache(context.getContextIdentifier(), context);
                if (log.isDebugEnabled()) {
                    log.debug("Context with id: " + context.getContextIdentifier() + " added to the cache.");
                }
            }
            // Clear the auto login related cookies only during none passive authentication flow.
            if (!context.isPassiveAuthenticate()) {
                FrameworkUtils.removeALORCookie(request, response);
            }
        }
        unwrapResponse(responseWrapper, sessionDataKey, response, context);
    }
}
Also used : AuthenticationContext(org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext) FrameworkException(org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException) MisconfigurationException(org.wso2.carbon.identity.application.authentication.framework.exception.MisconfigurationException) JsFailureException(org.wso2.carbon.identity.application.authentication.framework.exception.JsFailureException) PostAuthenticationFailedException(org.wso2.carbon.identity.application.authentication.framework.exception.PostAuthenticationFailedException) AuthenticationRequestCacheEntry(org.wso2.carbon.identity.application.authentication.framework.cache.AuthenticationRequestCacheEntry) CommonAuthResponseWrapper(org.wso2.carbon.identity.application.authentication.framework.model.CommonAuthResponseWrapper)

Aggregations

AuthenticationRequestCacheEntry (org.wso2.carbon.identity.application.authentication.framework.cache.AuthenticationRequestCacheEntry)5 AuthenticationRequest (org.wso2.carbon.identity.application.authentication.framework.model.AuthenticationRequest)5 HashMap (java.util.HashMap)4 Map (java.util.Map)3 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 AuthenticationResultCacheEntry (org.wso2.carbon.identity.application.authentication.framework.cache.AuthenticationResultCacheEntry)2 Enumeration (java.util.Enumeration)1 TreeMap (java.util.TreeMap)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 AuthenticationRequestCacheKey (org.wso2.carbon.identity.application.authentication.framework.cache.AuthenticationRequestCacheKey)1 AuthenticationContext (org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext)1 FrameworkException (org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException)1 JsFailureException (org.wso2.carbon.identity.application.authentication.framework.exception.JsFailureException)1 MisconfigurationException (org.wso2.carbon.identity.application.authentication.framework.exception.MisconfigurationException)1 PostAuthenticationFailedException (org.wso2.carbon.identity.application.authentication.framework.exception.PostAuthenticationFailedException)1 AuthenticationFrameworkWrapper (org.wso2.carbon.identity.application.authentication.framework.model.AuthenticationFrameworkWrapper)1 CommonAuthResponseWrapper (org.wso2.carbon.identity.application.authentication.framework.model.CommonAuthResponseWrapper)1 URLBuilderException (org.wso2.carbon.identity.core.URLBuilderException)1 OIDCSessionManagementException (org.wso2.carbon.identity.oidc.session.OIDCSessionManagementException)1 OIDCSessionDataCacheEntry (org.wso2.carbon.identity.oidc.session.cache.OIDCSessionDataCacheEntry)1