This wiki has undergone a migration to Confluence found Here
<meta name="googlebot" content="noindex">

Difference between revisions of "201709 Consumer Centered Data Exchange Implementation Notes for test.fhir.org"

From HL7Wiki
Jump to navigation Jump to search
 
(13 intermediate revisions by the same user not shown)
Line 1: Line 1:
= Acquiring the JWT =
+
= Using test.fhir.org as the target EHR =
  
you get the JWT (to use test.fhir.org as the target) by:
+
e.g information flows from another server to test.fhir.org
 +
 
 +
Sequence of steps:
 +
# get the test.fhir.org JWT
 +
# authorize the JWT on the other server
 +
# Ask test.fhir.org to start copying data
 +
# find out how copying data is going
 +
# stop copying data
 +
 
 +
== Acquiring test.fhir.org's JWT ==
 +
 
 +
you get the JWT by:
  
 
   GET http://test.fhir.org/r3/$jwt?source=[uri]
 
   GET http://test.fhir.org/r3/$jwt?source=[uri]
Line 9: Line 20:
 
this returns a 200 OK with a body content type of application/jwt:
 
this returns a 200 OK with a body content type of application/jwt:
  
   eyJhbGciIDogIlJTMjU2Iiwia2lkIiA6ICIvYXV0aF9rZXkiLCJ0eXAiIDogIkpXVCJ9.eyJleHAiIDogMTUwMTg2MzE3MCwiaWF0IiA6ICIxNTAxNzc2NzcwIiwiaXNzIiA6ICJsb2NhbC5maGlyLm9yZyIsInN1YiIgOiAibG9jYWwuZmhpci5vcmcifQ.RWhQyMf1Cr90kn1RtjV-BGAbi1lWobE0RQWTwYl_mBMcB8v4hpUzcjlay3miPRBrzxGYxhr0RPecv8zkk5KiGk_8VrVxqk21YGKjKoqXdi9fGkLuc4vw_sj_Nt6vDS3zdEyIYLMVELvu74Vemt2p16brQ-xKpJ-1PdUF8EVYI3n5r_b6xH6HcP9xgmSun38yDC-KbkfBYatdwZsVrnd2-VrOHBM-E8P44fu9-GQNyirvdD6rdpQQGtfcDyf4G940AJfW9WHUWLlWTyQ0uhYn1DD46Pc5wMqzHcja43u5O7r7g5oWxZ9Iiidq9tUV8UaGp_h2ejzdUds9uVA7Hd3VyVSBVUmIN-3oVH31-6o_MCKqeKOwB-Y9qFsN_8MTf77HS1xHXLeC4VPyKdk0rmb-v49b6_3DwI7SXLwYJu19kkqVWywHam-6_qaowB-8emdk-iE1QX9DXjna81CLGyFdsOPZ7kQEWlZrgsz7RmvLxrrJ0b8os8aqCW-3i7UDqUFIKXnvKwFPfsf7RMp_ruvxyyfIIcaI0T9RjZicME2-JBC3EoRTzAXkG9htX1KDe9vH3fcSTcjiCQ75gcGkKZWWDaN-6SV4itzoiFm0Re99E4mWmkQVj289y6jRAOercvioygyvUbgQ4rpLbZv1i2A5orx0Ze-6opc9Z1hGAQLcLn0
