use of com.auth0.android.jwt.Claim in project auth0-java by auth0.
the class IdTokenVerifier method verify.
/**
* Verifies a provided ID Token follows the <a href="https://openid.net/specs/openid-connect-core-1_0-final.html#IDTokenValidation">OIDC specification.</a>
*
* @param token the ID Token to verify. Must not be null or empty.
* @param nonce the nonce expected on the ID token, which must match the nonce specified on the authorization request.
* If null, no validation of the nonce will occur.
* @param maxAuthenticationAge The maximum authentication age allowed, which specifies the allowable elapsed time in seconds
* since the last time the end-user was actively authenticated. This must match the specified
* {@code max_age} parameter specified on the authorization request. If null, no validation
* of the {@code auth_time} claim will occur.
* @throws IdTokenValidationException if:
* <ul>
* <li>The ID token is null</li>
* <li>The ID token's signing algorithm is not supported</li>
* <li>The ID token's signature is invalid</li>
* <li>Any of the ID token's claims are invalid</li>
* </ul>
* @see IdTokenVerifier#verify(String)
* @see IdTokenVerifier#verify(String, String)
*/
public void verify(String token, String nonce, Integer maxAuthenticationAge) throws IdTokenValidationException {
if (isEmpty(token)) {
throw new IdTokenValidationException("ID token is required but missing");
}
DecodedJWT decoded = this.signatureVerifier.verifySignature(token);
if (isEmpty(decoded.getIssuer())) {
throw new IdTokenValidationException("Issuer (iss) claim must be a string present in the ID token");
}
if (!decoded.getIssuer().equals(this.issuer)) {
throw new IdTokenValidationException(String.format("Issuer (iss) claim mismatch in the ID token, expected \"%s\", found \"%s\"", this.issuer, decoded.getIssuer()));
}
if (isEmpty(decoded.getSubject())) {
throw new IdTokenValidationException("Subject (sub) claim must be a string present in the ID token");
}
final List<String> audience = decoded.getAudience();
if (audience == null) {
throw new IdTokenValidationException("Audience (aud) claim must be a string or array of strings present in the ID token");
}
if (!audience.contains(this.audience)) {
throw new IdTokenValidationException(String.format("Audience (aud) claim mismatch in the ID token; expected \"%s\" but found \"%s\"", this.audience, decoded.getAudience()));
}
// Org verification
if (this.organization != null) {
String orgClaim = decoded.getClaim("org_id").asString();
if (isEmpty(orgClaim)) {
throw new IdTokenValidationException("Organization Id (org_id) claim must be a string present in the ID token");
}
if (!this.organization.equals(orgClaim)) {
throw new IdTokenValidationException(String.format("Organization (org_id) claim mismatch in the ID token; expected \"%s\" but found \"%s\"", this.organization, orgClaim));
}
}
final Calendar cal = Calendar.getInstance();
final Date now = this.clock != null ? this.clock : cal.getTime();
final int clockSkew = this.leeway != null ? this.leeway : DEFAULT_LEEWAY;
if (decoded.getExpiresAt() == null) {
throw new IdTokenValidationException("Expiration Time (exp) claim must be a number present in the ID token");
}
cal.setTime(decoded.getExpiresAt());
cal.add(Calendar.SECOND, clockSkew);
Date expDate = cal.getTime();
if (now.after(expDate)) {
throw new IdTokenValidationException(String.format("Expiration Time (exp) claim error in the ID token; current time (%d) is after expiration time (%d)", now.getTime() / 1000, expDate.getTime() / 1000));
}
if (decoded.getIssuedAt() == null) {
throw new IdTokenValidationException("Issued At (iat) claim must be a number present in the ID token");
}
cal.setTime(decoded.getIssuedAt());
cal.add(Calendar.SECOND, -1 * clockSkew);
if (nonce != null) {
String nonceClaim = decoded.getClaim(NONCE_CLAIM).asString();
if (isEmpty(nonceClaim)) {
throw new IdTokenValidationException("Nonce (nonce) claim must be a string present in the ID token");
}
if (!nonce.equals(nonceClaim)) {
throw new IdTokenValidationException(String.format("Nonce (nonce) claim mismatch in the ID token; expected \"%s\", found \"%s\"", nonce, nonceClaim));
}
}
if (audience.size() > 1) {
String azpClaim = decoded.getClaim(AZP_CLAIM).asString();
if (isEmpty(azpClaim)) {
throw new IdTokenValidationException("Authorized Party (azp) claim must be a string present in the ID token when Audience (aud) claim has multiple values");
}
if (!this.audience.equals(azpClaim)) {
throw new IdTokenValidationException(String.format("Authorized Party (azp) claim mismatch in the ID token; expected \"%s\", found \"%s\"", this.audience, azpClaim));
}
}
if (maxAuthenticationAge != null) {
Date authTime = decoded.getClaim(AUTH_TIME_CLAIM).asDate();
if (authTime == null) {
throw new IdTokenValidationException("Authentication Time (auth_time) claim must be a number present in the ID token when Max Age (max_age) is specified");
}
cal.setTime(authTime);
cal.add(Calendar.SECOND, maxAuthenticationAge);
cal.add(Calendar.SECOND, clockSkew);
Date authTimeDate = cal.getTime();
if (now.after(authTimeDate)) {
throw new IdTokenValidationException(String.format("Authentication Time (auth_time) claim in the ID token indicates that too much time has passed since the last end-user authentication. Current time (%d) is after last auth at (%d)", now.getTime() / 1000, authTimeDate.getTime() / 1000));
}
}
}
use of com.auth0.android.jwt.Claim in project restheart by SoftInstigate.
the class JwtAuthenticationMechanism method authenticate.
@Override
public AuthenticationMechanism.AuthenticationMechanismOutcome authenticate(HttpServerExchange hse, SecurityContext sc) {
try {
String token = getToken(hse);
if (token != null) {
if (base64Encoded) {
token = StringUtils.newStringUtf8(Base64.getUrlDecoder().decode(token));
}
DecodedJWT verifiedJwt = jwtVerifier.verify(token);
String subject = verifiedJwt.getClaim(usernameClaim).asString();
if (subject == null) {
LOGGER.debug("username not specified with claim {}", usernameClaim);
sc.authenticationFailed("JwtAuthenticationManager", "username not specified");
return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
}
Set<String> actualRoles = new LinkedHashSet<>();
if (rolesClaim != null) {
Claim _roles = verifiedJwt.getClaim(rolesClaim);
if (_roles != null && !_roles.isNull()) {
try {
String[] __roles = _roles.asArray(String.class);
if (__roles != null) {
for (String role : __roles) {
actualRoles.add(role);
}
} else {
LOGGER.debug("roles is not an array: {}", _roles.asString());
return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
}
} catch (JWTDecodeException ex) {
LOGGER.warn("Jwt cannot get roles from claim {}, " + "extepected an array of strings: {}", rolesClaim, _roles.toString());
}
}
} else if (this.fixedRoles != null) {
actualRoles.addAll(this.fixedRoles);
}
if (this.extraJwtVerifier != null) {
this.extraJwtVerifier.accept(verifiedJwt);
}
var jwtPayload = new String(Base64.getUrlDecoder().decode(verifiedJwt.getPayload()), Charset.forName("UTF-8"));
JwtAccount account = new JwtAccount(subject, actualRoles, jwtPayload);
sc.authenticationComplete(account, "JwtAuthenticationManager", false);
Request.of(hse).addXForwardedHeader("Jwt-Payload", jwtPayload);
return AuthenticationMechanismOutcome.AUTHENTICATED;
}
} catch (JWTVerificationException ex) {
LOGGER.debug("Jwt not verified: {}", ex.getMessage());
return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
}
return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}
use of com.auth0.android.jwt.Claim in project ARLAS-server by gisaia.
the class AuthorizationFilter method filter.
@Override
public void filter(ContainerRequestContext ctx) {
Transaction transaction = ElasticApm.currentTransaction();
boolean isPublic = ctx.getUriInfo().getPath().concat(":").concat(ctx.getMethod()).matches(authConf.getPublicRegex());
String header = ctx.getHeaderString(HttpHeaders.AUTHORIZATION);
if (header == null || (header != null && !header.toLowerCase().startsWith("bearer "))) {
if (isPublic || ctx.getMethod() == "OPTIONS") {
return;
} else {
ctx.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
}
}
try {
// header presence and format already checked before in AuthenticationFilter
DecodedJWT jwt = jwtVerifier.verify(header.substring(7));
// remove it in case it's been set manually
ctx.getHeaders().remove(authConf.headerUser);
String userId = jwt.getSubject();
if (!StringUtil.isNullOrEmpty(userId)) {
ctx.getHeaders().putSingle(authConf.headerUser, userId);
transaction.setUser(userId, "", "");
}
// remove it in case it's been set manually
ctx.getHeaders().remove(authConf.headerGroup);
Claim jwtClaimRoles = jwt.getClaim(authConf.claimRoles);
if (!jwtClaimRoles.isNull()) {
List<String> groups = jwtClaimRoles.asList(String.class).stream().filter(r -> r.toLowerCase().startsWith("group")).collect(Collectors.toList());
ctx.setProperty("groups", groups);
ctx.getHeaders().put(authConf.headerGroup, groups);
}
Claim jwtClaimPermissions = jwt.getClaim(authConf.claimPermissions);
if (!jwtClaimPermissions.isNull()) {
ArlasClaims arlasClaims = new ArlasClaims(jwtClaimPermissions.asList(String.class));
ctx.setProperty("claims", arlasClaims);
if (arlasClaims.isAllowed(ctx.getMethod(), ctx.getUriInfo().getPath())) {
arlasClaims.injectHeaders(ctx.getHeaders(), transaction);
return;
}
}
if (isPublic) {
return;
} else {
ctx.abortWith(Response.status(Response.Status.FORBIDDEN).build());
}
} catch (JWTVerificationException e) {
LOGGER.warn("JWT verification failed.", e);
if (!isPublic) {
ctx.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
}
return;
}
ctx.abortWith(Response.status(Response.Status.FORBIDDEN).build());
}
use of com.auth0.android.jwt.Claim in project drug-formulary-ri by HL7-DaVinci.
the class PatientAuthorizationInterceptor method verify.
/**
* Helper method to verify and decode the access token
*
* @param token - the access token
* @param fhirBaseUrl - the base url of this FHIR server
* @return the base interface Patient ID datatype if the jwt token is verified
* and contains a patient ID in it claim, otherwise null.
* @throws SignatureVerificationException
* @throws TokenExpiredException
* @throws JWTVerificationException
*/
private IIdType verify(String token, String fhirBaseUrl) throws SignatureVerificationException, TokenExpiredException, JWTVerificationException {
Algorithm algorithm = Algorithm.RSA256(OauthEndpointController.getPublicKey(), null);
logger.fine("Verifying JWT token iss and aud is " + fhirBaseUrl);
JWTVerifier verifier = JWT.require(algorithm).withIssuer(fhirBaseUrl).withAudience(fhirBaseUrl).build();
DecodedJWT jwt = verifier.verify(token);
String patientId = jwt.getClaim("patient_id").asString();
if (patientId != null)
return new IdType("Patient", patientId);
return null;
}
use of com.auth0.android.jwt.Claim in project drug-formulary-ri by HL7-DaVinci.
the class AuthUtils method authCodeIsValid.
/**
* Verify the authorization code provided in the POST request's claim to /token
* path
*
* @param code - the authorization code provided in the request
* @param baseUrl - this server base URL
* @param redirectURI - the requestor/client redirect URI provided in the POST
* request
* @param clientId - the client ID retrieved from the request's Authorization
* Header
* @return patientId if the authorization code is valid, otherwise null
*/
public static String authCodeIsValid(String code, String baseUrl, String redirectURI, String clientId) {
String patientId = null;
try {
Algorithm algorithm = Algorithm.RSA256(OauthEndpointController.getPublicKey(), null);
JWTVerifier verifier = JWT.require(algorithm).withIssuer(baseUrl).withAudience(baseUrl).withClaim(REDIRECT_URI_KEY, redirectURI).withClaim(CLIENT_ID_KEY, clientId).build();
DecodedJWT jwt = verifier.verify(code);
String username = jwt.getClaim("username").asString();
User user = User.getUser(username);
patientId = user != null ? user.getPatientId() : null;
} catch (SignatureVerificationException | InvalidClaimException e) {
logger.log(Level.SEVERE, "TokenEndpoint::Authorization code is invalid: Signature invalid or claim value invalid", e);
} catch (AlgorithmMismatchException e) {
logger.log(Level.SEVERE, "TokenEndpoint::Authorization code is invalid: Algorithm mismatch", e);
} catch (TokenExpiredException e) {
logger.log(Level.SEVERE, "TokenEndpoint::Authorization code is invalid: Token expired", e);
} catch (JWTVerificationException e) {
logger.log(Level.SEVERE, "TokenEndpoint::Authorization code is invalid: Please obtain a new code", e);
}
return patientId;
}
Aggregations