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;
}
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;
}
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);
}
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;
}
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);
}
}
Aggregations