use of io.helidon.security.SubjectType in project helidon by oracle.
the class HttpBasicAuthProvider method validateBasicAuth.
private AuthenticationResponse validateBasicAuth(String basicAuthHeader) {
String b64 = basicAuthHeader.substring(BASIC_PREFIX.length());
String usernameAndPassword;
try {
usernameAndPassword = new String(Base64.getDecoder().decode(b64), StandardCharsets.UTF_8);
} catch (IllegalArgumentException e) {
// not a base64 encoded string
return failOrAbstain("Basic authentication header with invalid content - not base64 encoded");
}
Matcher matcher = CREDENTIAL_PATTERN.matcher(usernameAndPassword);
if (!matcher.matches()) {
LOGGER.finest(() -> "Basic authentication header with invalid content: " + usernameAndPassword);
return failOrAbstain("Basic authentication header with invalid content");
}
final String username = matcher.group(1);
final char[] password = matcher.group(2).toCharArray();
Optional<SecureUserStore.User> foundUser = Optional.empty();
for (SecureUserStore userStore : userStores) {
foundUser = userStore.user(username);
if (foundUser.isPresent()) {
// find first user from stores
break;
}
}
return foundUser.map(user -> {
if (user.isPasswordValid(password)) {
if (subjectType == SubjectType.USER) {
return AuthenticationResponse.success(buildSubject(user, password));
}
return AuthenticationResponse.successService(buildSubject(user, password));
} else {
return invalidUser();
}
}).orElseGet(this::invalidUser);
}
use of io.helidon.security.SubjectType in project helidon by oracle.
the class HeaderAtnProvider method syncOutbound.
@Override
protected OutboundSecurityResponse syncOutbound(ProviderRequest providerRequest, SecurityEnvironment outboundEnv, EndpointConfig outboundEndpointConfig) {
Optional<Subject> toPropagate;
if (subjectType == SubjectType.USER) {
toPropagate = providerRequest.securityContext().user();
} else {
toPropagate = providerRequest.securityContext().service();
}
// find the target
var target = outboundConfig.findTargetCustomObject(outboundEnv, HeaderAtnOutboundConfig.class, HeaderAtnOutboundConfig::create, HeaderAtnOutboundConfig::create);
// we have no target, let's fall back to original behavior
if (target.isEmpty()) {
if (outboundTokenHandler != null) {
return toPropagate.map(Subject::principal).map(Principal::id).map(id -> respond(outboundEnv, outboundTokenHandler, id)).orElseGet(OutboundSecurityResponse::abstain);
}
return OutboundSecurityResponse.abstain();
}
// we found a target
HeaderAtnOutboundConfig outboundConfig = target.get();
TokenHandler tokenHandler = outboundConfig.tokenHandler().orElse(defaultOutboundTokenHandler);
return outboundConfig.explicitUser().or(() -> toPropagate.map(Subject::principal).map(Principal::id)).map(id -> respond(outboundEnv, tokenHandler, id)).orElseGet(OutboundSecurityResponse::abstain);
}
use of io.helidon.security.SubjectType in project helidon by oracle.
the class HttpDigestAuthProvider method validateDigestAuth.
private AuthenticationResponse validateDigestAuth(String headerValue, SecurityEnvironment env) {
DigestToken token;
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);
return failOrAbstain(e.getMessage());
}
// decrypt
byte[] bytes;
try {
bytes = Base64.getDecoder().decode(token.getNonce());
} catch (IllegalArgumentException e) {
LOGGER.log(Level.FINEST, "Failed to base64 decode nonce", e);
// not base 64
return failOrAbstain("Nonce must be base64 encoded");
}
if (bytes.length < 17) {
return failOrAbstain("Invalid nonce length");
}
byte[] salt = new byte[SALT_LENGTH];
byte[] aesNonce = new byte[AES_NONCE_LENGTH];
byte[] encryptedBytes = new byte[bytes.length - SALT_LENGTH - AES_NONCE_LENGTH];
System.arraycopy(bytes, 0, salt, 0, salt.length);
System.arraycopy(bytes, SALT_LENGTH, aesNonce, 0, aesNonce.length);
System.arraycopy(bytes, SALT_LENGTH + AES_NONCE_LENGTH, encryptedBytes, 0, encryptedBytes.length);
Cipher cipher = HttpAuthUtil.cipher(digestServerSecret, salt, aesNonce, Cipher.DECRYPT_MODE);
try {
byte[] timestampBytes = cipher.doFinal(encryptedBytes);
long nonceTimestamp = HttpAuthUtil.toLong(timestampBytes, 0, timestampBytes.length);
// validate nonce
if ((System.currentTimeMillis() - nonceTimestamp) > digestNonceTimeoutMillis) {
return failOrAbstain("Nonce timeout");
}
} catch (Exception e) {
LOGGER.log(Level.FINEST, "Failed to validate nonce", e);
return failOrAbstain("Invalid nonce value");
}
// validate realm
if (!realm.equals(token.getRealm())) {
return failOrAbstain("Invalid realm");
}
return userStore.user(token.getUsername()).map(user -> {
if (token.validateLogin(user)) {
// yay, correct user and password!!!
if (subjectType == SubjectType.USER) {
return AuthenticationResponse.success(buildSubject(user));
} else {
return AuthenticationResponse.successService(buildSubject(user));
}
} else {
return failOrAbstain("Invalid username or password");
}
}).orElse(failOrAbstain("Invalid username or password"));
}
Aggregations