I have a custom policy in B2C which is calling a rest api. Currently, when running the policy, when the technical profile which calls the rest api is reached, the profile waits for the api to return a response.
After adding the rest api in, there is now a noticeable additional delay in the time it takes for the policy to complete. Which will be the time it takes for the rest api to run.
However, my rest api is used to just pass a set of data in. There is no value that the api returns to B2C that is then used. Is it therefore possible to change the custom policy so that once the call to the rest api is made, then it doesn't wait for a response from it, but instead carries on with the next step in the custom policy?
As far as I know, no you cannot change that behaviour. I would suggest to change the API it is calling to send a queue message to start a background job to do the work. Then the API can return back faster and B2C won't need to wait for the work to finish.
Related
I have service Ticketing and a service Auth.
Not everyone is allowed to perform CRUD on tickets.
When a request comes to perform an action the ticket, I need to check if the user has proper right.
For that I need to communicate to service Auth which holds roles and endpoints of allowed permissions on the resource for a user.
How can I make this call?
Should I make sync call? i.e. Direct call from service A to B?
Use event bus
Or any other possible ways?
Also, there are some tables that is needed from Auth service to join with Ticketing service to fetch data.
How this issue can be solved?
Given the microservices tag, I assume Ticketing and Auth are separate microservices.
I am also assuming, based on description, that each has it's own API.
What's not quite clear, is how the user accessed the Ticketing service. Were they authenticated first (e.g. if a human user via a web application, did they login first, prior to being directed to Ticketing in some manner).
I assume a login was performed first.
An approach might be
At the point of user login (or caller if non-human) obtain the list of authorizations the user has access to via the Auth service.
Store the authorizations within the HTTP Authorization header
As each microservice is called, it then only need (synchronously) ask the Auth service to validate the list of authorizations is correct.
An appropriate technology approach is JWT.
In the scenario described above, when Auth is first called to authenticate the user/caller, the authorizations could be returned within the sub claim, or you could create your own claim to determine authorizations used.
As the user/caller moves through different microservices, a syncrhonous call to the Auth service need only be made to validate the user/caller is authorized.
Synchronous or asynchronous: regardless of direct call/event bus, if an authorization check is required, it needs to complete before the calling service takes action. Otherwise it may expose data / modify it, when the caller did not have authorization.
Joining tables: in a microservice pattern, this is not likely to be wise. Rather, obtain the data required from the Auth service via an API call and use that with the calling service (e.g. Ticketing).
I am working on an Azure B2C custom policy with a rest API call. When a user signs up or signs in, i'm hitting an api endpoint to get user information and add it back to the claims.
However, when a user is not found in the external system(such as during sign up), the api will throw a 404. When this happens the error is posted in the url and the user flow errors out.
What I would like to do is ignore the 404 error and continue to the next orchestration step where we can then check if we got any information back from the api, and if not, hit another api endpoint to generate the users info and continue on with the sign up/sign in flow.
I've been looking for ways to do this, and the only answer i've seen is about handling errors from the api side which is very difficult in this situation due to access constraints.
Whenever your API sends a non 200 response to AAD B2C, it will halt the execution of the journey. If there is a page displayed to the user, and the REST API call is run as a validation technical profile, then the error is displayed on screen. Otherwise the error is sent to the App URL.
In a Validation Technical profile, you can change this behavior by using the ContinueOnError property.
https://learn.microsoft.com/en-us/azure/active-directory-b2c/validation-technical-profile
Call the REST API technical profile via a Validation Technical profile, then add the flag ContinueOnError="true" .
<ValidationTechnicalProfile ReferenceId="REST-ReadProfileFromCustomerDatabase" ContinueOnError="true" >
Context
We have created a custom policy used when users are invited to our SPA application.
The policy does one time user initialization like creating records in our database by invoking the REST API capabilities. Everything here works as expected: The custom logic is executed and we get and id token back.
The problem starts when we are supposed to get an access token for a protected API when invoking the msal.js method
"acquireTokenSilent".
We now see, that the custom policy is executed again, the REST endpoint is once again executed and it's trying to create the user again.
Question
Isn't it possible to get an access token without executing all business logic defined in a custom policy?
I thought that getting an acccesstoken was completely separate from the policy, since we are already authenticated when we got the id token.
acquireTokenSilent in MSAL.js 1.x uses an iframe that runs through the login with prompt=none.
So in the case of implicit grant flow (which is used here), the answer is that it runs through the login flow every time the token is refreshed.
There are a couple choices here:
Make the API endpoint idempotent, i.e. allow calling it multiple times (but ignore the request if the user already exists)
Set a claim on the user that is stored in session state (SSO) and skip the REST API orchestration step if that claim has a value (or you can use the objectIdFromSession claim, which I think is there in the starter template)
The first option is sort of the simplest, and I assume you've already made it like that since it would be called again also when the user logs out and logs back in.
It might result in a lot of requests to that API though.
To avoid that, you could use the newUser claim or set an extension property on the user after the API call.
When calling acquireTokenSilent(), pass in a new authority for a normal Sign In policy. That Sign In policy needs to have session management (SM-AAD) and the same SM-AAD SM technical profile must be present in a technical profile within your invite policy, such that the user can get SSO via the Sign In policy after using the Invite policy.
I want to create a Lambda function that uses the Google Tasks API to add tasks every evening at a certain time.
I am unsure of how to authenticate with my account and be able to store access tokens / credentials securely in my lambda environment variables.
As I understand it since my lambda is making a request on behalf of a user (which will always be me in this case) it seems like everything in the docs points to needing to use OAuth2.0 to authenticate which makes sense since you'd want the user's permission to make changes in their account. However since I only want to do so on my account, I wanted to know if there was a way to simply authorize my account without doing a OAuth flow which I don't believe is possible from a lambda since I won't be responding to it every time it runs.
How would I authenticate my application so I can make calls to the tasks API and be authenticated against my account?
This is surprisingly more work than I'd imagined and unfortunately google doesn't generate developer tokens which would have solved a lot of this problem.
Authorization & Consent
There are no immediate ways of authorizing your account for the app that you've created without going through the consent flow. Some cloud service providers generate a developer token for testing your app with your credentials - but google doesn't seem to have this functionality. Not for the Tasks API anyways. AdWords API talks about a developer token but I'm not sure if it's the same concept.
You won't have to re-authorize once you've given consent. This general principal applies to other OAuth using parties, unless the level of consent changes (example: the app starts asking for write permissions in addition to previously consented read) you won't get re-prompted. If permission levels change, you'll get re-prompted.
Now - the second part - how do you make one?
Google explains it in detail here - but I'll further simplify because you don't need to setup a web-server for your case, you're only doing this for yourself.
Our goal is to only to get you the initial refresh token. Once you've retrieved the refresh token, you can use that from your Lambda to retrieve a new access + refresh token whenever you're accessing the tasks API. You just need to keep the refresh token stored somewhere, so you can continuously keep on accessing the tasks API. You're just looking to get the access + refresh token.
Head over to https://console.developers.google.com and create a new application.
After the creation, click 'Enable APIs and Services' and look for Tasks API.
Proceed with creating the credentials and make sure you select you'll be calling this API from a Web Server. Selecting Browser (JavaScript) would only give you an access token and not a refresh token, because they would trust you to store the refresh token on your server, but not on a browser. An access token is time-limited to (conventionally) 60 minutes.
You should also select the User Data / Information and not the App Data / Information for the types of data you want to access. The app one is generally used for GSuite.
Set your redirect uri to be http://localhost:8080 - This is where you normally would need a web-server but we'll just redirect back to your machine and get the parameter from here. It obviously won't find a web-server but the parameter we want is in the url, we'll just copy it.
Now here comes the authentication part. Google's auth url is: https://accounts.google.com/o/oauth2/v2/auth
We will add parameters to this url
access_type=offline // so your daemon app can access it offline
response_type=code // required if you have access_type=offline
scope=https://www.googleapis.com/auth/tasks // what do you want to access to
redirect_uri=http://localhost:8080 // where would google send the code
client_id=
so the whole thing should look like https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&response_type=code&scope=https://www.googleapis.com/auth/tasks&redirect_uri=http://localhost:8080&client_id=
Go to this URL and you should get prompted for consent.
Consent to it and google should redirect you to http://localhost:8080/?code= We'll need that code. That needs to be sent to google to get an access + refresh token.
Code exchange: Make a post request to Google. You can use PostMan. Again normally all of this would be automatically handled by a webserver (detect code parameter, make post request etc..) - but we just need the refresh token here, so we can stick that into our Lambda app.
POST to:
https://www.googleapis.com/oauth2/v4/token
with parameters:
code=<the code you've retrieved>
client_id=<your_client_id>&
client_secret=<your_client_secret>&
redirect_uri=http://localhost:8080&
grant_type=authorization_code
Google should return you the access token and the refresh token. From this point on you need to save the refresh token into your Lambda app - and if it's running on a scheduled job on every bootup:
Read the refresh token
Call Google for a new refresh token + access token
Save the new refresh token.
Use the access token to access your Tasks API.
Let's say I have Instagram connector inside my Logic App workflow, authenticated and authorized to perform actions on my behalf.
I can see this connection stored in "$connections": sections but there is no access token or anything that really makes this connection work with instagram API.
The problem here is that available Logic App actions for Instagram are way from complete and for some API calls I have to use plain HTTP action and inject my access token manually.
My question - where is in general this information is stored by Logic App (OAuth tokens and so on) and how to access it inside workflow?
This is not available. I see what you want to do - if Instagram introduced a new API Logic Apps doesn't support, it would be cool to use a generic HTTP action, but use the token Logic Apps already retrieved for auth.
This is not possible because, it would be a violation of the terms of use for third party services to make token available so end users can make any arbitrary call, since it may be abused. And this would risk all Logic Apps user lossing the ability to communicate with said service when our API key is revoked.