Search in sources :

Example 6 with JWT

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;
}
Also used : JsonPrimitive(com.google.gson.JsonPrimitive) JsonElement(com.google.gson.JsonElement) ArrayList(java.util.ArrayList) JsonObject(com.google.gson.JsonObject) DefinitionException(org.hl7.fhir.exceptions.DefinitionException) DataFormatException(java.util.zip.DataFormatException) IOException(java.io.IOException) FHIRException(org.hl7.fhir.exceptions.FHIRException) JsonArray(com.google.gson.JsonArray) JsonElement(com.google.gson.JsonElement)

Example 7 with JWT

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;
}
Also used : JwtAuthenticationToken(org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken) Arrays(java.util.Arrays) UrlType(org.hl7.fhir.r4.model.UrlType) Resource(org.hl7.fhir.r4.model.Resource) Condition(org.hl7.fhir.r4.model.Condition) Collectors(java.util.stream.Collectors) StringUtils(org.apache.commons.lang3.StringUtils) IdType(org.hl7.fhir.r4.model.IdType) ArrayList(java.util.ArrayList) Value(org.springframework.beans.factory.annotation.Value) RuleBuilder(ca.uhn.fhir.rest.server.interceptor.auth.RuleBuilder) List(java.util.List) RequestDetails(ca.uhn.fhir.rest.api.server.RequestDetails) CollectionUtils(org.apache.commons.collections.CollectionUtils) RestOperationTypeEnum(ca.uhn.fhir.rest.api.RestOperationTypeEnum) IBaseResource(org.hl7.fhir.instance.model.api.IBaseResource) IAuthRule(ca.uhn.fhir.rest.server.interceptor.auth.IAuthRule) AuthorizationInterceptor(ca.uhn.fhir.rest.server.interceptor.auth.AuthorizationInterceptor) SecurityContextHolder(org.springframework.security.core.context.SecurityContextHolder) Jwt(org.springframework.security.oauth2.jwt.Jwt) Collections(java.util.Collections) Patient(org.hl7.fhir.r4.model.Patient) JwtAuthenticationToken(org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken) IAuthRule(ca.uhn.fhir.rest.server.interceptor.auth.IAuthRule) Jwt(org.springframework.security.oauth2.jwt.Jwt) ArrayList(java.util.ArrayList) RuleBuilder(ca.uhn.fhir.rest.server.interceptor.auth.RuleBuilder)

Example 8 with JWT

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);
}
Also used : RequestLog(org.hl7.davinci.endpoint.database.RequestLog) ObjectWriter(com.fasterxml.jackson.databind.ObjectWriter) UsernamePasswordAuthenticationToken(org.springframework.security.authentication.UsernamePasswordAuthenticationToken) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) ServletException(javax.servlet.ServletException) IOException(java.io.IOException) Date(java.util.Date)

Example 9 with JWT

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
}
Also used : Practitioner(org.hl7.fhir.dstu3.model.Practitioner) PrivateKey(java.security.PrivateKey) IGenericClient(ca.uhn.fhir.rest.client.api.IGenericClient) Bundle(org.hl7.fhir.dstu3.model.Bundle) UUID(java.util.UUID) IParser(ca.uhn.fhir.parser.IParser) AbstractSecureApplicationTest(gov.cms.dpc.api.AbstractSecureApplicationTest) Test(org.junit.jupiter.api.Test)

Example 10 with JWT

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();
}
Also used : Pattern(java.util.regex.Pattern) TokenExpiredException(com.auth0.jwt.exceptions.TokenExpiredException) Matcher(java.util.regex.Matcher) AuthenticationException(ca.uhn.fhir.rest.server.exceptions.AuthenticationException) SignatureVerificationException(com.auth0.jwt.exceptions.SignatureVerificationException) AuthenticationException(ca.uhn.fhir.rest.server.exceptions.AuthenticationException) TokenExpiredException(com.auth0.jwt.exceptions.TokenExpiredException) SignatureVerificationException(com.auth0.jwt.exceptions.SignatureVerificationException) JWTVerificationException(com.auth0.jwt.exceptions.JWTVerificationException) IIdType(org.hl7.fhir.instance.model.api.IIdType)

Aggregations

IOException (java.io.IOException)4 FHIRException (org.hl7.fhir.exceptions.FHIRException)4 JsonObject (com.google.gson.JsonObject)3 ArrayList (java.util.ArrayList)3 JsonArray (com.google.gson.JsonArray)2 JsonElement (com.google.gson.JsonElement)2 JsonPrimitive (com.google.gson.JsonPrimitive)2 DataFormatException (java.util.zip.DataFormatException)2 DefinitionException (org.hl7.fhir.exceptions.DefinitionException)2 IIdType (org.hl7.fhir.instance.model.api.IIdType)2 IdType (org.hl7.fhir.r4.model.IdType)2 IParser (ca.uhn.fhir.parser.IParser)1 RestOperationTypeEnum (ca.uhn.fhir.rest.api.RestOperationTypeEnum)1 RequestDetails (ca.uhn.fhir.rest.api.server.RequestDetails)1 IGenericClient (ca.uhn.fhir.rest.client.api.IGenericClient)1 AuthenticationException (ca.uhn.fhir.rest.server.exceptions.AuthenticationException)1 AuthorizationInterceptor (ca.uhn.fhir.rest.server.interceptor.auth.AuthorizationInterceptor)1 IAuthRule (ca.uhn.fhir.rest.server.interceptor.auth.IAuthRule)1 RuleBuilder (ca.uhn.fhir.rest.server.interceptor.auth.RuleBuilder)1 JWTVerifier (com.auth0.jwt.JWTVerifier)1