+
   eyJhbGciIDogIlJTMjU2Iiwia2lkIiA6ICIvYXV0aF9rZXkiLCJ0eXAiIDogIkpXVCJ9.eyJleHAiIDogMTUwMTkyOTA2OSwiaWF0IiA6ICIxNTAxODQyNjY5IiwiaXNzIiA6ICJ1cm46dXVpZDoxNDg2MzMyYi1mZTNiLTQ4M2EtYjlkNC1kNmQ4MWNjNWI3MmUiLCJzdWIiIDogImxvY2FsLmZoaXIub3JnIn0.FAeo0jK8yo5VtpmSiySzzzT3NwuMc1WVrgPUiVNH1srQVm5Qa7wJmh5j9RDL8BH52b0-Ek8tz7JLDF_BYHJ6qGJ2Yni1_MC31lp5_C64s55ZU5Bh2LCy3NlWP3UxgSLT42KDQqYuJ-ZQ_09zbor-Jo5Bv10qcXaQoqfha0ib-unrbJBfHVJgFEbvaR_fQwdP06hMhQMdr4MIluwQ0aVp1fckV_Uf4Wc9GhEtd58ZKSo2ce0YDo852AZIO00WXoE6bX6xHm5V1RTgjTQe-1ji4bwzkIajTViMSn6Ly3MfQdNoLxRQBmrtc22dTzZ_Mn_Y26pgPyF9NRGMuwyC--EAVHz5S1oXNAVcVI4--Tt14jiqXxomGbAVlly6fnk3_o8lWZ8AsKuivMK4QIy2Od58lYu086RbtQnSYtdRyr2rUik1NvOYh2MLZj8psjOnALiGWLF9aYKbQZx7tvaZ_ijFlFw0D3j43BE36oZ7ztcFuScEqLe-TK7yF7k6AQ1NJZ9gd-bpaoGq6fBXVIZd7J8tyKlpWYCpaboaw-_MxGCxayXZqGcx-nMf4FCAErjYAPbZ9qR2_QiSKYau-G6SM84b_6uia1nRG8CHpPY8O87_uK0GSLyPax0XoJQW5-6pg57JA0lElepsHIX2ZBk3-euxki9gBJIBWKc-h679qCL7-aw
  
 
(note that some browsers don't like this content type in the return body)
 
(note that some browsers don't like this content type in the return body)
  
= Consent =
+
== Calling $connect ==
 +
 
 +
post to https://test.fhir.org/r3/$connect:
 +
 
 +
  source=http%3A%2F%2Fsomething%2Fsomewhere&consent=1&expires_in=7621372&patient=example&jwt=eyJhbGciIDogIlJTMjU2Iiwia2lkIiA6ICIvYXV0aF9rZXkiLCJ0eXAiIDogIkpXVCJ9.eyJleHAiIDogMTUwMTkyOTA2OSwiaWF0IiA6ICIxNTAxODQyNjY5IiwiaXNzIiA6ICJ1cm46dXVpZDoxNDg2MzMyYi1mZTNiLTQ4M2EtYjlkNC1kNmQ4MWNjNWI3MmUiLCJzdWIiIDogImxvY2FsLmZoaXIub3JnIn0.FAeo0jK8yo5VtpmSiySzzzT3NwuMc1WVrgPUiVNH1srQVm5Qa7wJmh5j9RDL8BH52b0-Ek8tz7JLDF_BYHJ6qGJ2Yni1_MC31lp5_C64s55ZU5Bh2LCy3NlWP3UxgSLT42KDQqYuJ-ZQ_09zbor-Jo5Bv10qcXaQoqfha0ib-unrbJBfHVJgFEbvaR_fQwdP06hMhQMdr4MIluwQ0aVp1fckV_Uf4Wc9GhEtd58ZKSo2ce0YDo852AZIO00WXoE6bX6xHm5V1RTgjTQe-1ji4bwzkIajTViMSn6Ly3MfQdNoLxRQBmrtc22dTzZ_Mn_Y26pgPyF9NRGMuwyC--EAVHz5S1oXNAVcVI4--Tt14jiqXxomGbAVlly6fnk3_o8lWZ8AsKuivMK4QIy2Od58lYu086RbtQnSYtdRyr2rUik1NvOYh2MLZj8psjOnALiGWLF9aYKbQZx7tvaZ_ijFlFw0D3j43BE36oZ7ztcFuScEqLe-TK7yF7k6AQ1NJZ9gd-bpaoGq6fBXVIZd7J8tyKlpWYCpaboaw-_MxGCxayXZqGcx-nMf4FCAErjYAPbZ9qR2_QiSKYau-G6SM84b_6uia1nRG8CHpPY8O87_uK0GSLyPax0XoJQW5-6pg57JA0lElepsHIX2ZBk3-euxki9gBJIBWKc-h679qCL7-aw&authorization=a81de03d-cfad-462d-a81b-3f8254909622
 +
 
 +
response:
 +
 
 +
200 OK
 +
 
 +
<OperationOutcome xmlns="http://hl7.org/fhir">
 +
    <text>
 +
        <status value="generated"/>
 +
        <div xmlns="http://www.w3.org/1999/xhtml">
 +
            <p>Connection Accepted</p>
 +
        </div>
 +
    </text>
 +
    <issue>
 +
        <severity value="error"/>
 +
        <code value="informational"/>
 +
        <diagnostics value="Connection Accepted"/>
 +
    </issue>
 +
</OperationOutcome>
 +
 
 +
test.fhir.org will now start consuming data using the S4S interface specified in source
 +
 
 +
= Using test.fhir.org as the source EHR =
 +
 
 +
Sequence of steps:
 +
# set up consent on test.fhir.org JWT
 +
# get a JWT  form some other system
 +
# connect that JWT to the consent using the $authorize function
 +
 
 +
== Consent ==
  
Use this consent resource as the base for authorization (post it to the server):
+
Use this consent resource as the base for authorization (post it to the server, record the id that the server assigns):
  
 
  <Consent xmlns="http://hl7.org/fhir">  
 
  <Consent xmlns="http://hl7.org/fhir">  
  <id value="1"/>
 
 
   <status value="active"/>
 
   <status value="active"/>
 
   <patient>
 
   <patient>
Line 34: Line 77:
 
     <class>
 
     <class>
 
       <system value="http://smarthealthit.org/fhir/scopes"/>
 
       <system value="http://smarthealthit.org/fhir/scopes"/>
       <code value="User/*"/>  
+
       <code value="user/*.*"/>  
 
     </class>
 
     </class>
 
   </except>  
 
   </except>  
 
  </Consent>
 
  </Consent>
  
= Authorization =
+
Notes:
 +
* you can change the patient but it must be a patient that exists on the server. If you logged via smart on fhir, and you chose a particular patient during the login, the consent must refer to that patient.
 +
* you can use json instead if you want
 +
 
 +
== Authorization ==
  
 
This is what you post to the server as a body to the $authorize routine (this time in json):
 
This is what you post to the server as a body to the $authorize routine (this time in json):
 +
 +
POST http://test.fhir.org/r3/Consent[id]/$authorize
  
 
  {
 
  {
Line 54: Line 103:
 
   }, {
 
   }, {
 
     "name" : "jwt",
 
     "name" : "jwt",
     "valueString" : "{your packed JWT}"
+
     "valueString" : "{packed JWT from the target server}"
 
   }   
 
   }   
 
   ]
 
   ]
 
  }
 
  }
 +
 +
