@Override protected AuthenticationResponse syncAuthenticate(ProviderRequest providerRequest) { Map<String, List<String>> headers = providerRequest.env().headers(); List<String> authorizationHeader = headers.get(HEADER_AUTHENTICATION); if (null == authorizationHeader) { return fail("No " + HEADER_AUTHENTICATION + " header"); } return authorizationHeader.stream() .filter(header -> header.toLowerCase().startsWith(BASIC_PREFIX)) .findFirst() .map(this::validateBasicAuth) .orElseGet(() -> fail("Authorization header does not contain basic authentication: " + authorizationHeader)); }
private SecurityEnvironment updateRequestHeaders(SecurityEnvironment env, OutboundSecurityResponse response) { SecurityEnvironment.Builder builder = env.derive(); response.requestHeaders().forEach(builder::header); return builder.build(); }
String getSignedString(Map<String, List<String>> newHeaders, SecurityEnvironment env) { StringBuilder toSign = new StringBuilder(); Map<String, List<String>> requestHeaders = env.headers(); .append(env.method().toLowerCase()) .append(" ") .append(env.path().orElse("/")) .append('\n'); } else { URI uri = env.targetUri();
/** * Find target for current security request. * Example of implementation * of {@link OutboundSecurityProvider#isOutboundSupported(ProviderRequest, SecurityEnvironment, EndpointConfig)}: * {@code * return (null != outboundTargets) && outboundTargets.findTarget(request).isPresent(); * } * * @param env request we are processing * @return TargetConfig wrapped in {@link Optional} valid for the request */ public Optional<OutboundTarget> findTarget(SecurityEnvironment env) { String transport = env.transport(); String host = env.targetUri().getHost(); String path = env.path().orElse(null); for (OutboundTarget outboundTarget : targets) { if (outboundTarget.matches(transport, host, path)) { return Optional.of(outboundTarget); } } return Optional.empty(); }
private String origUri(ProviderRequest providerRequest) { List<String> origUri = providerRequest.env().headers() .getOrDefault(Security.HEADER_ORIG_URI, CollectionsHelper.listOf()); if (origUri.isEmpty()) { origUri = CollectionsHelper.listOf(providerRequest.env().targetUri().getPath()); } try { return URLEncoder.encode(origUri.get(0), "UTF-8"); } catch (UnsupportedEncodingException e) { throw new SecurityException("UTF-8 must be supported for security to work", e); } }
/** * Security environment builder, to be used to create * environment for evaluating security in integration components. * * @return builder to build {@link SecurityEnvironment} */ public SecurityEnvironment.Builder environmentBuilder() { return SecurityEnvironment.builder(serverTime); }
try { token = DigestToken.fromAuthorizationHeader(headerValue.substring(DIGEST_PREFIX.length()), env.method().toLowerCase()); } catch (HttpAuthException e) { LOGGER.log(Level.FINEST, "Failed to process digest token", e);
private AuthenticationResponse validateSignature(SecurityEnvironment env, HttpSignature httpSignature, InboundClientDefinition clientDefinition) { // validate algorithm Optional<String> validationResult = httpSignature.validate(env, clientDefinition, inboundRequiredHeaders.headers(env.method(), env.headers())); if (validationResult.isPresent()) { return AuthenticationResponse.failed(validationResult.get()); } Principal principal = Principal.builder() .name(clientDefinition.principalName()) .addAttribute(ATTRIB_NAME_KEY_ID, clientDefinition.keyId()) .build(); Subject subject = Subject.builder() .principal(principal) .build(); if (clientDefinition.subjectType() == SubjectType.USER) { return AuthenticationResponse.success(subject); } else { return AuthenticationResponse.successService(subject); } }
/** * Find target for current security request. * Example of implementation * of {@link OutboundSecurityProvider#isOutboundSupported(ProviderRequest, SecurityEnvironment, EndpointConfig)}: * {@code * return (null != outboundTargets) && outboundTargets.findTarget(request).isPresent(); * } * * @param env request we are processing * @return TargetConfig wrapped in {@link Optional} valid for the request */ public Optional<OutboundTarget> findTarget(SecurityEnvironment env) { String transport = env.transport(); String host = env.targetUri().getHost(); String path = env.path().orElse(null); for (OutboundTarget outboundTarget : targets) { if (outboundTarget.matches(transport, host, path)) { return Optional.of(outboundTarget); } } return Optional.empty(); }
/** * Create a new instance of security environment with all default values. * * @return environment instance */ public static SecurityEnvironment create() { return builder().build(); }
private AuthenticationResponse challenge(SecurityEnvironment env, String description) { return AuthenticationResponse.builder() .responseHeader("WWW-Authenticate", "Signature realm=\"" + realm + ",headers=\"" + headersForMethod(env.method()) + "\"") .status(SecurityResponse.SecurityStatus.FAILURE) .statusCode(401) .description(description) .build(); }
@Override protected AuthenticationResponse syncAuthenticate(ProviderRequest providerRequest) { Map<String, List<String>> headers = providerRequest.env().headers(); List<String> authorizationHeader = headers.get(HEADER_AUTHENTICATION); if (null == authorizationHeader) { return fail("No " + HEADER_AUTHENTICATION + " header"); } return authorizationHeader.stream() .filter(header -> header.toLowerCase().startsWith(DIGEST_PREFIX)) .findFirst() .map(value -> validateDigestAuth(value, providerRequest.env())) .orElseGet(() -> fail("Authorization header does not contain digest authentication: " + authorizationHeader)); }
void extractQueryParams(SecurityContext securityContext, ServerRequest req) { Map<String, List<String>> headers = new HashMap<>(); queryParamHandlers.forEach(handler -> handler.extract(req, headers)); //the following line is not possible, as headers are read //only in web server, must explicitly send them with security requests //headers.forEach(req.headers()::put); // update environment in context with the found headers securityContext.env(securityContext.env().derive() .headers(headers) .build()); }
@Override public SecurityContext build() { if (null == env) { env = SecurityEnvironment.builder(serverTime).build(); } if (null == ec) { ec = EndpointConfig.builder().build(); } return new SecurityContextImpl(this); }
private OutboundSecurityResponse outboundSecurity(ProviderRequest providerRequest, SecurityEnvironment outboundEnv, EndpointConfig outboundEndpointConfig, TokenCredential token) { if (!token.getIssuer().map(issuer -> issuer.endsWith(".google.com")).orElse(false)) { // not our token :( return OutboundSecurityResponse.abstain(); } Map<String, List<String>> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); headers.putAll(outboundEnv.headers()); tokenHandler.header(headers, token.token()); return OutboundSecurityResponse.withHeaders(headers); }
SecurityEnvironment.Builder outboundEnv = context.env().derive(); outboundEnv.method(requestContext.getMethod()) .path(requestContext.getUri().getPath())
/** * Derive a new environment builder based on this environment. * * @return builder to build a new environment overriding only needed values with a new timestamp */ public Builder derive() { return builder(timeProvider) .attributes(properties) .targetUri(targetUri) .method(method) .transport(transport) .path(path.orElse(null)) .headers(headers); }
private AuthenticationResponse authorizeHeader(SecurityEnvironment env) { List<String> authorization = env.headers().get("Authorization"); AuthenticationResponse response = null; // attempt to validate each authorization, first one that succeeds will finish processing and return for (String authorizationValue : authorization) { if (authorizationValue.toLowerCase().startsWith("signature ")) { response = signatureHeader(CollectionsHelper.listOf(authorizationValue.substring("singature ".length())), env); if (response.status().isSuccess()) { // that was a good header, let's return the response return response; } } } // we have reached the end - all headers validated, none fit, fail or abstain if (optional) { return AuthenticationResponse.abstain(); } // challenge return challenge(env, (null == response) ? "No Signature authorization header" : response.description().orElse("Unknown problem")); }
void extractQueryParams(SecurityContext securityContext, ServerRequest req) { Map<String, List<String>> headers = new HashMap<>(); queryParamHandlers.forEach(handler -> handler.extract(req, headers)); //the following line is not possible, as headers are read //only in web server, must explicitly send them with security requests //headers.forEach(req.headers()::put); // update environment in context with the found headers securityContext.setEnv(securityContext.getEnv().derive() .headers(headers) .build()); }