I am integrating a Smart on FHIR app that will be launched from within an EHR. When the user clicks a button to launch the app, we set a GUID and the current Patient ID to a database record on our FHIR server. The assumption being that given the 'Launch' scope, the OAuth server will call the appropriate API to retrieve the Patient ID given that the GUID is included in the url params.
The call to auth looks like this:
_clientID = {the unique client ID registered to our auth server}
_redirectURL = {redirect back to auth for eventual token request}
launch={the GUID value generated at start of the session and paired with the Patient ID}
_scopes = "launch patient/*.* openid profile"
state = {some opaque value}
aud = {the base URL for our FHIR server}
string url = $"{authorizeURL}?response_type=code&client_id={_clientID}&" +
$"redirect_uri={_redirectURL}&" +
$"launch={launch}&" +
$"scope={HttpUtility.UrlEncode(_scopes)}&" +
$"state={state}&" +
$"aud=https://xxx-smart.xxxxxxxxx.com";
All of this works and I end up with a json response that includes the id_token, access_token, expires_in, token_type('Bearer'). But, no 'patient'.
My assumption was that the OAuth server would call the scope 'launch/patient' on our FHIR server but no such call is being made. In fact, I created a few endpoints just for the purpose of logging and NONE of them are being called.
Here is an example of one of my FHIR Server test/log endpoints (I created few with 1 to 4 parameters):
[AllowAnonymous]
[HttpGet("{functionName}/{id}")]
public string GetPatientData3(string functionName, string id)
{
TelemetryClient telemetry = new();
telemetry.TrackEvent($"FHIR SVR GetPatientData3 {functionName} {id}");
string configJson = "0009998888";
return configJson;
}
How do I set this 'patient' context properly?
How does the OAuth server retrieve this context so I can have that patient ID appear in the json response from the ~/token call?
Further Notes:
The contents of the openid-configuration:
{"token_endpoint":
"https://aadproxy.azurewebsites.net/xxx/oauth2/v2.0/token",
"token_endpoint_auth_methods_supported":
["client_secret_post","private_key_jwt","client_secret_basic"],
"jwks_uri":
"https://login.microsoftonline.com/xxx/discovery/v2.0/keys",
"response_modes_supported": ["query","fragment","form_post"],
"subject_types_supported": ["pairwise"],
"id_token_signing_alg_values_supported": ["RS256"],
"response_types_supported":["code","id_token","code
id_token","id_token token"],
"scopes_supported":["openid","profile","email","offline_access"],
"issuer": "https://login.microsoftonline.com/xxx/v2.0",
"request_uri_parameter_supported":false,
"userinfo_endpoint":"https://graph.microsoft.com/oidc/userinfo",
"authorization_endpoint":
"https://aadproxy.azurewebsites.net/xxx/oauth2/v2.0/authorize",
"device_authorization_endpoint":
"https://login.microsoftonline.com/xxx/oauth2/v2.0/devicecode",
"http_logout_supported":true,
"frontchannel_logout_supported":true,
"end_session_endpoint":
"https://login.microsoftonline.com/xxx/oauth2/v2.0/logout",
"claims_supported":
["sub","iss","cloud_instance_name","cloud_instance_host_name",
"cloud_graph_host_name","msgraph_host","aud","exp","iat",
"auth_time","acr","nonce","preferred_username",
"name","tid","ver","at_hash","c_hash","email"],
"kerberos_endpoint":
"https://login.microsoftonline.com/xxx/kerberos",
"tenant_region_scope":"NA",
"cloud_instance_name":"microsoftonline.com",
"cloud_graph_host_name":"graph.windows.net",
"msgraph_host":"graph.microsoft.com",
"rbac_url":"https://pas.windows.net"}
So, I notice that the 'patient/.' and the 'launch' scope among a whole host of others that I have are not supported according to my openid config. The only supported ones are "openid","profile","email", "offline_access".
In Azure AD, 'App Registration' > 'Expose an API' I have a list of at least 15 scopes entered there. In 'API' permissions they are all listed there as well.
One other thing to note, AzureAD does not handle scopes with a forward slash. So, launch/patient has to be entered as launch-patient. We also had to implement a proxy server to capture the ~/oauth2/v2.0/authorize request and modify the scope parameter entries to reflect this before passing on the request to the actual server.
I guess the pertinent question now is: How do the scopes that I have entered manually get supported?
How can I filter by multiple IDs using the Office 365 Service Communications API?
I'm getting the current status using https://manage.office.com/api/v1.0/{tenent}/ServiceComms/CurrentStatus which gives me incident IDs. I'm trying to use those IDs to get the messages affiliated but the message endpoint /ServiceComms/Messages is not working well with the filters.
The documentation shows:
I've tried:
/ServiceComms/Messages?ID=CR555555,/ServiceComms/Messages?ID='CR555555', /ServiceComms/Messages?Id=CR555555,/ServiceComms/Messages?Id='CR555555' - Returns everything (doesn't filter)
/ServiceComms/Messages?$filter=ID eq 'CR555555' - Returns Error
/ServiceComms/Messages?$filter=Id eq 'CR555555' - Returns 1 result
/ServiceComms/Messages?$filter=Id eq 'CR555555' or Id eq 'CR555556' - Returns error
I was able to get an AND result using
$filter=MessageType eq Microsoft.Office365ServiceComms.ExposedContracts.MessageType'Incident' and EndTime ge 2019-07-25T00:00:00Z but OR always errors with the message "Filter {filter} is invalid. Expected '<Item> <operator> <Value>' pattern."
You need to use Microsoft.Office365ServiceComms.ExposedContracts.MessageType'Incident' as your MessageType.
A request to /Messages should return you a odata context at the top of the response. For example:
{
"#odata.context": "https://office365servicecomms-prod.cloudapp.net/api/v1.0/{{TenantID}}/$metadata#Messages",
...
}
If you query that, you receive the metadata along with the possible filters. I cannot give you an example as of today (2020-02-16) a query returns a 500 Internal Server Error. Microsoft is working on a fix. Maybe it works again by the time you read my reply.
Complete example:
https://manage.office.com/api/v1.0/{{TenantID}}/ServiceComms/Messages?$filter=MessageType eq Microsoft.Office365ServiceComms.ExposedContracts.MessageType'Incident' and LastUpdatedTime ge 2020-02-13T00:00:00.000Z
And yes, the ID filter must be written 'Id'. Microsofts documentation has a lot of wrong information in it.
Objective: I am trying to integrate creator-form-data with google-sheet using google-sheet-api-v4.
I am able to create an empty sheet(data params being empty ) at google spreadsheets.
but i don't know ,how to create sheet with data-params , to either-
(1) assign title ,to spreadsheet , or
(2) write any data, to spreadsheet
error received : using deluge to perform task no. ( 1 ), the error thrown is :
Invalid JSON payload received. Unexpected token
Note:
(1)Oauth credentials are checked and correct,
google access token is also valid, confirming via
Google-oauth-playground
(2) i am able to assign title and data from google-try-api-platform,but no success from deluge side.
google-sheet-try-api
The issue is solved now ,in postUrl the post-data to be posted , must be converted from json to string (params=data.toString(); ).
I had sent post-data in json format thats the mistake I made.
Below is correct sample code for deluge:
append_data = {"values":{{thisDate,thisQuantity}}};
final_append_data = append_data.toString();
response = postUrl(append_data_sheet_url,final_append_data,mymap,false);
Note: variable "final_append_data" is converted to string.
I was using an HTTP POST method using the URL
"https://stream.twitter.com/1.1/statuses/filter.json" and in the body I was posting the key/value I wanted to get tweets from - for example "track=london". This was working fine.
Now I am trying to switch to AKKA-CAMEL and I am using their twitter consumer. I am using an endpoint URL of:
def endpointUri: String = s"twitter:////search?type=direct&keywords=${Settings.queryList()}&consumerKey=${tweeterCredentials.consumerKey}&consumerSecret=${tweeterCredentials.consumerSecret}&accessToken=${tweeterCredentials.accessToken}&accessTokenSecret=${tweeterCredentials.accessTokenSecret}"
I get a response from twitter but it is not in JSON and it is not the same information about the tweet as before. It just return the tweet text but before I was getting the whole metadata which I need to analyze.
Does somebody knows how to configure Camel URI to return JSON and the whole metadata as before?
Thanks
I got this to work by using the following syntax:
def endpointUri: String = s"twitter://streaming/filter?type=event&keywords=${Settings.queryList()}&consumerKey=${tweeterCredentials.consumerKey}&consumerSecret=${tweeterCredentials.consumerSecret}&accessToken=${tweeterCredentials.accessToken}&accessTokenSecret=${tweeterCredentials.accessTokenSecret}"
Where: Settings.queryList return a comma separated list of keyworkds. The object tweeterCredentials holds the keys from Tweeter to access the site.
Also it is necessary to set autoAck like this in Camel:
override def autoAck = true
This prevents a timeout exception.
i'm currently trying to add a field into the Header of my Cypher request to tell the load-balancer wether it's a write or read request so it directs the query on Master or Slave Neo4j instance.
HttpClientWrapper clientWrapper = new HttpClientWrapper(ConfigurationManager.AppSettings["Neo4jUserName"], ConfigurationManager.AppSettings["Neo4jPassword"]);
Uri uri = new Uri(ConfigurationManager.AppSettings["Neo4jClient"]);
GraphClient client = new GraphClient(uri, clientWrapper);
client.JsonConverters.Add(new CoordinateConverter());
client.Connect();
...
NameValueCollection collection = new NameValueCollection();
collection.Add("X:Write", "1");
...
client.Cypher.CustomHeader(collection)...
But when executing the query, i'm getting Exception such as:
System.FormatException: "The header name format is invalid."
My question is, do the .CustomHeader(collection) override the standard Header instead of only adding the field X:Write ?
I'm struggling to find documentation on CustomHeader and how it's supposed to work.
Thanks in advance for reading me.
EDIT: Here is some code examples i found and should work: https://github.com/Readify/Neo4jClient/pull/149/files
The error was that i couldn't use ':' in the headername, changing the name to "IsWrite" solved the problem.