APIM - Redirect to login.microsoftonline.com if calling API with no Token? - azure-api-management

I'm not quite sure if it is possible to setup an API in Azure API Management with the following behaviour if I call this API-URL from the browser:
Check the token
If passed, check if valid.
If not, redirect to login.microsoftonline.com.
After login call API-URL again.
This is possible with OWIN in this ASP.Net WebApp:
https://github.com/AzureADQuickStarts/AppModelv2-WebApp-OpenIDConnect-DotNet
Maybe I am completly wrong and it is not possible, but I have to know.

Related

Foundry's OAuth2 API Endpoints

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).

Custom portal: server-side sign-in

We have been using APIM since 2018. As the legacy portal has been deprecated and we wanted more freedom, we decided to skip the default APIM portal altogether, and to embed the APIM API methods in our own website, using Postman as the documentation portal.
Most of the methods are straightforward, but it's not clear how to sign-in the user? We can, of course, fetch their statistics and API keys, but how do we know they are who they claim they are?
The code in the self-hosted portal in GitHub is more client-side oriented.
EDIT. From the usersService.ts module it appears that GET /identity with the Authorization header made of Basic and base64-encoded pair of userId:password is to be invoked.
But I keep getting:
{
"error": {
"code": "AuthenticationFailedInvalidHeader",
"message": "Authentication failed. The 'Authorization' header is provided in an invalid format."
}
}
Changing Basic to Bearer predictably yields InvalidAuthenticationToken.
OK, solved (with the help of Microsoft support who sent a screenshot of the method being invoked on their side).
It seems that the method is not to be invoked from management.azure.com like all the other methods. Nope. It has to be invoked from the Management API URL that can be found in the Management API section of your APIM in Azure.
Curiously, the management API toggle does not even have to be on.
Your GET request should be like this:
https://my_apim_instance.management.azure-api.net/subscriptions/my_subscription_id/resourceGroups/my_resource_group/providers/Microsoft.ApiManagement/service/my_apim_instance/identity?api-version=2019-12-01
Now cue in the ever-helpful posters with ever-useful post-solution advice.

How to debug server-side `redirect_uri_mismatch` error from Google Signin

I'm attempting to use Google Sign-In with a firebase function following Google's documentation for Google Sign-In for server-side apps, however I'm running into a redirect_uri_mismatch error (unlike the examples in that documentation, I am using Google's nodejs SDK).
The general flow I'm following is to use google's javascript SDK to request an offlineAccessCode() from a user, send that access code to the server (firebase function), use the access code to get an access token and refresh token, and save the refresh token for later use (this is the flow outlined in the documentation).
It might seem like the meaning of the term redirect_uri_mismatch is self-explanatory, but, as stated in the linked documentation, The Authorized redirect URI field does not require a value. Redirect URIs are not used with JavaScript APIs. That line comes from the section "Step 1: Create a client ID and client secret" and is explaining how to configure the OAuth client credentials. This is the only time in the documentation that a redirect uri is mentioned, and there is no indication that a redirect URI is needed when the server uses the authorization code to fetch an access token.
Indeed, the concept of a redirect uri doesn't seem to make sense in the context of a cloud function using an access code obtained from a client. If the server needs to supply a matching redirect_uri as the javascript client (which doesn't seem to be specified anywhere), I'm not sure what redirect_uri the javascript client uses.
So with that background, does anyone have any idea how to solve this redirect_uri_mismatch error?
Or, more generally, any pointers on implementing this auth flow (my cloud function is written in javascript using the google nodejs sdk). I'm finding it very hard to debug this issue.
Update
I realized that the reason why the error message says redirect_uri_mismatch is because I had been testing various values as redirect_uri. When I remove the (optional) redirect_uri param from the request, the response from google's servers is invalid_request: Missing parameter redirect_uri. So google's making it clear that it wants a redirect URI, even as the documentation seems to imply that it isn't necessary for this auth flow. As a larger problem, the documentation doesn't seem to describe how to set up a redirect URI for an auth flow on a single page app.
Ah HA! The answer (as given in this other S.O. answer) is to set the redirect_uri to "postmessage" on the server (firebase function in my case). I have no idea where this answer came from (i.e. I haven't been able to find it in the docs), but it works.

Pass Authentication Token to Service

I have used lifeary service builder to build my services. some of my services require that the user is authenticated before he can use them.
how can i generate an auth token and send it in the header or in the URL?
I have tried username#host.com:password#http://localhost:8080/PortletName-portlet/api/jsonws/?serviceClassName=com.service.NameServiceUtil&serviceMethodName=getMyNames&serviceParameters=[userid]&userid=1
and it did not work!
I have made sure i have added the below line in my portal-ext.properties and restarted the server.
json.service.auth.token.enabled=true
What more should i do to be able to pass Auth Token? is there a better method that i can use?
You actually want to use AuthVerifier. This is the best way how to access the Liferay API and be authenticated. It similar to the autologin concept.
Have a look at https://dev.liferay.com/es/discover/deployment/-/knowledge_base/7-0/authentication-verifiers and check out the PortalSessionAuthVerifier class in the source code.
The concept is quite simple. Read the request object and determine who the user is. Perform your custom authentication and return the auth result with the user identification.

Chrome Identity API - POST request

I am trying to develop a chrome extension in which I need to use 3rd party Oauth2 authentication. The third party service I want to use, only supports POST requests. But it seems that the launchWebAuthFlow method in the Chrome Identity API, only supports sending GET requests, as all the query parameters are sent in the URL itself. Is this correct? If yes, how should I do authentication?
UPDATE : The API I want to connect is that of Pocket
Partially you're right about POST requirements. But it is only used to initialize Oauth flow.
According to the documentation:
1) You must make a POST request to obtain a request token from Pocket auth service
2) Redirect user to the auth page: https://getpocket.com/auth/authorize?request_token=YOUR_REQUEST_TOKEN&redirect_uri=YOUR_REDIRECT_URI
Which means that you have to make a simple XHR to retrieve request token and then you can use chrome.identity.launchWebAuthFlow function to begin Oauth flow.
Did you try launchWebAuthFlow? You may find that it works. Once authenticated, you can exercise the API via POST, using XMLHttpRequest. (launchWebAuthFlow only handles the authentication, not the API itself.)