I am trying to integrate Quickbooks online with Mule. So far, I can complete the OAuth dance and retrieve the access token via the HTTP connector using the authorization code configuration.
The steps followed include:
COnfiguring the HTTP Request connector for OAuth dance which includes
Added authorization, callback URL, token URL, and client credentials
Configured payload for saving the access and refresh tokens
To trigger the oauth flow , I hit the authorize URL which in return gives me the realmId and authorization code
To make subsequent requests to the APIs using the extracted token I need the realm ID as well but I am not able to extract that.
The realmId is returned in the initial call along with the authorization code in the payload but when the process happens through mulesoft, there is no way to capture it and without the realmId I cannot make requests to the API.
Following is the XML configuration for HTTP:
<http:request-config name="HTTP_Request_configuration" doc:name="HTTP Request configuration" doc:id="36a1c561-9498-4dbf-b323-5c726b20cb6a" >
<http:request-connection protocol="HTTPS" host="sandbox-quickbooks.api.intuit.com" port="443">
<http:authentication >
<oauth:authorization-code-grant-type externalCallbackUrl="http://localhost:8082/callback" localAuthorizationUrl="https://localhost:8082/login" authorizationUrl="https://appcenter.intuit.com/connect/oauth2" clientId="ABNxxKq4xy1KWs1BteaIIAhY3NC7G5jg9YZg3h15Zf3waDdEja" clientSecret="5k5GxV3HIBtM7DRSQOqlBqtjWfg07tFNAFeW9EeJ" tokenUrl="https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer" localCallbackUrl="http://localhost:8082/callback" state="abc" scopes="com.intuit.quickbooks.accounting">
<oauth:custom-parameter-extractors >
</oauth:custom-parameter-extractors>
</oauth:authorization-code-grant-type>
</http:authentication>
</http:request-connection>
</http:request-config>
I need a way to extract the realmId and set it dynamically instead of hardcoding.
[This is the first request which gets the auth code and realmId before token exchange][2]
This is how realmId will be used in subsequent requests after token exchange
It is to be noted that I am not manually saving and reusing any variables, it is all happening as part of the Mulesoft HTTP connector oauth config
Reference guide for oauth in Mulesoft
Related
So I would like to add SSO using Azure AD.
My stack consists of a React app as frontend and a NestJS API as backend(decoupled). The scenario looks like the following
User clicks login button
I create a new window (popup) which leads the user to the Azure AD login page (step 3 in the diagram)
After the user logs in to Azure AD successfully Azure AD will POST the SAML response to a redirect URL I have provided them (let's say http://myapp.com/saml) (step 5 in the diagram) (This redirect URL, to my understanding, has to be an endpoint in the NestJS api since React frontend can't handle post request.)
NestJS will handle the post request get the info it needs, validates etc etc and then NestJS has to return a Token to the frontend somehow in order for the frontend to store that token in a cookie and be able use it in subsequent requests to the NestJS api so that NestJS will be able to know that this user is logged in. (Step 6)
My issue with this approach is that I don't know how will the client get the token when the the validation is completed from NestJS. If this was a coupled application this would not be an issue since the backend would handle the post request set a cookie and redirect the user. But in this case NestJS can't redirect the user since react handles the routing.
What is the correct approach to handle this?
I thought maybe this could work by using websockets...so that when NestJS handles the post request it can send a message to the user which message will contain the token and then the frontend can add it to a cookie and redirect the user to a protected page.
(1) Does the frontend really need to store a token to send to the backend on subsequent requests? What if the backend set a cookie at Step 7 in your diagram? Then the cookie would be sent to the backend on subsequent requests. The cookie would be scoped to the backend’s domain name and path. Keeping tokens away from the frontend has the advantage that you can keep them safe from being accessed via a Cross-Site Scripting attack on your frontend, if your backend’s cookie has the HttpOnly attribute set.
(2) If you still need to communicate info from the backend to the frontend in Step 7, then send an HTTP 301 response with the Location header set to your frontend’s URL with the info you want to communicate included in the query or hash portion of the URL. For example, after validating in Step 6, in Step 7 your backend’s HTTP 301 response could have the Location header set to https://my-frontend-domain.com?user=bob or set to https://my-frontend-domain.com#user=bob. With ?user=bob, user=bob would get sent over the network again when the browser requests https://my-frontend-domain.com/?user=bob, whereas with #user=bob it would not. Then the frontend’s JavaScript can read user=bob from the URL.
Hi I am exploring some of the authentication and authorization flows with respect to azure active directory. I was using previously oath implicit flow in single page application. After spending time in reading microsoft documentation, I have understood following with respect to implicit flow.
Implicit Flow:
Single page javacript application uses implicit flow to get obtain access token from azure active directory. It directly calls token endpoint to obtain the token so this makes implicit flow less secure.
Authorization Folw in .Net Web application
Whenever we use .Net core web mvc application with authorization code flow, first call will happen in browser to authorization endpoint to get code. In browser we could see the request made to authorization end point. In request url I will pass response type as code then client id and redirect ui. Here first handshake take place between browser and authorization end point. This handshake returns code to the redirect uri. Next part, application has to make POST request to token endpoint to get access token. Code received in first step I will send in token request. In this request I will include client secrete also, redierct uri also. But whenever I make first GET request to authorization endpoint I will not pass client secrete. This is because Its not good to expose secrete in browser. So in second post request I will include client secrete also. Once I get access token I will add it in api request header to make secured call to apis.
This is the authorization code flow flavor I have understood with respect to .Net core web application. now I have another flavor of authorization code with respect to single page application.
Authorization Code Flow in React Web App
I have SPA react application which uses MSAL library. I have cloned sample application from github https://github.com/Azure-Samples/ms-identity-javascript-react-tutorial/tree/main/3-Authorization-II/1-call-api/SPA.
Whenever I run this application, and sign in first call will happen as below
https://login.microsoftonline.com/common/discovery/instance?api-version=1.1&authorization_endpoint=https://login.microsoftonline.com/c5ffa990-7e0a-4bf6-6c04-79ab98e05931/oauth2/v2.0/authorize
I am trying to understand this request. I have query string appended to the url authorization_endpoint=https://login.microsoftonline.com/c5ffa990-7e0a-4bf6-6c04-79ab98e05931/oauth2/v2.0/authorize so this may be used to return the code from authorization server.
Immediately next call will happen https://login.microsoftonline.com/c5ffa990-7e0a-4bf6-6c04-79ab98e05931/oauth2/v2.0/token
to get access token and in request in FormData section I could see following parameters
client_d, redirect_uri,scope,code
In code I see some code value hopefully received from authorization endpoint. anyway this api returned me access_token.
Now coming to conclusion, In .Net core web application and React SPA application both places I am using authorization code flow.
In .Net core authorization code flow I am making use of client secrete whenever trying to obtain access token. All this happen in server side in secure manner. In react also I am using Authorization code flow but I am not using Client secrete anywhere.
In react app also I am making two requests one for authorization endpoint to get code and another to get token. All this I can see in browser itself but then How can I consider this is as secure?
In .Net web app and react app both apps making use of authorization code flow but it behaves independently depends on the type of application.
After going through several documents and videos over the internet I concluded myself as
When Authorization code flow used with server side web apps like .Net core MVC, It makes use of client_secrete to get access token and this call will happen in server side so client secrete not exposed through browser to the users
When Authorization flow used SPA applications without server side support, first it will make call to get authorization code then It will make post request to get access token WITHOUT client_secrete.The only way the authorization code grant with no client secret can be secure is by using the “state” parameter and restricting the redirect URL to trusted clients.
So I am concluding myself as when we use server side web app with authorization code flow we can make use of client secrete but in case of SPA we are not making use of client_secrete.
I have understood above concepts and explained what I understood and also I listed the confusions I got after implementing 2 flavors of authorization code flow in web app and spa app. can someone help me If my understanding is correct or not, If my understanding is wrong, where exactly I understood wrong? Can anyone help me with respect to this. Any help would be greatly appreciated. Thanks
Authcode flow is an OAuth 2.0 workflow, you can use it in any kind of client (Web/mobile/SPA).
Clients should be using MSAL library to communicate with AAD/B2C with PKCE which is used to secure authorization code grants via Proof Key for Code Exchange (code_challenge) with S256 encryption.
Authcode Grant Flow spec:
If you are using B2C, your entry endpoint is:
https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/authorize?
client_id=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6
&response_type=code
&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob
&response_mode=query
&scope=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6%20offline_access
&state=arbitrary_data_you_can_receive_in_the_response
&code_challenge=YTFjNjI1OWYzMzA3MTI4ZDY2Njg5M2RkNmVjNDE5YmEyZGRhOGYyM2IzNjdmZWFhMTQ1ODg3NDcxY2Nl
&code_challenge_method=S256
that will display the SignIn-SignUp-Social Login Form. Just navigate to this URL with you App ClientId registered inside B2C.
You also can take a look to the custom policies starter pack to adapt your workflow to your needs (claims).
If you change response_type=code for response_type=id_token you will get a Token that can be used to authenticate against your restricted resources (API's) after all login process.
Or you can use a second call to the token endpoint to get it.
Token endpoint:
POST https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&client_id=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6&scope=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6 offline_access&code=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrq...&redirect_uri=urn:ietf:wg:oauth:2.0:oob&code_verifier=ThisIsntRandomButItNeedsToBe43CharactersLong
code=XXXXXXXXXXXXX parameter is the access_code returned from first GET request.
Solutions to this is to switch to implicit flow, where there is no need of exchanging code for access token. But keeping access token in web application still vulnerable as this can be exposed using XSS or similar kind of attacks.
Other best practice is https://curity.io/resources/learn/the-token-handler-pattern/
At work we are making an SPFx Web Part React client app that deploys to SharePoint as a Web Part. Our back-end is a ASP.NET Core 2.2 Web API that is secured using Azure Portal's built in Authentication feature. The front-end is using AadHttpClient that magically handles the authentication by taking the context of the current page (SharePoint) that has the user already logged in. Doing so, silent authentication occurs and the API call is successfully made with authentication successfully passed. The AadHttpClient is supposed to magically bundle up the token in the request header that gets sent to the back-end Web API. I still need to debug the live development app and see how to retrieve the Bearer Token in the back-end Web API. These are my next probable steps?
Would I just probably use 'string bearerToken = Request.Headers.....;' or 'string bearerToken = Request.Headers["KeyValue"]' to get the token itself?
Assuming I can get this Bearer Token, how can I check the caller's user information? Is it just var userName = User.Identity.Name;? Or would I or could I use the token and some how make a call to Microsoft Graph API to view the user's info?
If you are using ASP.NET Core and using default authentication then things are bit easier. From documentation you can see that several tokens are injected in the request header based on Identity provider so in your case you have to look for following headers which Azure AD injects. These headers would contain ID Token which you would need to verify the claims and get user information.
X-MS-TOKEN-AAD-ID-TOKEN
X-MS-TOKEN-AAD-ACCESS-TOKEN
X-MS-TOKEN-AAD-EXPIRES-ON
X-MS-TOKEN-AAD-REFRESH-TOKEN
Ideally all the claims are injected automatically in ClaimsPrincipal
you can find more here
Official Docs
How To extract Token
So in my google cloud project I generated a Web Client ID, and follow the steps in
https://developers.google.com/adwords/api/docs/guides/oauth_playground
to get the authentication token.
In my #endpoints.api(allowed_client_ids=) I've put the client id inside it. Then in OAuth2 playground I sent a http request using the authentication token which I have acquired (e.g: Bearer ya29.bwL-f-hz-wcxFq_i-IlEQaJDiinwIP7ad7CaZoRkJRdGrsxxs4Wc9ZeNOgVlhD69zOQk) to the API.
But the problem is, it did not recognize the token, and said it is an invalid token. To compare with, I put endpoints.API_EXPLORER_CLIENT_ID together inside the allowed_clients_ids=, and when I tested it using API Explorer it just works. So am I doing something wrong?
You have specify your own client id and client secret. see this
screenshot
Can I use REST token as SOAP session ID? If so, is that a correct way of doing it? I have an App which consume SOAP and want to give an option to OAuth login to avoid user entering credentials to the App.
Thanks a lot.
You can take the access token resulting from your OAuth flow and use it in the same place that you'd use a sessionId in the SOAP API (i.e. you'd send it in the SessionHeader header in your soap requests). Remember that you'll need to include API scope when you start the OAuth flow.