From Cache how to Retrieve and Use/Reuse a Bearer Token to authenticate and send data to REST web service?
Need a sample of using %Net.HttpRequest and %NetHttpResponse from Cache to retrieve and then use/reuse a bearer token to send json data to a REST web service.
For the first part of your question, here's a sample method that gets a bearer token from the request:
ClassMethod GetAccessTokenFromRequest(pRequest As %CSP.Request = {%request}) As %String { Set accessToken="" Set authorizationHeader=pRequest.GetCgiEnv("HTTP_AUTHORIZATION") If $zcvt($piece(authorizationHeader," ",1),"U")="BEARER" { If $length(authorizationHeader," ")=2 { Set accessToken=$piece(authorizationHeader," ",2) } } return accessToken }
EDIT:
And here is a full sample of a REST handler that retrieves a bearer token and reuses it to make a request against another REST service.
Class API.DemoBearerToken Extends %CSP.REST { Parameter APIHOST = "localhost"; Parameter APIPORT = 52773; Parameter APIPATH = "/some/other/path"; XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ] { <Routes> <Route Url="/example" Method="GET" Call="example"/> </Routes> } ClassMethod example() { set accessToken = ..GetAccessTokenFromRequest(%request) set req = ##class(%Net.HttpRequest).%New() set req.Https = 1 set req.SSLConfiguration = "some ssl config" set req.Server = ..#APIHOST set req.Port = ..#APIPORT set req.Authorization = "Bearer "_accessToken $$$ThrowOnError(req.Get(..#APIPATH)) set %response.Status = req.HttpResponse.StatusCode set %response.ContentType = req.HttpResponse.ContentType if req.HttpResponse.StatusCode <= 400 { //if not an error response set jsonData = {}.%FromJSON(req.HttpResponse.Data) write jsonData.%ToJSON() } return $$$OK } ClassMethod GetAccessTokenFromRequest(pRequest As %CSP.Request = {%request}) As %String { Set accessToken="" Set authorizationHeader=pRequest.GetCgiEnv("HTTP_AUTHORIZATION") If $zcvt($piece(authorizationHeader," ",1),"U")="BEARER" { If $length(authorizationHeader," ")=2 { Set accessToken=$piece(authorizationHeader," ",2) } } return accessToken } }
Thanks for your response. Will this work if the REST web service I am targeting is a 3rd party not running Cache or using CSP?
I have Cache 2016.1 (not Ensemble or IRIS) and need to duplicate the functionality of this C# .net code. The target REST web service is a 3rd party not using Intersystems products.
public static TokenResponseModel getBearerToken(string siteUrl, string Username, string Password)
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(siteUrl);
client.DefaultRequestHeaders.Accept.Clear();
// uncomment to allow self signed certificates for https requests
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
HttpContent requestContent = new StringContent("grant_type=password&username=" + Username + "&password=" + Password, Encoding.UTF8, "application/x-www-form-urlencoded");
HttpResponseMessage responseMessage = client.PostAsync("Token", requestContent).Result;
if (responseMessage.IsSuccessStatusCode)
{
string jsonMessage;
using (Stream responseStream = responseMessage.Content.ReadAsStreamAsync().Result)
{
jsonMessage = new StreamReader(responseStream).ReadToEnd();
}
TokenResponseModel tokenResponse = (TokenResponseModel)JsonConvert.DeserializeObject(jsonMessage, typeof(TokenResponseModel));
return tokenResponse;
}
else
{
return null;
}
}
Great article!
Can you enable HTTP Bearer token authentication on Web Applications via the System Management Portal?
All I see under 'Allowed Authentication Methods' are options for:
Perhaps I am missing a trick somewhere?
Do you want to auth using Bearer aginst external REST API?
If so, you don't need web app config, just the code by @Pravin Barton
I was hoping to convert the above sample into an Internal REST API so that Bearer Authentication could replace Basic Authentication
First create a REST API. After that override AccessCheck method in your REST broker to check for bearer token.
yes, the proposed solution would work with any external REST API.