The response contains a key value: the authorization token:
 +
 +
{
 +
    "resourceType": "Parameters",
 +
    "parameter": [
 +
        {
 +
            "name": "Message",
 +
            "valueString": "Application Validation is not implemented yet"
 +
        },
 +
        {
 +
            "name": "id",
 +
            "valueId": "a81de03d-cfad-462d-a81b-3f8254909622"
 +
        }
 +
    ]
 +
}
 +
 +
== Acquiring an Access Token ==
 +
 +
Once $authorize has been called, the target EHR may acquire an access token for the FHIR API:
 +
 +
  POST http://test.fhir.org/auth/token
 +
  Authorization: Bearer [JWT]
 +
  Content-Type: application/x-www-form-urlencoded
 +
 
 +
  grant_type=client_credentials&scope=[id]
 +
 +
where [JWT] is the JWT provided to $authorize in the previous step and [id] is the token returned from the $authorise operation above
 +
 +
The response will be:
 +
 +
{
 +
    "access_token": "urn:oauth:e8a4131c-1c04-4c2f-aba0-985ce472b90d",
 +
    "token_type": "Bearer",
 +
    "expires_in": "7621372",
 +
    "scope": "user/*.*",
 +
    "patient": "example"
 +
}
 +
 +
The token returned with this can now be used in the Authorization header to read what data the patient authorized
 +
 +
GET [base]/Patient/[id]
 +
Authorization: Bearer urn:oauth:e8a4131c-1c04-4c2f-aba0-985ce472b90d
 +
 +
= Client Application Verification Service =
 +
 +
http://test.fhir.org also implements the Client Application Verification Service. The CAVS end-point is
 +
 +
  http://test.fhir.org/auth/cavs
 +
 +
No authentication is needed to call the cavs.
 +
 +
todo: JWK sources
 +
 +
The decision making behind the cavs is based on the device, organization and observation resources stored in test.fhir.org. This is a matter of internal convenience; these are not directly suitable for the task, and there's no recommendation that other systems should follow this example. It was just a matter of convenience. There's a client app that edits the content - you can get that by asking grahameg@gmail.com

Latest revision as of 12:32, 10 August 2017

Using test.fhir.org as the target EHR

e.g information flows from another server to test.fhir.org

