use of com.nimbusds.oauth2.sdk.ResponseMode in project Kustvakt by KorAP.
the class OpenIdResponseHandler method createAuthorizationErrorResponse.
/**
* According to OpenID connect core 1.0 specification, all
* authentication errors must be represented through
* AuthenticationErrorResponse. Moreover, for authorization code
* flow, the error response parameters must be added to the
* redirect URI as query parameters, unless a different response
* mode was specified.
*
* {@link AuthorizationErrorResponse} defines specific
* {@link ErrorObject}s regarding OAUTH2 errors.
* {@link AuthenticationErrorResponse} defines additional
* ErrorObjects regarding OpenID connect authenticaition errors.
*
* @param e
* a {@link KustvaktException}
* @param isAuthentication
* @param redirectURI
* @param state
* @param responseMode
* @return a redirect uri with error response parameters as part
* of query parameters
*/
public Response createAuthorizationErrorResponse(KustvaktException e, boolean isAuthentication, URI redirectURI, State state, ResponseMode responseMode) {
ErrorObject errorObject = createErrorObject(e);
errorObject = errorObject.setDescription(e.getMessage());
if (redirectURI == null) {
return Response.status(errorObject.getHTTPStatusCode()).entity(errorObject.toJSONObject()).build();
}
URI uri = null;
if (isAuthentication) {
uri = new AuthenticationErrorResponse(redirectURI, errorObject, state, responseMode).toURI();
} else {
uri = new AuthorizationErrorResponse(redirectURI, errorObject, state, responseMode).toURI();
}
ResponseBuilder builder = Response.temporaryRedirect(uri).type(MediaType.APPLICATION_FORM_URLENCODED);
return builder.build();
}
use of com.nimbusds.oauth2.sdk.ResponseMode in project Kustvakt by KorAP.
the class OAuth2WithOpenIdController method requestAuthorizationCode.
/**
* Required parameters for OpenID authentication requests:
*
* <ul>
* <li>scope: MUST contain "openid" for OpenID Connect
* requests</li>
* <li>response_type: only "code" is supported</li>
* <li>client_id: client identifier given by Kustvakt during
* client registration</li>
* <li>redirect_uri: MUST match a pre-registered redirect uri
* during client registration</li>
* </ul>
*
* Other parameters:
*
* <ul>
* <li>state (recommended): Opaque value used to maintain state
* between the request and the callback.</li>
* <li>response_mode (optional) : mechanism to be used for
* returning parameters, only "query" is supported</li>
* <li>nonce (optional): String value used to associate a Client
* session with an ID Token,
* and to mitigate replay attacks. </li>
* <li>display (optional): specifies how the Authorization Server
* displays the authentication and consent user interface
* pages. Options: page (default), popup, touch, wap. This
* parameter is more relevant for Kalamar. </li>
* <li>prompt (optional): specifies if the Authorization Server
* prompts the End-User for reauthentication and consent. Defined
* values: none, login, consent, select_account </li>
* <li>max_age (optional): maximum Authentication Age.</li>
* <li>ui_locales (optional): preferred languages and scripts for
* the user interface represented as a space-separated list of
* BCP47 [RFC5646] </li>
* <li>id_token_hint (optional): ID Token previously issued by the
* Authorization Server being passed as a hint</li>
* <li>login_hint (optional): hint to the Authorization Server
* about the login identifier the End-User might use to log
* in</li>
* <li>acr_values (optional): requested Authentication Context
* Class Reference values. </li>
* </ul>
*
* @see "OpenID Connect Core 1.0 specification"
*
* @param request
* @param context
* @param form
* @return a redirect to client redirect uri
*/
@POST
@Path("authorize")
@ResourceFilters({ AuthenticationFilter.class, BlockingFilter.class })
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
public Response requestAuthorizationCode(@Context HttpServletRequest request, @Context SecurityContext context, MultivaluedMap<String, String> form) {
TokenContext tokenContext = (TokenContext) context.getUserPrincipal();
String username = tokenContext.getUsername();
ZonedDateTime authTime = tokenContext.getAuthenticationTime();
Map<String, String> map = MapUtils.toMap(form);
State state = authzService.retrieveState(map);
ResponseMode responseMode = authzService.retrieveResponseMode(map);
boolean isAuthentication = false;
if (map.containsKey("scope") && map.get("scope").contains("openid")) {
isAuthentication = true;
}
URI uri = null;
try {
scopeService.verifyScope(tokenContext, OAuth2Scope.AUTHORIZE);
if (isAuthentication) {
authzService.checkRedirectUriParam(map);
}
uri = authzService.requestAuthorizationCode(form, username, isAuthentication, authTime);
} catch (ParseException e) {
return openIdResponseHandler.createErrorResponse(e, state);
} catch (KustvaktException e) {
return openIdResponseHandler.createAuthorizationErrorResponse(e, isAuthentication, e.getRedirectUri(), state, responseMode);
}
ResponseBuilder builder = Response.temporaryRedirect(uri);
return builder.build();
}
use of com.nimbusds.oauth2.sdk.ResponseMode in project ddf by codice.
the class OidcHandlerConfigurationImpl method setProperties.
public void setProperties(Map<String, Object> properties) {
if (properties == null || properties.isEmpty()) {
LOGGER.warn("Received null or empty properties. Cannot update.");
return;
}
idpType = (String) properties.getOrDefault(IDP_TYPE_KEY, idpType);
clientId = (String) properties.getOrDefault(CLIENT_ID_KEY, idpType);
realm = (String) properties.getOrDefault(REALM_KEY, realm);
secret = (String) properties.getOrDefault(SECRET_KEY, secret);
discoveryUri = (String) properties.getOrDefault(DISCOVERY_URI_KEY, discoveryUri);
baseUri = (String) properties.getOrDefault(BASE_URI_KEY, baseUri);
scope = (String) properties.getOrDefault(SCOPE_KEY, scope);
useNonce = (boolean) properties.getOrDefault(USE_NONCE_KEY, useNonce);
responseType = (String) properties.getOrDefault(RESPONSE_TYPE_KEY, responseType);
responseMode = (String) properties.getOrDefault(RESPONSE_MODE_KEY, responseMode);
logoutUri = (String) properties.getOrDefault(LOGOUT_URI_KEY, logoutUri);
connectTimeout = (int) properties.getOrDefault(CONNECT_TIMEOUT_KEY, connectTimeout);
readTimeout = (int) properties.getOrDefault(READ_TIMEOUT_KEY, readTimeout);
// TODO - Remove if fragment response_mode is supported
if (IMPLICIT_FLOWS.contains(new ResponseType(responseType))) {
responseMode = "form_post";
}
oidcConfiguration = createOidcConfiguration(idpType, realm, baseUri);
oidcConfiguration.setClientId(clientId);
oidcConfiguration.setDiscoveryURI(discoveryUri);
oidcConfiguration.setSecret(secret);
oidcConfiguration.setScope(scope);
oidcConfiguration.setResponseType(responseType);
oidcConfiguration.setResponseMode(responseMode);
oidcConfiguration.setUseNonce(useNonce);
oidcConfiguration.setLogoutUrl(logoutUri);
oidcConfiguration.setWithState(true);
oidcConfiguration.setConnectTimeout(connectTimeout);
oidcConfiguration.setReadTimeout(readTimeout);
try {
testConnection();
} catch (TechnicalException e) {
LOGGER.warn("Failed to validate OIDC handler configuration. Please review configuration and ensure the auth server is reachable", e);
}
}
use of com.nimbusds.oauth2.sdk.ResponseMode in project OpenConext-oidcng by OpenConext.
the class AuthorizationEndpoint method doAuthorization.
private ModelAndView doAuthorization(MultiValueMap<String, String> parameters, OidcSamlAuthentication samlAuthentication, HttpServletRequest request, boolean consentRequired) throws ParseException, CertificateException, JOSEException, IOException, BadJOSEException, java.text.ParseException, URISyntaxException {
AuthorizationRequest authenticationRequest = AuthorizationRequest.parse(parameters);
Scope scope = authenticationRequest.getScope();
boolean isOpenIdClient = scope != null && isOpenIDRequest(scope.toStringList());
String clientId = authenticationRequest.getClientID().getValue();
OpenIDClient client = openIDClientRepository.findOptionalByClientId(clientId).orElseThrow(() -> new UnknownClientException(clientId));
MDCContext.mdcContext("action", "Authorize", "rp", client.getClientId());
if (isOpenIdClient) {
AuthenticationRequest oidcAuthenticationRequest = AuthenticationRequest.parse(parameters);
if (oidcAuthenticationRequest.specifiesRequestObject()) {
oidcAuthenticationRequest = JWTRequest.parse(oidcAuthenticationRequest, client);
LOG.debug("/oidc/authorize with JWT 'request'");
}
// swap reference
authenticationRequest = oidcAuthenticationRequest;
}
State state = authenticationRequest.getState();
String redirectURI = validateRedirectionURI(authenticationRequest.getRedirectionURI(), client).getRedirectURI();
List<String> scopes = validateScopes(openIDClientRepository, authenticationRequest.getScope(), client);
ResponseType responseType = validateGrantType(authenticationRequest, client);
User user = samlAuthentication.getUser();
MDCContext.mdcContext(user);
if (scope != null) {
List<String> scopeList = scope.toStringList();
boolean apiScopeRequested = !(scopeList.size() == 0 || (scopeList.size() == 1 && scopeList.contains("openid")));
Set<String> filteredScopes = scopeList.stream().filter(s -> !s.equalsIgnoreCase("openid")).map(String::toLowerCase).collect(toSet());
List<OpenIDClient> resourceServers = openIDClientRepository.findByScopes_NameIn(filteredScopes);
Prompt prompt = authenticationRequest.getPrompt();
boolean consentFromPrompt = prompt != null && prompt.toStringList().contains("consent");
/*
* We prompt for consent when the following conditions are met:
* Consent feature toggle is on
* The RP has requested scope(s) other then openid
* Manage attribute "oidc:consentRequired" is true for the RP or the RP has explicitly asked for consent
* There is at least one ResourceServer that has the requested scope(s) configured in manage
*/
if (consentRequired && apiScopeRequested && (consentFromPrompt || client.isConsentRequired()) && resourceServers.size() > 0) {
LOG.info("Asking for consent for User " + user + " and scopes " + scopes);
return doConsent(parameters, client, filteredScopes, resourceServers);
}
}
// We do not provide SSO as does EB not - up to the identity provider
logout(request);
ResponseMode responseMode = authenticationRequest.impliedResponseMode();
if (responseType.impliesCodeFlow()) {
AuthorizationCode authorizationCode = createAndSaveAuthorizationCode(authenticationRequest, client, user);
LOG.debug(String.format("Returning authorizationCode flow %s %s", ResponseMode.FORM_POST, redirectURI));
if (responseMode.equals(ResponseMode.FORM_POST)) {
Map<String, String> body = new HashMap<>();
body.put("redirect_uri", redirectURI);
body.put("code", authorizationCode.getCode());
if (state != null && StringUtils.hasText(state.getValue())) {
body.put("state", state.getValue());
}
return new ModelAndView("form_post", body);
}
return new ModelAndView(new RedirectView(authorizationRedirect(redirectURI, state, authorizationCode.getCode(), responseMode.equals(ResponseMode.FRAGMENT))));
} else if (responseType.impliesImplicitFlow() || responseType.impliesHybridFlow()) {
if (responseType.impliesImplicitFlow()) {
// User information is encrypted in access token
LOG.debug("Deleting user " + user.getSub());
userRepository.delete(user);
}
Map<String, Object> body = authorizationEndpointResponse(user, client, authenticationRequest, scopes, responseType, state);
LOG.debug(String.format("Returning implicit flow %s %s", ResponseMode.FORM_POST, redirectURI));
if (responseMode.equals(ResponseMode.FORM_POST)) {
body.put("redirect_uri", redirectURI);
return new ModelAndView("form_post", body);
}
if (responseMode.equals(ResponseMode.QUERY)) {
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(redirectURI);
body.forEach(builder::queryParam);
return new ModelAndView(new RedirectView(builder.toUriString()));
}
if (responseMode.equals(ResponseMode.FRAGMENT)) {
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(redirectURI);
String fragment = body.entrySet().stream().map(entry -> String.format("%s=%s", entry.getKey(), entry.getValue())).collect(Collectors.joining("&"));
builder.fragment(fragment);
return new ModelAndView(new RedirectView(builder.toUriString()));
}
throw new IllegalArgumentException("Response mode " + responseMode + " not supported");
}
throw new IllegalArgumentException("Not yet implemented response_type: " + responseType.toString());
}
Aggregations