use of org.hl7.fhir.r5.elementmodel.SHCParser.JWT in project org.hl7.fhir.core by hapifhir.
the class SHCParser method parse.
public List<NamedElement> parse(InputStream stream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
List<NamedElement> res = new ArrayList<>();
String src = TextFile.streamToString(stream).trim();
List<String> list = new ArrayList<>();
String pfx = null;
if (src.startsWith("{")) {
JsonObject json = JsonTrackingParser.parseJson(src);
if (checkProperty(json, "$", "verifiableCredential", true, "Array")) {
pfx = "verifiableCredential";
JsonArray arr = json.getAsJsonArray("verifiableCredential");
int i = 0;
for (JsonElement e : arr) {
if (!(e instanceof JsonPrimitive)) {
logError(line(e), col(e), "$.verifiableCredential[" + i + "]", IssueType.STRUCTURE, "Wrong Property verifiableCredential in JSON Payload. Expected : String but found " + JSONUtil.type(e), IssueSeverity.ERROR);
} else {
list.add(e.getAsString());
}
i++;
}
} else {
return res;
}
} else {
list.add(src);
}
int c = 0;
for (String ssrc : list) {
String prefix = pfx == null ? "" : pfx + "[" + Integer.toString(c) + "].";
c++;
JWT jwt = null;
try {
jwt = decodeJWT(ssrc);
} catch (Exception e) {
logError(1, 1, prefix + "JWT", IssueType.INVALID, "Unable to decode JWT token", IssueSeverity.ERROR);
return res;
}
map = jwt.map;
checkNamedProperties(jwt.getPayload(), prefix + "payload", "iss", "nbf", "vc");
checkProperty(jwt.getPayload(), prefix + "payload", "iss", true, "String");
logError(1, 1, prefix + "JWT", IssueType.INFORMATIONAL, "The FHIR Validator does not check the JWT signature " + "(see https://demo-portals.smarthealth.cards/VerifierPortal.html or https://github.com/smart-on-fhir/health-cards-dev-tools) (Issuer = '" + jwt.getPayload().get("iss").getAsString() + "')", IssueSeverity.INFORMATION);
checkProperty(jwt.getPayload(), prefix + "payload", "nbf", true, "Number");
JsonObject vc = jwt.getPayload().getAsJsonObject("vc");
if (vc == null) {
logError(1, 1, "JWT", IssueType.STRUCTURE, "Unable to find property 'vc' in the payload", IssueSeverity.ERROR);
return res;
}
String path = prefix + "payload.vc";
checkNamedProperties(vc, path, "type", "credentialSubject");
if (!checkProperty(vc, path, "type", true, "Array")) {
return res;
}
JsonArray type = vc.getAsJsonArray("type");
int i = 0;
for (JsonElement e : type) {
if (!(e instanceof JsonPrimitive)) {
logError(line(e), col(e), path + ".type[" + i + "]", IssueType.STRUCTURE, "Wrong Property Type in JSON Payload. Expected : String but found " + JSONUtil.type(e), IssueSeverity.ERROR);
} else {
types.add(e.getAsString());
}
i++;
}
if (!types.contains("https://smarthealth.cards#health-card")) {
logError(line(vc), col(vc), path, IssueType.STRUCTURE, "Card does not claim to be of type https://smarthealth.cards#health-card, cannot validate", IssueSeverity.ERROR);
return res;
}
if (!checkProperty(vc, path, "credentialSubject", true, "Object")) {
return res;
}
JsonObject cs = vc.getAsJsonObject("credentialSubject");
path = path + ".credentialSubject";
if (!checkProperty(cs, path, "fhirVersion", true, "String")) {
return res;
}
JsonElement fv = cs.get("fhirVersion");
if (!VersionUtilities.versionsCompatible(context.getVersion(), fv.getAsString())) {
logError(line(fv), col(fv), path + ".fhirVersion", IssueType.STRUCTURE, "Card claims to be of version " + fv.getAsString() + ", cannot be validated against version " + context.getVersion(), IssueSeverity.ERROR);
return res;
}
if (!checkProperty(cs, path, "fhirBundle", true, "Object")) {
return res;
}
// ok. all checks passed, we can now validate the bundle
Element e = jsonParser.parse(cs.getAsJsonObject("fhirBundle"), map);
if (e != null) {
res.add(new NamedElement(path, e));
}
}
return res;
}
use of org.hl7.fhir.r5.elementmodel.SHCParser.JWT in project fhir-bridge by ehrbase.
the class SmartOnFhirAuthorizationInterceptor method buildRuleList.
@Override
public List<IAuthRule> buildRuleList(RequestDetails theRequestDetails) {
List<IAuthRule> rules = new ArrayList<>();
// allow unconditional access to metadata requests
if (theRequestDetails.getRestOperationType() == RestOperationTypeEnum.METADATA) {
return new RuleBuilder().allowAll("SOF_allow_all").build();
}
Jwt jwt = ((JwtAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getToken();
// callers would just get a 401
if (jwt != null) {
List<String> scopes = Arrays.asList(jwt.getClaimAsString(SCOPE_CLAIM).split(" "));
if (scopes.contains(SOF_SCOPE)) {
List<String> systemScopes = scopes.stream().filter(s -> s.startsWith(SYSTEM_SCOPE)).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(systemScopes)) {
systemScopes.forEach(systemScope -> rules.addAll(buildSmartSystemRules(systemScope)));
rules.addAll(new RuleBuilder().denyAll("rule_deny_resource_if_no_appropriate_scope").build());
} else {
String smartOnFhirPatientId = jwt.getClaim(PATIENT_CLAIM);
if (StringUtils.isNotEmpty(smartOnFhirPatientId)) {
addSmartOFPatientRules(smartOnFhirPatientId, rules);
addSmartOFWildcardAccess(smartOnFhirPatientId, rules, Condition.class);
rules.addAll(new RuleBuilder().denyAll("rule_deny_resource_if_no_SOF_patId_claim").build());
}
}
} else {
// non smart on fhir logic
rules.addAll(new RuleBuilder().allowAll("allow_all_operations_for_all_resources").build());
}
}
return rules;
}
use of org.hl7.fhir.r5.elementmodel.SHCParser.JWT in project CRD by HL7-DaVinci.
the class JwtAuthorizationFilter method doFilterInternal.
@Override
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
String requestStr;
try {
ObjectMapper mapper = new ObjectMapper();
ObjectWriter w = mapper.writer();
requestStr = w.writeValueAsString(req);
} catch (Exception e) {
logger.error("failed to write request json: " + e.getMessage());
requestStr = "{\"error\": \"Authorization failed, request rejected\"}";
}
RequestLog requestLog = new RequestLog(requestStr.getBytes(), new Date().getTime());
String header = req.getHeader("Authorization");
if (header == null || !header.startsWith("Bearer")) {
requestService.create(requestLog);
logger.warn("JWT authorization failed - no bearer auth token present");
chain.doFilter(req, res);
return;
}
logger.info("Bearer auth token recieved");
UsernamePasswordAuthenticationToken authentication = getAuthentication(req);
SecurityContextHolder.getContext().setAuthentication(authentication);
if (authentication == null) {
requestService.create(requestLog);
}
chain.doFilter(req, res);
}
use of org.hl7.fhir.r5.elementmodel.SHCParser.JWT in project dpc-app by CMSgov.
the class PractitionerResourceTest method ensurePractitionersExist.
@Test
void ensurePractitionersExist() throws IOException, URISyntaxException, GeneralSecurityException {
final IParser parser = ctx.newJsonParser();
final IGenericClient attrClient = APITestHelpers.buildAttributionClient(ctx);
IGenericClient client = APIAuthHelpers.buildAuthenticatedClient(ctx, getBaseURL(), ORGANIZATION_TOKEN, PUBLIC_KEY_ID, PRIVATE_KEY);
APITestHelpers.setupPractitionerTest(client, parser);
// Find everything attributed
final Bundle practitioners = client.search().forResource(Practitioner.class).returnBundle(Bundle.class).encodedJson().execute();
assertEquals(4, practitioners.getTotal(), "Should have all the providers");
final Bundle specificSearch = client.search().forResource(Practitioner.class).where(Practitioner.IDENTIFIER.exactly().code("1232131239")).returnBundle(Bundle.class).encodedJson().execute();
assertEquals(1, specificSearch.getTotal(), "Should have a specific provider");
// Fetch the provider directly
final Practitioner foundProvider = (Practitioner) specificSearch.getEntryFirstRep().getResource();
final IReadExecutable<Practitioner> clientQuery = client.read().resource(Practitioner.class).withId(foundProvider.getIdElement()).encodedJson();
final Practitioner queriedProvider = clientQuery.execute();
assertTrue(foundProvider.equalsDeep(queriedProvider), "Search and GET should be identical");
// Try to delete the practitioner
client.delete().resourceById(queriedProvider.getIdElement()).encodedJson().execute();
// Try again, should be not found
assertThrows(AuthenticationException.class, clientQuery::execute, "Should not have practitioner");
// Create a new org and make sure it has no providers
final String m2 = FHIRHelpers.registerOrganization(attrClient, parser, OTHER_ORG_ID, "1112111111", getAdminURL());
// Submit a new public key to use for JWT flow
final String keyLabel = "new-key";
final Pair<UUID, PrivateKey> uuidPrivateKeyPair = APIAuthHelpers.generateAndUploadKey(keyLabel, OTHER_ORG_ID, GOLDEN_MACAROON, getBaseURL());
// Update the authenticated client to use the new organization
client = APIAuthHelpers.buildAuthenticatedClient(ctx, getBaseURL(), m2, uuidPrivateKeyPair.getLeft(), uuidPrivateKeyPair.getRight());
final Bundle otherPractitioners = client.search().forResource(Practitioner.class).returnBundle(Bundle.class).encodedJson().execute();
assertEquals(0, otherPractitioners.getTotal(), "Should not have any practitioners");
// Try to look for one of the other practitioners
final Bundle otherSpecificSearch = client.search().forResource(Practitioner.class).where(Practitioner.IDENTIFIER.exactly().identifier(foundProvider.getIdentifierFirstRep().getValue())).returnBundle(Bundle.class).encodedJson().execute();
assertEquals(0, otherSpecificSearch.getTotal(), "Should not have a specific provider");
// Try to search for our fund provider
}
use of org.hl7.fhir.r5.elementmodel.SHCParser.JWT in project drug-formulary-ri by HL7-DaVinci.
the class PatientAuthorizationInterceptor method buildRuleList.
@Override
public List<IAuthRule> buildRuleList(RequestDetails theRequestDetails) {
String authHeader = theRequestDetails.getHeader("Authorization");
if (authHeader != null) {
// Retrieve the JWT token from the Authorization header
Pattern pattern = Pattern.compile("Bearer (.*)");
Matcher matcher = pattern.matcher(authHeader);
if (matcher.find() && matcher.groupCount() == 1) {
String token = matcher.group(1);
logger.fine("AuthorizationInterceptor::Token retrieved is " + token);
String adminToken = HapiProperties.getAdminToken();
if (adminToken != null && token.equals(adminToken)) {
logger.info("AuthorizationInterceptor::JWT token is admin token");
return adminAuthorizedRule();
}
try {
IIdType patientId = verify(token, theRequestDetails.getFhirServerBase());
if (patientId != null)
return authorizedRule(patientId);
} catch (SignatureVerificationException e) {
String msg = "Authorization failed: invalid signature";
throw new AuthenticationException(msg, e.getCause());
} catch (TokenExpiredException e) {
String msg = "Authorization failed: access token expired";
throw new AuthenticationException(msg, e.getCause());
} catch (Exception e) {
throw new AuthenticationException(e.getMessage(), e.getCause());
}
} else {
throw new AuthenticationException("Authorization header is not in the form 'Bearer <token>'");
}
}
return unauthorizedRule();
}
Aggregations