I am building a React-based SPA that communicates with a spring-boot backend via a REST API. I need the user to be able to log into their Microsoft account on the browser client (the SPA) and I need the backend service (spring-boot app) to be able to query Microsoft's Graph API on behalf of that user.
After reading up on the Oauth2 flows, the authorization code flow (not the PKCE flow, just the regular authorization code flow) seems the most appropriate. The browser client could let the user log into their Microsoft account, retrieve an authorization code, and send the authorization code to our backend service via HTTP request. The backend service (which is trusted and can safely store a client secret) can then request an access token, make requests to the Graph API directly (meaning that the SPA would never need to make any requests to the Graph API), and silently refresh the token as needed.
However, I cannot see any examples of anyone using this flow to access Microsoft's Graph API.
Looking at Microsoft's documentation, it seems like they recommend using the on-behalf-of flow. But this flow requires the browser client to request an access token and then use that to communicate with the backend service (which in turn can communicate with the Graph API). It doesn't make sense to me why the access token cannot be requested on the backend using a client secret. Wouldn't this be a more secure and preferred method than having the client retrieve the access token, as is done in the on-behalf-of flow?
The Oauth2.0 site, recommends that SPAs should either use the authorization code with PKE or the implicit flow, but I do not see an option to use the standard authentication code flow for SPAs. Should I take this as an indication that SPAs should not be using the standard authorization code flow as I described earlier?
Despite not finding a clear-cut example of the standard authorization code flow in Microsoft's documentation for a react frontend + java backend, I tried to go about doing this myself. However, using the #microsoft/mgt-react and #microsoft/mgt-element libraries to do this are not straight forward. For example, the #microsoft/mgt-element notion of a Provider supports a call to retrieve an access token, but doesn't clearly expose the authorization code. If I wanted to do the authorization code flow described earlier, it seems like I would need to use raw HTTP requests, which I know is not a recommended way of accomplishing this.
Summarizing my questions:
What OAuth2.0 flow should I be using: 1) authorization code (access token is retrieved by backend service using client secret), 2)
authorization code with PKE (access token is retrieved by client), or
3) on-behalf-of flow (access token is retrieved by client, seems to be an extension of PKE flow)?
If using the on-behalf-of flow, does the SPA just include the access token in the header (marked as 'bearer') and the backend service just
includes that same header to query the Graph API, or does the backend
service need to request another token before querying the Graph API?
Agree with #ch4mp to call graph api directly in SPA if it's allowed. If not, then I recommend you using on-behalf-flow or client credential flow based on your requirement.
Let's come back to your requirement -- call ms graph api in a springboot api project. First, let's see one of the graph api getting user api. You can see permission types here: Delegated which means call graph api on behalf of the user, Application which means calling api on behalf of the application(your spingboot api project) itself. If you want to call api behalf of the user, then you have to use on-behalf-of flow. This is because the api project which will be considered as a daemon application, so the project itself doesn't have a UI page to let users enter username/password to sign in and get authenticated.
You can certainly use ROPC flow which have to pass the username/password to api but I really think it unsafe, so I don't recommend.
If it's not necessary for you to call graph api on behalf of user, you can certainly take client credential flow into consideration. But pls note here, application type api permission is a "large" api permission which always have name like User.ReadWrite.All, Mail.ReadWrite.All and it always means the application can not only query user information but also be able to modify user information.
If you want to use on-behalf-flow, then you may review this answer and it explained the whole progress...
I would use authorization-code flow (with PKCE) to get an access-token and then refresh-token flow to "maintain" this token, both from client.
Authorizing the request to your resource-server with this token only makes sense if Microsoft authorization-server is your main authorization-server. Otherwise (user also logged in with an authorization-server of your own or not using OAuth2 betwean React and backend), you can still send Microsoft access-token in request body.
In any case, when issuing requests in the name of the user from the backend, do as you suggest: just set the access-token sent by the client as Bearer Authorization header (token is retrieved either from Spring security context or request body). Backend fetches a new access-token (using client-credentials flow) when issuing requests in its own name (without the context of a user).
Side note: have you considered calling Microsoft API directly from React client? If you don't have to store the result of that call on your resource-server (i.e. call graph API to display data and store only what user selected from that data), that would save quite some latency on the client and costs (network and CPU) on the backend.
I want to create an API with Mulesoft to be able to obtain the token from calling the OAuth2 Ping provider.
I want to call External REST API in my Domain Service, what is the best way to do that in abp framework, and where I can put this API Url and how to get it in my Domain Service?
ABP Framework version: v5.3
Project Type: MVC
You can simply use a http client, like RestSharp (https://restsharp.dev/) to be able to call an external api.
Since the api url might change, you can add it in the appsettings.json file and inject Microsoft.Extensions.Configuration.IConfiguration into your domain service constructor.
I have a scenario where I have an on-premise GUI application which has a "Web Service Invoke" component which I use to call a GAE API.
In the GUI application, it is possible to:
store credentials
create a chain of web services/http(s) calls that can integrate an output of preceding https(s) call as a query parameter or header value into the next http(s) call
retrieve a value from JSON response of the http(s) call
But it is not possible to programmatically do anything. The Web Service widget has fields for passing API URL, query parameters and headers only.
I'm looking to do a service-to-service authentication for the API call and the API should be protected using IAP as well.
I'm aware of the recommended approach is to create a service account and provide the service account JSON key file to the client and the client signs a JWT token and pass it as a bearer token. But as I only have widgets, no programming possible, therefore signing JWT token is not an option.
I was looking at Google OAuth or IAM APIs which can support "client_credentials" grant type wherein I can get an access token using just clientId and clientSecret - something possible in Apigee. But it seems this grant type is not supported by Google OAuth APIs.
I also looked at Cloud Endpoints using API KEY - so the current thought is to the client passes API KEY in header/parameter for authentication to Cloud Endpoints, then Cloud Endpoints uses its service account to get access through IAP, and finally, I'm thinking that the client can also send in "Basic Auth" credentials through Authorization header which the GAE API backend service validates. The additional "Basic Auth" is because Google recommends using another auth method in addition to API KEY.
I would like a simpler solution if possible using GAE and IAP only. Any other suggestions, especially using time-limited tokens, that can work over only http(s) calls (non-programmatic or client library), is much appreciated.
Any alternatives or things to try is also appreciated.
Look into this server-to-server authentication using JWT Google API Authentication
I have exposed my camel project as a rest web service. http://localhost:9090/route/restservice/getQuote
How do i identify that the incoming request is SOAP or rest - if it is REST or SOAP (are there any headers to identify)
if it is SOAP how can I convert SOAP to rest in camel/routes ?
Thanks