@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)); }
@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)); }
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); } }
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); }
String getSignedString(Map<String, List<String>> newHeaders, SecurityEnvironment env) { StringBuilder toSign = new StringBuilder(); Map<String, List<String>> requestHeaders = env.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")); }
@Override public CompletionStage<AuthenticationResponse> authenticate(ProviderRequest providerRequest) { Map<String, List<String>> headers = providerRequest.env().headers(); if ((headers.get("Signature") != null) && acceptHeaders.contains(HttpSignHeader.SIGNATURE)) { return CompletableFuture .supplyAsync(() -> signatureHeader(headers.get("Signature"), providerRequest.env()), providerRequest.securityContext().executorService()); } else if ((headers.get("Authorization") != null) && acceptHeaders.contains(HttpSignHeader.AUTHORIZATION)) { // TODO when authorization header in use and "authorization" is also a // required header to be signed, we must either fail or ignore, as we cannot sign ourselves return CompletableFuture .supplyAsync(() -> authorizeHeader(providerRequest.env()), providerRequest.securityContext().executorService()); } if (optional) { return CompletableFuture.completedFuture(AuthenticationResponse.abstain()); } return CompletableFuture .completedFuture(AuthenticationResponse.failed("Missing header. Accepted headers: " + acceptHeaders)); }
@Override protected AuthenticationResponse syncAuthenticate(ProviderRequest providerRequest) { Optional<String> maybeToken; try { maybeToken = tokenHandler.extractToken(providerRequest.env().headers()); } catch (Exception e) { return failInvalidRequest(e); } SecurityContext sContext = providerRequest.securityContext(); return maybeToken .map(token -> cachedResponse(token, sContext.tracer(), sContext.tracingSpan())) .orElseGet(this::failNoToken); }
@Override protected AuthenticationResponse syncAuthenticate(ProviderRequest providerRequest) { if (!authenticate) { return AuthenticationResponse.abstain(); } Optional<String> username = atnTokenHandler.extractToken(providerRequest.env().headers()); return username .map(Principal::create) .map(principal -> { if (subjectType == SubjectType.USER) { return AuthenticationResponse.success(principal); } else { return AuthenticationResponse.successService(principal); } }) .orElseGet(() -> { if (optional) { return AuthenticationResponse.abstain(); } else { return AuthenticationResponse.failed("Header not available or in a wrong format"); } } ); }
@Override protected AuthenticationResponse syncAuthenticate(ProviderRequest providerRequest) { /* 1. Get token from request - if available, validate it and continue 2. If not - Redirect to login page */ Optional<String> token = Optional.empty(); if (oidcConfig.useHeader()) { token = OptionalHelper.from(token) .or(() -> oidcConfig.headerHandler().extractToken(providerRequest.env().headers())) .asOptional(); } if (oidcConfig.useParam()) { token = OptionalHelper.from(token) .or(() -> paramHeaderHandler.extractToken(providerRequest.env().headers())) .asOptional(); } if (oidcConfig.useCookie()) { token = OptionalHelper.from(token) .or(() -> findCookie(providerRequest.env().headers())) .asOptional(); } if (token.isPresent()) { return validateToken(providerRequest, token.get()); } else { return errorResponse(providerRequest, Http.Status.UNAUTHORIZED_401, null, "Missing token"); } }
outboundDefinition.algorithm(), outboundDefinition.signedHeadersConfig() .headers(env.method(), env.headers()));
AuthenticationResponse authenticate(ProviderRequest providerRequest, LoginConfig loginConfig) { return atnTokenHandler.extractToken(providerRequest.env().headers()) .map(token -> { SignedJwt signedJwt = SignedJwt.parseToken(token); Errors errors = signedJwt.verifySignature(verifyKeys, defaultJwk); if (errors.isValid()) { Jwt jwt = signedJwt.getJwt(); // verify the audience is correct Errors validate = jwt.validate(expectedIssuer, expectedAudience); if (validate.isValid()) { return AuthenticationResponse.success(buildSubject(jwt, signedJwt)); } else { return AuthenticationResponse.failed("Audience is invalid or missing: " + expectedAudience); } } else { return AuthenticationResponse.failed(errors.toString()); } }).orElseGet(() -> { if (optional) { return AuthenticationResponse.abstain(); } else { return AuthenticationResponse.failed("Header not available or in a wrong format"); } }); }
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); } }
@Override protected AuthenticationResponse syncAuthenticate(ProviderRequest providerRequest) { if (!authenticate) { return AuthenticationResponse.abstain(); } return atnTokenHandler.extractToken(providerRequest.env().headers()) .map(token -> { SignedJwt signedJwt = SignedJwt.parseToken(token); Errors errors = signedJwt.verifySignature(verifyKeys); if (errors.isValid()) { Jwt jwt = signedJwt.getJwt(); // verify the audience is correct Errors validate = jwt.validate(null, expectedAudience); if (validate.isValid()) { return AuthenticationResponse.success(buildSubject(jwt, signedJwt)); } else { return AuthenticationResponse.failed("Audience is invalid or missing: " + expectedAudience); } } else { return AuthenticationResponse.failed(errors.toString()); } }).orElseGet(() -> { if (optional) { return AuthenticationResponse.abstain(); } else { return AuthenticationResponse.failed("Header not available or in a wrong format"); } }); }
@Override protected AuthenticationResponse syncAuthenticate(ProviderRequest providerRequest) { if (!authenticate) { return AuthenticationResponse.abstain(); } Optional<String> username = atnTokenHandler.extractToken(providerRequest.env().headers()); return username .map(Principal::create) .map(principal -> { if (subjectType == SubjectType.USER) { return AuthenticationResponse.success(principal); } else { return AuthenticationResponse.successService(principal); } }) .orElseGet(() -> { if (optional) { return AuthenticationResponse.abstain(); } else { return AuthenticationResponse.failed("Header not available or in a wrong format"); } } ); }
AuthenticationResponse authenticate(ProviderRequest providerRequest, LoginConfig loginConfig) { return atnTokenHandler.extractToken(providerRequest.env().headers()) .map(token -> { SignedJwt signedJwt = SignedJwt.parseToken(token); Errors errors = signedJwt.verifySignature(verifyKeys, defaultJwk); if (errors.isValid()) { Jwt jwt = signedJwt.getJwt(); // verify the audience is correct Errors validate = jwt.validate(expectedIssuer, expectedAudience); if (validate.isValid()) { return AuthenticationResponse.success(buildSubject(jwt, signedJwt)); } else { return AuthenticationResponse.failed("Audience is invalid or missing: " + expectedAudience); } } else { return AuthenticationResponse.failed(errors.toString()); } }).orElseGet(() -> { if (optional) { return AuthenticationResponse.abstain(); } else { return AuthenticationResponse.failed("Header not available or in a wrong format"); } }); }
@Override protected AuthenticationResponse syncAuthenticate(ProviderRequest providerRequest) { if (!authenticate) { return AuthenticationResponse.abstain(); } return atnTokenHandler.extractToken(providerRequest.env().headers()) .map(token -> { SignedJwt signedJwt = SignedJwt.parseToken(token); Errors errors = signedJwt.verifySignature(verifyKeys); if (errors.isValid()) { Jwt jwt = signedJwt.getJwt(); // verify the audience is correct Errors validate = jwt.validate(null, expectedAudience); if (validate.isValid()) { return AuthenticationResponse.success(buildSubject(jwt, signedJwt)); } else { return AuthenticationResponse.failed("Audience is invalid or missing: " + expectedAudience); } } else { return AuthenticationResponse.failed(errors.toString()); } }).orElseGet(() -> { if (optional) { return AuthenticationResponse.abstain(); } else { return AuthenticationResponse.failed("Header not available or in a wrong format"); } }); }