Sequence of steps:

  1. get the test.fhir.org JWT
  2. authorize the JWT on the other server
  3. Ask test.fhir.org to start copying data
  4. find out how copying data is going
  5. stop copying data

Acquiring test.fhir.org's JWT

you get the JWT by:

 GET http://test.fhir.org/r3/$jwt?source=[uri]

Where [uri] is the address of the source system. Source is a mandatory parameter, though it does not make any difference to test.fhir.org

this returns a 200 OK with a body content type of application/jwt:

 eyJhbGciIDogIlJTMjU2Iiwia2lkIiA6ICIvYXV0aF9rZXkiLCJ0eXAiIDogIkpXVCJ9.eyJleHAiIDogMTUwMTkyOTA2OSwiaWF0IiA6ICIxNTAxODQyNjY5IiwiaXNzIiA6ICJ1cm46dXVpZDoxNDg2MzMyYi1mZTNiLTQ4M2EtYjlkNC1kNmQ4MWNjNWI3MmUiLCJzdWIiIDogImxvY2FsLmZoaXIub3JnIn0.FAeo0jK8yo5VtpmSiySzzzT3NwuMc1WVrgPUiVNH1srQVm5Qa7wJmh5j9RDL8BH52b0-Ek8tz7JLDF_BYHJ6qGJ2Yni1_MC31lp5_C64s55ZU5Bh2LCy3NlWP3UxgSLT42KDQqYuJ-ZQ_09zbor-Jo5Bv10qcXaQoqfha0ib-unrbJBfHVJgFEbvaR_fQwdP06hMhQMdr4MIluwQ0aVp1fckV_Uf4Wc9GhEtd58ZKSo2ce0YDo852AZIO00WXoE6bX6xHm5V1RTgjTQe-1ji4bwzkIajTViMSn6Ly3MfQdNoLxRQBmrtc22dTzZ_Mn_Y26pgPyF9NRGMuwyC--EAVHz5S1oXNAVcVI4--Tt14jiqXxomGbAVlly6fnk3_o8lWZ8AsKuivMK4QIy2Od58lYu086RbtQnSYtdRyr2rUik1NvOYh2MLZj8psjOnALiGWLF9aYKbQZx7tvaZ_ijFlFw0D3j43BE36oZ7ztcFuScEqLe-TK7yF7k6AQ1NJZ9gd-bpaoGq6fBXVIZd7J8tyKlpWYCpaboaw-_MxGCxayXZqGcx-nMf4FCAErjYAPbZ9qR2_QiSKYau-G6SM84b_6uia1nRG8CHpPY8O87_uK0GSLyPax0XoJQW5-6pg57JA0lElepsHIX2ZBk3-euxki9gBJIBWKc-h679qCL7-aw

