Difference between revisions of "201709 Consumer Centered Data Exchange Implementation Notes for test.fhir.org"
(2 intermediate revisions by the same user not shown) | |||
Line 20: | 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. | + | 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) | ||
+ | |||
+ | == 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 = | = Using test.fhir.org as the source EHR = | ||
Line 124: | Line 150: | ||
GET [base]/Patient/[id] | GET [base]/Patient/[id] | ||
Authorization: Bearer urn:oauth:e8a4131c-1c04-4c2f-aba0-985ce472b90d | 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
Contents
Using test.fhir.org as the target EHR
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]
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:
- 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, 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