We have an existing API that is secured by an initial username & password call to xxxx.com/api/vi/auth/token that returns a bearer token to be included in all future calls to the API. This API is live with some trusted apps.
We now have a requirement to put this API behind Azure API Management (APIM) for a new partner and have set that up to use OAuth2 with AD.
Ideally when APIM calls our backend API we need it to go through the existing API auth flow to get the existing API token and include that with any calls.
There seems to be some limited 'Authorization credentials' that can be set in Azure but I cant find any help on how to set/use them.
It can be done in a number of ways, but most of them would involve writing custom policy. Most simply something like below:
<send-request mode="new" response-variable-name="token" timeout="3">
<set-url>xxxx.com/api/vi/auth/token</set-url>
<set-method>POST</set-method>
<set-header name="Authorization" exists-action="override">
<value>Basic dXNlcm5hbWU6cGFzc3dvcmQ=</value>
</set-header>
</send-request>
<set-header name="Authorization" exists-action="override">
<value>#("Bearer " + ((IResponse)context.Variables["token"]).Body.As<string>())</value>
</set-header>
send-request sends request with basic auth header (substitute for your value), and will store response in token variable.
set-header gets body from token response, parses it as a string and puts it into Authorization header for request to backend.
A few improvements that can be done here:
Store your basic credentials in named value for security.
Cache token so that you don't need to fetch it for every request, possibly cache based on token expiration
Related
In my app, after a user sends a message to someone, another function is triggered to notify the receiver. For that, the sender has to have the receiver's push token (front end). My question is: Is that safe? Is there a better approach?
I'm using Firebase but I couldn't figure out a way to send this notification through Google Cloud Functions...
Yes you can treat it as sensitive information. Tokens could contain information that when a malicious user accessed, it can be used to impersonate your app and send their own messages to users. While there's no reported instance (yet), it would be wise to follow the best security practices.
According to this documentation on Sending Notifications with Expo's Push API
We offer the use of an access token alongside the push token as an additional layer of security.
If you're using the expo-server-sdk-node, upgrade to at least v3.6.0 and pass your accessToken as an option in the constructor. Otherwise, pass in the header 'Authorization': 'Bearer ${accessToken}' with any requests to our push API.
Any requests sent without a valid access token after you enable push security will result in an error with code: UNAUTHORIZED.
You can check this blog on Implementing Push Notifications with Expo and Firebase Cloud Functions on how to push notifications securely.
I want to test the "Third-party applications" access using Postman.
When trying to obtain an OAuth token I am receiving a '404 Not Found' from Foundry. I suspect that I've configured the wrong URLs for the OAuth2 endpoints.
From reading the documentation
https://<foundryhost.com>/workspace/documentation/product/foundry-backend/security-api#oauth2-api-endpoints
I put together the following 2 endpoints:
Auth URL: https://<foundryhost.com>/api/oauth2/authorize
Access Token URL: https://<foundryhost.com>/api/oauth2/token
Are those correct or am I missing something?
You're on the right track with the service context path - in this case it's multipass - which is Foundry's authentication service.
Try this:
authorize_url=FOUNDRY_STACK + 'multipass/api/oauth2/authorize',
access_token_url=FOUNDRY_STACK + 'multipass/api/oauth2/token'
Looks like the docs could do with some clarification. Will get that fixed.
Another gotcha to remember with OAuth2 on Foundry: the refresh token rotates on use - remember to save both when you request a new access token (this is compliant with the standard, but it is optional).
I have an APIM API, which is associated with a Product(Product scope). When I test the API within APIM (Test tab), everything works fine.
But when I copy the same headers along with the same Authorization JWT token to Postman and test the API, I'm getting 401 error with the error reason Signature validation failed. I see the kid value in JWT is different in both the cases (testing within APIM, postman).
When I remove Product for the APIM API, the request from postman works fine with the same JWT token.
Can someone please help me understand why JWT validation is failing when the Product is mapped to APIM API?
JWT Validation policy is as below. We have our own JWT token generation mechanism, those details are part of Named Values
<policies>
<inbound>
<validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Invalid_AccessToken" require-expiratation-time="true" require-scheme="Bearer" require-signed-tokens="true" output-token-variable-name="outToken">
<openid-config url="{{openid-config-url}}" />
<issuers>
<issuer>{{issuer id}}</issuer>
</issuers>
</validate-jwt>
</inbound>
</policies>
All the incoming request to api management will have a token in a header, before backend service is hit token has to be verified. To verify token a GET tokenVallidationApi is to be hit and the response will tell us whether the token is valid or not. If the response exists for token validation , we have to take out few entries from response and enrich the body/header to hit the backend api. I am very new to api management tool and just figuring out how can we achieve this with azure api management?
This is possible. You would have to implement your policies like something below
1. Validate Token
For this, you would first call the validation endpoint using send-request. You could also implement caching using value caching policies for multiple requests.
The doc also highlights how you can extract value from the response body.
2. Transform Body & Headers
For headers, you would use the set-header policy and for the body, you would use the set-body policy.
I'm looking to use Azure API Management to provide a centralized API for some external, authenticated APIs (Twitter, etc.), utilizing application-only authentication. I want to provide specific tweets, etc. to a dashboard-like mobile app without users needing to authenticate with their own account for each service.
I haven't been able to find any documentation or examples on doing this so far. Policies look promising, but I haven't been able to prove them out yet. Or possibly creating my own API App for each external service (to handle the authentication properly) and then managing that API via API Management.
Anyone have thoughts/ideas on better ways of accomplishing this? Thanks.
Thanks to #DarrelMiller for keeping me on the correct path
The solution ended up being just needing to pass the correct bearer token as a header, accomplished with Set-Header in the inbound policy of the operation. Twitter has non-trivial instructions on how to obtain the bearer token for their service.
Example:
<inbound>
<set-header name="Authorization" exists-action="override">
<value>Bearer xxxxxxxxxxxxxxxxxxxxx</value>
</set-header>
<base />
</inbound>