(note that some browsers don't like this content type in the return body)

Calling $connect

post to https://test.fhir.org/r3/$connect:

 source=http%3A%2F%2Fsomething%2Fsomewhere&consent=1&expires_in=7621372&patient=example&jwt=eyJhbGciIDogIlJTMjU2Iiwia2lkIiA6ICIvYXV0aF9rZXkiLCJ0eXAiIDogIkpXVCJ9.eyJleHAiIDogMTUwMTkyOTA2OSwiaWF0IiA6ICIxNTAxODQyNjY5IiwiaXNzIiA6ICJ1cm46dXVpZDoxNDg2MzMyYi1mZTNiLTQ4M2EtYjlkNC1kNmQ4MWNjNWI3MmUiLCJzdWIiIDogImxvY2FsLmZoaXIub3JnIn0.FAeo0jK8yo5VtpmSiySzzzT3NwuMc1WVrgPUiVNH1srQVm5Qa7wJmh5j9RDL8BH52b0-Ek8tz7JLDF_BYHJ6qGJ2Yni1_MC31lp5_C64s55ZU5Bh2LCy3NlWP3UxgSLT42KDQqYuJ-ZQ_09zbor-Jo5Bv10qcXaQoqfha0ib-unrbJBfHVJgFEbvaR_fQwdP06hMhQMdr4MIluwQ0aVp1fckV_Uf4Wc9GhEtd58ZKSo2ce0YDo852AZIO00WXoE6bX6xHm5V1RTgjTQe-1ji4bwzkIajTViMSn6Ly3MfQdNoLxRQBmrtc22dTzZ_Mn_Y26pgPyF9NRGMuwyC--EAVHz5S1oXNAVcVI4--Tt14jiqXxomGbAVlly6fnk3_o8lWZ8AsKuivMK4QIy2Od58lYu086RbtQnSYtdRyr2rUik1NvOYh2MLZj8psjOnALiGWLF9aYKbQZx7tvaZ_ijFlFw0D3j43BE36oZ7ztcFuScEqLe-TK7yF7k6AQ1NJZ9gd-bpaoGq6fBXVIZd7J8tyKlpWYCpaboaw-_MxGCxayXZqGcx-nMf4FCAErjYAPbZ9qR2_QiSKYau-G6SM84b_6uia1nRG8CHpPY8O87_uK0GSLyPax0XoJQW5-6pg57JA0lElepsHIX2ZBk3-euxki9gBJIBWKc-h679qCL7-aw&authorization=a81de03d-cfad-462d-a81b-3f8254909622

response:

200 OK

<OperationOutcome xmlns="http://hl7.org/fhir">
   <text>
       <status value="generated"/>

Connection Accepted

   </text>
   <issue>
       <severity value="error"/>
       
       <diagnostics value="Connection Accepted"/>
   </issue>
</OperationOutcome>

test.fhir.org will now start consuming data using the S4S interface specified in source

Using test.fhir.org as the source EHR

Sequence of steps:

  1. set up consent on test.fhir.org JWT
  2. get a JWT form some other system
  3. connect that JWT to the consent using the $authorize function

Consent

Use this consent resource as the base for authorization (post it to the server, record the id that the server assigns):

<Consent xmlns="http://hl7.org/fhir"> 
 <status value="active"/>
 <patient>
   <reference value="Patient/example"/>
 </patient>
 <policyRule value="http://hl7.org/fhir/ConsentDefinition/simple-oauth"/>  
 <except>  
   <type value="permit"/>
   <action>
     <coding>
       <system value="http://hl7.org/fhir/consentaction"/>
       
     </coding>
   </action>
   <class>
     <system value="http://smarthealthit.org/fhir/scopes"/>
      
   </class>
 </except> 
</Consent>

Notes:

  • you can change the patient but it must be a patient that exists on the server. If you logged via smart on fhir, and you chose a particular patient during the login, the consent must refer to that patient.
  • you can use json instead if you want

Authorization

This is what you post to the server as a body to the $authorize routine (this time in json):

POST http://test.fhir.org/r3/Consent[id]/$authorize
{
 "resourceType" : "Parameters",
 "parameter" : [{
    "name" : "duration",
    "valueDuration" : {
      "value" : "3",
      "system" : "http://unitsofmeasure.org",
      "code" : "mo"
    }
  }, {
    "name" : "jwt",
    "valueString" : "{packed JWT from the target server}"
  }  
 ]
}

The response contains a key value: the authorization token:

{
   "resourceType": "Parameters",
   "parameter": [
       {
           "name": "Message",
           "valueString": "Application Validation is not implemented yet"
       },
       {
           "name": "id",
           "valueId": "a81de03d-cfad-462d-a81b-3f8254909622"
       }
   ]
}

Acquiring an Access Token

Once $authorize has been called, the target EHR may acquire an access token for the FHIR API:

 POST http://test.fhir.org/auth/token
 Authorization: Bearer [JWT]
 Content-Type: application/x-www-form-urlencoded
 
 grant_type=client_credentials&scope=[id]

where [JWT] is the JWT provided to $authorize in the previous step and [id] is the token returned from the $authorise operation above

The response will be:

{

   "access_token": "urn:oauth:e8a4131c-1c04-4c2f-aba0-985ce472b90d",
   "token_type": "Bearer",
   "expires_in": "7621372",
   "scope": "user/*.*",
   "patient": "example"

}

The token returned with this can now be used in the Authorization header to read what data the patient authorized

GET [base]/Patient/[id]
Authorization: Bearer urn:oauth:e8a4131c-1c04-4c2f-aba0-985ce472b90d

Client Application Verification Service

http://test.fhir.org also implements the Client Application Verification Service. The CAVS end-point is

 http://test.fhir.org/auth/cavs

No authentication is needed to call the cavs.

todo: JWK sources

The decision making behind the cavs is based on the device, organization and observation resources stored in test.fhir.org. This is a matter of internal convenience; these are not directly suitable for the task, and there's no recommendation that other systems should follow this example. It was just a matter of convenience. There's a client app that edits the content - you can get that by asking grahameg@gmail.com