@Override protected AuthenticationResponse syncAuthenticate(ProviderRequest providerRequest) { if (!authenticate) { return AuthenticationResponse.abstain(); } List<LoginConfig> loginConfigs = providerRequest.endpointConfig() .combineAnnotations(LoginConfig.class, EndpointConfig.AnnotationScope.APPLICATION); try { return loginConfigs.stream() .filter(JwtAuthAnnotationAnalyzer::isMpJwt) .findFirst() .map(loginConfig -> authenticate(providerRequest, loginConfig)) .orElseGet(AuthenticationResponse::abstain); } catch (java.lang.SecurityException e) { return AuthenticationResponse.failed("Failed to process authentication header", e); } }
@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)); }
private AuthenticationResponse signatureHeader(List<String> signatures, SecurityEnvironment env) { /* Signature keyId="rsa-key-1",algorithm="rsa-sha256", headers="(request-target) host date digest content-length", signature="Base64(RSA-SHA256(signing string))" */ String lastError = signatures.isEmpty() ? "No signature values for Signature header" : null; for (String signature : signatures) { HttpSignature httpSignature = HttpSignature.fromHeader(signature); Optional<String> validate = httpSignature.validate(); if (validate.isPresent()) { lastError = validate.get(); } else { //this is a valid signature object, let's validate against key InboundClientDefinition clientDefinition = inboundKeys.get(httpSignature.getKeyId()); if (null == clientDefinition) { lastError = "Client definition for client with key " + httpSignature.getKeyId() + " not found"; continue; } //now we have a signature with a valid keyId - if validation fails, we fail return validateSignature(env, httpSignature, clientDefinition); } } if (optional) { return AuthenticationResponse.abstain(); } else { return AuthenticationResponse.failed(lastError); } }
@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"); } }); }
return ((AsyncAtnException) cause).response; return AuthenticationResponse.failed("Failed processing: " + throwable.getMessage(), throwable); }).thenApply(authenticationResponse -> { if (authenticationResponse.status() == SecurityResponse.SecurityStatus.ABSTAIN) {
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); } }
.addProvider(AbacProvider.create()) .addAuthenticationProvider(providerRequest -> CompletableFuture .completedFuture(AuthenticationResponse.failed("No provider configured"))) .build();
@Override protected AuthenticationResponse syncAuthenticate(ProviderRequest providerRequest) { if (!authenticate) { return AuthenticationResponse.abstain(); } List<LoginConfig> loginConfigs = providerRequest.endpointConfig() .combineAnnotations(LoginConfig.class, EndpointConfig.AnnotationScope.APPLICATION); try { return loginConfigs.stream() .filter(JwtAuthAnnotationAnalyzer::isMpJwt) .findFirst() .map(loginConfig -> authenticate(providerRequest, loginConfig)) .orElseGet(AuthenticationResponse::abstain); } catch (java.lang.SecurityException e) { return AuthenticationResponse.failed("Failed to process authentication header", e); } }
@Override protected AuthenticationResponse syncAuthenticate(ProviderRequest providerRequest) { if (!authenticate) { return AuthenticationResponse.abstain(); } Optional<String> username = atnTokenHandler.extractToken(providerRequest.getEnv().getHeaders()); 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) { 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"); } }); }
.addProvider(AbacProvider.create()) .addAuthenticationProvider(providerRequest -> CompletableFuture .completedFuture(AuthenticationResponse.failed("No provider configured"))) .build();