use of org.pac4j.core.context.JEEContext in project cas by apereo.
the class OAuth20AuthorizeEndpointController method prepareAccessTokenRequestContext.
/**
* Build access token request context.
*
* @param authzRequest the authz request
* @param registeredService the registered service
* @param context the context
* @param service the service
* @param authentication the authentication
* @return the access token request context
* @throws Exception the exception
*/
protected AccessTokenRequestContext prepareAccessTokenRequestContext(final OAuth20AuthorizationRequest authzRequest, final OAuthRegisteredService registeredService, final JEEContext context, final Service service, final Authentication authentication) throws Exception {
var payloadBuilder = AccessTokenRequestContext.builder();
if (authzRequest.isSingleSignOnSessionRequired()) {
val tgt = getConfigurationContext().fetchTicketGrantingTicketFrom(context);
payloadBuilder = payloadBuilder.ticketGrantingTicket(tgt);
}
val redirectUri = OAuth20Utils.getRequestParameter(context, OAuth20Constants.REDIRECT_URI).map(String::valueOf).orElse(StringUtils.EMPTY);
val grantType = context.getRequestParameter(OAuth20Constants.GRANT_TYPE).map(String::valueOf).orElseGet(OAuth20GrantTypes.AUTHORIZATION_CODE::getType).toUpperCase();
val scopes = OAuth20Utils.parseRequestScopes(context);
val codeChallenge = context.getRequestParameter(OAuth20Constants.CODE_CHALLENGE).map(String::valueOf).orElse(StringUtils.EMPTY);
val codeChallengeMethod = context.getRequestParameter(OAuth20Constants.CODE_CHALLENGE_METHOD).map(String::valueOf).orElse(StringUtils.EMPTY).toUpperCase();
val userProfile = OAuth20Utils.getAuthenticatedUserProfile(context, getConfigurationContext().getSessionStore());
val claims = OAuth20Utils.parseRequestClaims(context);
val holder = payloadBuilder.service(service).authentication(authentication).registeredService(registeredService).grantType(OAuth20Utils.getGrantType(context)).responseType(OAuth20Utils.getResponseType(context)).codeChallenge(codeChallenge).codeChallengeMethod(codeChallengeMethod).scopes(scopes).clientId(authzRequest.getClientId()).redirectUri(redirectUri).userProfile(userProfile).claims(claims).responseMode(OAuth20Utils.getResponseModeType(context)).build();
context.getRequestParameters().keySet().forEach(key -> context.getRequestParameter(key).ifPresent(value -> holder.getParameters().put(key, value)));
LOGGER.debug("Building authorization response for grant type [{}] with scopes [{}] for client id [{}]", grantType, scopes, authzRequest.getClientId());
return holder;
}
use of org.pac4j.core.context.JEEContext in project cas by apereo.
the class OAuth20AuthorizeEndpointController method buildAuthorizationForRequest.
/**
* Build callback url for request string.
*
* @param registeredService the registered service
* @param context the context
* @param service the service
* @param authentication the authentication
* @return the model and view
*/
protected ModelAndView buildAuthorizationForRequest(final OAuthRegisteredService registeredService, final JEEContext context, final Service service, final Authentication authentication) {
val registeredBuilders = getConfigurationContext().getOauthAuthorizationResponseBuilders().getObject();
val authzRequest = registeredBuilders.stream().sorted(OrderComparator.INSTANCE).map(builder -> toAuthorizationRequest(registeredService, context, service, authentication, builder)).filter(Objects::nonNull).filter(Optional::isPresent).findFirst().orElseThrow(() -> new IllegalArgumentException("Unable to build authorization request")).get().build();
val payload = Optional.ofNullable(authzRequest.getAccessTokenRequest()).orElseGet(Unchecked.supplier(() -> prepareAccessTokenRequestContext(authzRequest, registeredService, context, service, authentication)));
return registeredBuilders.stream().sorted(OrderComparator.INSTANCE).filter(b -> b.supports(authzRequest)).findFirst().map(Unchecked.function(builder -> {
if (authzRequest.isSingleSignOnSessionRequired() && payload.getTicketGrantingTicket() == null) {
val message = String.format("Missing ticket-granting-ticket for client id [%s] and service [%s]", authzRequest.getClientId(), registeredService.getName());
LOGGER.error(message);
return OAuth20Utils.produceErrorView(new PreventedException(message));
}
return builder.build(payload);
})).orElseGet(() -> OAuth20Utils.produceErrorView(new PreventedException("Could not build the callback response")));
}
use of org.pac4j.core.context.JEEContext in project cas by apereo.
the class OidcClientConfigurationEndpointController method handleRequestInternal.
/**
* Handle request response entity.
*
* @param clientId the client id
* @param request the request
* @param response the response
* @return the response entity
*/
@GetMapping(value = { '/' + OidcConstants.BASE_OIDC_URL + '/' + OidcConstants.CLIENT_CONFIGURATION_URL, "/**/" + OidcConstants.CLIENT_CONFIGURATION_URL }, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity handleRequestInternal(@RequestParam(name = OidcConstants.CLIENT_REGISTRATION_CLIENT_ID) final String clientId, final HttpServletRequest request, final HttpServletResponse response) {
val webContext = new JEEContext(request, response);
if (!getConfigurationContext().getOidcRequestSupport().isValidIssuerForEndpoint(webContext, OidcConstants.CLIENT_CONFIGURATION_URL)) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
val service = OAuth20Utils.getRegisteredOAuthServiceByClientId(getConfigurationContext().getServicesManager(), clientId);
if (service instanceof OidcRegisteredService) {
val prefix = getConfigurationContext().getCasProperties().getServer().getPrefix();
val regResponse = OidcClientRegistrationUtils.getClientRegistrationResponse((OidcRegisteredService) service, prefix);
return new ResponseEntity<>(regResponse, HttpStatus.OK);
}
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
use of org.pac4j.core.context.JEEContext in project cas by apereo.
the class OidcLogoutEndpointController method handleRequestInternal.
/**
* Handle request.
*
* @param postLogoutRedirectUrl the post logout redirect url
* @param state the state
* @param idToken the id token
* @param request the request
* @param response the response
* @return the response entity
* @throws Exception the exception
*/
@GetMapping(value = { '/' + OidcConstants.BASE_OIDC_URL + '/' + OidcConstants.LOGOUT_URL, '/' + OidcConstants.BASE_OIDC_URL + "/logout", "/**/" + OidcConstants.LOGOUT_URL })
public ResponseEntity<HttpStatus> handleRequestInternal(@RequestParam(value = "post_logout_redirect_uri", required = false) final String postLogoutRedirectUrl, @RequestParam(value = "state", required = false) final String state, @RequestParam(value = "id_token_hint", required = false) final String idToken, final HttpServletRequest request, final HttpServletResponse response) throws Exception {
val webContext = new JEEContext(request, response);
if (!getConfigurationContext().getOidcRequestSupport().isValidIssuerForEndpoint(webContext, OidcConstants.LOGOUT_URL)) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
String clientId = null;
if (StringUtils.isNotBlank(idToken)) {
LOGGER.trace("Decoding logout id token [{}]", idToken);
val configContext = getConfigurationContext();
val claims = configContext.getIdTokenSigningAndEncryptionService().decode(idToken, Optional.empty());
clientId = claims.getStringClaimValue(OAuth20Constants.CLIENT_ID);
LOGGER.debug("Client id retrieved from id token is [{}]", clientId);
val registeredService = OAuth20Utils.getRegisteredOAuthServiceByClientId(configContext.getServicesManager(), clientId);
LOGGER.debug("Located registered service [{}]", registeredService);
val service = configContext.getWebApplicationServiceServiceFactory().createService(clientId);
val audit = AuditableContext.builder().service(service).registeredService(registeredService).build();
val accessResult = configContext.getRegisteredServiceAccessStrategyEnforcer().execute(audit);
accessResult.throwExceptionIfNeeded();
WebUtils.putRegisteredService(request, Objects.requireNonNull(registeredService));
val urls = configContext.getSingleLogoutServiceLogoutUrlBuilder().determineLogoutUrl(registeredService, service, Optional.of(request)).stream().map(SingleLogoutUrl::getUrl).collect(Collectors.toList());
LOGGER.debug("Logout urls assigned to registered service are [{}]", urls);
if (StringUtils.isNotBlank(postLogoutRedirectUrl) && registeredService.getMatchingStrategy() != null) {
val matchResult = registeredService.matches(postLogoutRedirectUrl) || urls.stream().anyMatch(url -> postLogoutRedirectUrlMatcher.matches(postLogoutRedirectUrl, url));
if (matchResult) {
LOGGER.debug("Requested logout URL [{}] is authorized for redirects", postLogoutRedirectUrl);
return new ResponseEntity<>(executeLogoutRedirect(Optional.ofNullable(StringUtils.trimToNull(state)), Optional.of(postLogoutRedirectUrl), Optional.of(clientId), request, response));
}
}
val validURL = urls.stream().filter(urlValidator::isValid).findFirst();
if (validURL.isPresent()) {
return new ResponseEntity<>(executeLogoutRedirect(Optional.ofNullable(StringUtils.trimToNull(state)), validURL, Optional.of(clientId), request, response));
}
LOGGER.debug("No logout urls could be determined for registered service [{}]", registeredService.getName());
}
return new ResponseEntity<>(executeLogoutRedirect(Optional.ofNullable(StringUtils.trimToNull(state)), Optional.empty(), Optional.ofNullable(clientId), request, response));
}
use of org.pac4j.core.context.JEEContext in project cas by apereo.
the class OidcClientConfigurationAccessTokenAuthenticatorTests method verifyOperation.
@Test
public void verifyOperation() throws Exception {
val request = new MockHttpServletRequest();
val ctx = new JEEContext(request, new MockHttpServletResponse());
val auth = new OidcClientConfigurationAccessTokenAuthenticator(ticketRegistry, oidcAccessTokenJwtBuilder);
val at = getAccessToken();
when(at.getScopes()).thenReturn(Set.of(OidcConstants.CLIENT_REGISTRATION_SCOPE));
ticketRegistry.addTicket(at);
val credentials = new TokenCredentials(at.getId());
auth.validate(credentials, ctx, JEESessionStore.INSTANCE);
val userProfile = credentials.getUserProfile();
assertNotNull(userProfile);
assertEquals("casuser", userProfile.getId());
}
Aggregations