Modify API OAuth Token Expire Time - rest

Acumatica Version: 2019R1
I'm looking to either modify the expiry time on granted OAuth tokens using a Connected Application within Acumatica. Currently, my token is granted using the 'api' and the 'offline_access' scopes to be able to access the API, and to get a refresh token.
I am trying to avoid using any type of session/cookie-based authentication, as my system will be solely interacting with the Acumatica REST API from a complete external source, and cannot store any session/cookie-related data.
My ultimate end goal would allow my application a specific token for absolute concurrent access without the need for refreshing, but a longer expiry time would most likely suffice.
For background, I have looked within all of the help docs, and through each of the Acumatica Developer Training courses, but none of them explicitly state if the OAuth protocol is editable.
I've looked in the OAuth 2.0 Framework documentation at https://www.rfc-editor.org/rfc/rfc6749, but while it shows that it is possible to modify the token expiry time/completely remove the expiry, it has no specific information on how to modify it, since Acumatica implemented the framework.
Here is the x-www-form-urlencoded request body being sent to grant the initial token:
grant_type: <password>
client_id: <applicationID>#<company>
client_secret: <secret>
username: <username>
password: <password>
scope: api offline_access
Here is the response received from both the initial token request, as well as each request to refresh the token:
{
"access_token": "<accesstoken>",
"expires_in": 3600,
"token_type": "Bearer",
"refresh_token": "<refreshtoken>"
}

From what I am searching through, it seems that Acumatica uses IdentityServer3 to implement the OAuth API for Connected Applications. The clients are entered through the SM303010 screen where you can set the ClientSecrets and RedirectURIs. The attribute in IdentityServer3 to modify would be AccessTokenLifetime.
https://identityserver.github.io/Documentation/docsv2/configuration/clients.html
It is defaulted as 3600 seconds (one hour) and does not seem to give you any entry point to modify.
I would verify with Support, but if it is not available, you can always request the feature to be added on https://feedback.acumatica.com

Related

Enable OAuth2.0 in Grafana Infinity plugin for Citrix data source

I am trying to collect data from REST API using Grafana plug-ins (Infinity, Simple JSON, JSON), The problem is in order to access the API you should maintain a valid OAuth Token which expires every hour and should be refreshed, and it should be pre-fixed by certain word,
EX: 'Authorization' : 'Bearer AUTHTOKEN'
Any idea how to solve this ?
Thanks.
Your Grafana Infinity plugin wants to access the protected Citrix data source.
Citrix is protected with the OAuth 2.0 client credentials grant: that means, Citrix clients must collect a short-lived access token by authenticating themselves with their id and secret and requests to Citrix APIs must include the access token as a bearer token (as the HTTP Authorization header prefixed with Bearer ).
Creating an API client in Citrix gives you your client id, client secret, and additionally, customer id.
Grafana Infinity plugin supports client credentials grant out of the box, meaning once you have Infinity configured with the required parameters (those you got while creating your client in Citrix), it will collect the token and include it as a bearer token for you.
The Infinity plugin documentation doesn't explicitly mention how it handles access token expiration: possibly it requests for a new access token if it detects that the access token has expired (the expiration time is returned as the expires_in value with the access token).
You just need to follow these steps, if you have already logged in through any OAuth mechanism:
Go to Configuration > Data sources.
Add data sources, and select Infinity.
In authentication select Forward OAuth and add some Allowed host. For instance http://:8080/ to allow
any data coming form the quarkus app.
Save and exit, the url will be set in the dashboard.

How do I get the personal access token name using the Tableau REST API

I am creating an application to interact with Tableau's REST API.
I am using Tableaus Online Server to host the workbooks/groups/users etc.
What I need is a way to let a user sign in and then interact with the REST API without having to store a username and password for server authentication.
Currently, if someone wanted to get a list of workbooks, they would need the following code
import tableauserverclient as TSC
tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD', site_id='CONTENTURL')
server = TSC.Server('https://SERVER_URL', use_server_version=True)
server.auth.sign_in(tableau_auth)
Tableau does use personal access tokens and I can authenticate like this
import tableauserverclient as TSC
tableau_auth = TSC.PersonalAccessTokenAuth('TOKEN-NAME', 'TOKEN-VALUE', site_id='CONTENTURL')
server = TSC.Server('https://SERVER_URL', use_server_version=True)
server.auth.sign_in(tableau_auth)
The problem I am running into is that signing in with a username and password only returns a token value. I don't think this is meant to be the same as the personal access token, but can I use this token value to authenticate the user and do other actions with the REST API?
The structure of the signin response is
{
credentials: {
site: {id: ...},
user: {id: ...},
token: tokenValue
}
}
You can also create a personal access token manually on the tableau online server. Is there a way to get this value after signing in with a username and password?
Okay, so I kinda figured it out like a few minutes after posting this. And if anyone else gets a little confused when working with the Tableau REST API and their authentication, I hope this helps a little bit.
There is a python package called tableauserverclient and it's supposed to make interacting with the REST API easier. It does, except I don't believe there is a way to pass values to the header of the request. Which is how they manage the access tokens after signing in (and the personal access token is a completely separate thing).
So, when a user signs in, they receive an access token that can be used later to authenticate other services. But, the token needs to be passed in the header as the X-Tableau-Auth value.
So, while the TSC library simplifies and python-izes some of the requests, it doesn't allow you to utilize the access token from sign in.

REST Validating token in business API generated by authentication service

I have two different REST API’s say Authentication API & Business API hosted in Windows azure.
Authentication API is responsible for authenticating user using WsFederation or OpenID or custom authentication
Business API is responsible for executing business logic. Only legitimate user should be able to access this API.
Client will contact first Authentication API and will acquire the token and then it will pass that token to Business API.
Since client can send any token to business API. Business has to validate the token. It simply cannot trust on the token. Since token Is generated by Authentication API, how business API will validate the token.
What is a standard way to validate the token in such scenario where Authentication API and Business API are hosted separately?
Good References
Principles of Token Validation (Vittorio's blog) - Awesome article, most of the information is generic so applies with or without Azure AD, and it's coming from a very knowledgeable author of course
Manually validating a JWT access token in a web API - This one is specific to validating an Azure AD issued token. Has complete code implementation too. You don't need to do exactly this, because your validation will depend on token format/claims that you use but may provide a helpful reference.
You can look at how token validation is recommended for applications secured by Azure Active Directory as a case study (and may be some other systems as well), then decide what works best for your case.
Brief explanation on how Azure AD example is relevant.. as validating received token is required just like in your case
When you develop any web API (or web app) secured by Azure Active Directory and use bearer token based authentication, the way things flow is very similar to what you explain above with your 2 APIs (just for understanding purpose, your authentication API is doing what Azure AD token endpoints would do.. i.e. provide a valid token).
To access the secure web API, calling application/client first interacts with Azure AD endpoints to get a relevant token for required resource, then it sends a request for actual resource along with the token in Authorization header to the web API. Now, the first thing web API does is to validate this token and only if everything is correct continue with execution to eventually return a response. I hope this matches at a high level with your flow.
What to validate?
1. Token Signature
The key used to sign the issued token is uniquely associated to the issuing authority, so nobody else can issue a token with your Authority's signature.
a. This helps to check that the token was in fact issued by Azure AD (or in your case your trusted STS, using the Authentication API you mention).
b. This also makes sure that since the token was issued and till it reached your web API, no body has tampered with it. If any attempt is made to change any information in the token, the signature will break.
2. Token Claims
This will depend on what claims/information you send as part of the token (for example, if same Authentication API issues tokens for multiple different APIs, then something like audience and issuer might make sense for you as well. Token validity time period using something like nbf and exp below are also pretty generic)
Taking Azure AD issued tokens as example here are the important ones that should be validated:
audience claim (aud), to verify that the token was intended to be given to your application
not before (nbf) and expiration time (exp) claims, to verify that the token has been received within it's validity period
issuer claim (iss), to verify that that token was in fact issued by the said authority. Notice this is a second way, apart from signature for the same purpose and generally both signature and issuer check are used together. (See Vittorio's blog)
nonce, as a token replay attack mitigation
tenant claim (tid), to verify the tenant. This is useful in case of multi-tenant applications.
Sample JWT Token from Azure AD
Actual Value: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1N... (a long encoded string continues) Decoded Value (you can check this easily using a website like https://jwt.ms or https://jwt.io):
{
"aud": "https://service.contoso.com/",
"iss": "https://sts.windows.net/7fe81447-da57-4385-becb-6de57f21477e/",
"iat": 1388440863,
"nbf": 1388440863,
"exp": 1388444763,
"ver": "1.0",
"tid": "7fe81447-da57-4385-becb-6de57f21477e",
"oid": "68389ae2-62fa-4b18-91fe-53dd109d74f5",
"upn": "frankm#contoso.com",
"unique_name": "frankm#contoso.com",
"sub": "deNqIj9IOE9PWJWbHsftXt2EabPVl0Cj8QAmefRLV98",
"family_name": "Miller",
"given_name": "Frank",
"appid": "2d4d11a2-f814-46a7-890a-274a72a7309e",
"appidacr": "0",
"scp": "user_impersonation",
"acr": "1"
}
How to do token validation?
Make use of standard libraries as much as possible. See the code implementation sample Manually validating a JWT access token in a web API. This one makes use of JwtSecurityTokenHandler.ValidateToken Method (JwtSecurityToken). Your case will depend on your token format/implementation etc.

Use LinkedIn JSAPI credentials cookie to authenticate a user

We would like to implement "Sign-in with LinkedIn" in our app. Since the app has JS fronted and RESt-based backend, we decided to exchange JSAPI tokens for REST API OAuth tokens as described here.
If a user successfully signs in, the frontend sends credentials cookie with client-side bearer token and member ID to the backend. On the backend we check if a user with such a member ID already exists and if not, we exchange JSAPI token for REST API OAuth token, retrieve user details from LinkedIn a store it in our database.
Now the question is if we can use that cookie to authenticate each user's request to our REST backend. After a user successfully signed in via JSAPI, the cookie should be automatically passed to our backend on all subsequent requests so we can check member ID. Are there any drawbacks that we missed? Or is this idea as a whole wrong?
Should we rather authenticate a user only once by means of the cookie and then issue our own authentication token and send it back to the client?
The way cookies work in general is they are passed on every request to the domain they belong to. LinkedIn is setting a credentials cookie to your domain.
As long as you are validating those credentials on every request it's perfectly acceptable to use their tokens as authentication.
Personally I don't find that to be a great idea and would prefer to validate their credentials once and create my own auth token to use from there on out. You can always set that token to expire at some-point and re-validate the LinkedIn credentials (which will still be getting sent on every request anyway). This limits the amount of times you're checking with LinkedIn and should increase the responsiveness of your app.
Either way could work.
If you are using the LinkedIn cookie to validate a user by member id, you should validate the cookie's signature on each request per section 2 of the doc you linked and question 2 of the FAQ.
Using your own token could make it easier to implement an account which belongs to your app and is not necessarily connected to LinkedIn, assuming there's the potential to either connect solely with some other service(s) or no 3rd part(y/ies). Still should validate any time you trust the member id in the cookie though.
The doc provides a validation example in PHP, and if you're interested in improving a ruby version, I have a shameless plug.
The flow that you've outlined in your latest comment of going straight for the OAuth tokens is the best way to go if you were only signing in to convert the JSAPI tokens to OAuth tokens and then not using the JSAPI further. If you were planning to actually use both the JSAPI tokens within your front-end app and the OAuth tokens on your back-end, then it's better to take the conversion route.

Facebook OAuth 2.0 "code" and "token"

Why do you need both a "code" and a "token" in the Facebook OAuth2 authentication flow as described here: https://developers.facebook.com/docs/authentication/ ?
If you look at the OAuth dialog reference (https://developers.facebook.com/docs/reference/dialogs/oauth/), it seems like you only ever use the token to fetch information about the user, and if you specify the response_type parameter as token or code,token, then you get the token on the first time.
Why do you need to get a "code" and then use the code to get a "token" as opposed to getting the token directly?
I guess I'm misunderstanding something basic about how OAuth works, but it seems you avoid the request to https://graph.facebook.com/oauth/access_token entirely if you get the token the first time with the dialog.
Let us take a simple example to differentiate authentication code vs access token.
You as a user want to try a new Facebook app called Highjack.
So you click on the application and the Highjack app asks you to log into your Facebook account. When you are done, Facebook generates an authentication code for you.
This code is then passed to the Highjack server which uses its own FB client id, FB secret and your authentication code to get an access token.
In the above example the authentication code is confirming you as a user is a valid FB user. But the second steps says "you as a FB user is giving access to the Highjack app for certain resources".
If the Highjack app wanted implicit grant (i.e direct access token), then the access token would be visible to you also since it is being exchanged with the browser. This means you can now call all Facebook APIs on behalf of Highjack using the access token. (You can only use the access token to get your personal information but Facebook has no way of knowing who is calling their APIs.)
Since we have 2 parties (You and Highjack) authenticating with Facebook we have this 2 fold mechanism.
Borrowed shamelessly from Salesforce Documentation:
Authorization Code
An authorization code is a short-lived token representing the user's access grant, created by the authorization server and passed to the client application via the browser. The client application sends the authorization code to the authorization server to obtain an access token and, optionally, a refresh token.
Access Token
The access token is used by the client to make authenticated requests on behalf of the end user. It has a longer lifetime than the authorization code, typically on the order of minutes or hours. When the access token expires, attempts to use it will fail, and a new access token must be obtained via a refresh token.
From the OAuth 2.0 Spec:
The authorization code provides a few important security benefits
such as the ability to authenticate the client, and the transmission
of the access token directly to the client without passing it through
the resource owner's user-agent, potentially exposing it to others,
including the resource owner.
So, basically - the main reason is to limit the # of actors getting the access token.
"token" response is intended primarily for clients that live in the browser (e.g.: JavaScript client).
Answer) You need/want both the code and token for extra security.
According to Nate Barbettini we want the extra step of exchanging the authentication code for the access token, because the authentication code can be used in the front channel (less secure), and the access token can be used in the back channel (more secure).
Thus, the security benefit is that the access token isn't exposed to the browser, and thus cannot be intercepted/grabbed from a browser. We trust the web server more, which communicates via back channels. The access token, which is secret, can then remain on the web server, and not be exposed to the browser (i.e. front channels).
For more information, watch this fantastic video:
OAuth 2.0 and OpenID Connect (in plain English)
https://youtu.be/996OiexHze0?t=26m30s (Start 26 mins)
If you look at the flow of Authorization Code OAuth type, yes, there are actuary two steps:
<user_session_id, client_id> => authorization_code
<client_id, redirect_uri, authorization_code, client_secret> => access_token, refresh_token
In step1: the user tells the OAuth Server that "I want to auth this client (client_id) to access my resource. Here is my authentication (user_session_id or what else)"
In step2: the client (client_id) tells the OAuth server that "I've got the user the authorization (authorization_code), please give me an access token for later access. And this is my authentication (client_id & client_secret)"
You see, if we omit step 2, then there is no guarantee for client authentication. Any client can invoke step1 with a different client_id and get an access token for that client_id instead of its own. That's why we need step2.
If you really want to combine step1 and step2, you can do something like this:
<client_id, redirect_uri, client_secret> => access_token, refresh_token
We use this approach in our Open API Platform, and we haven't find any security problem yet.
BTW, there is actually an Implicit Grant type, that is:
<client_id, redirect_uri> => access_token, refresh_token
It is generally applicable to client only application which have no server backend. In that case, the OAuth server must ensure that the redirect URI belongs to that client (same with the register redirect_uri, for example).
The mix-up came because the user on behalf of himself and not the client app authenticate against the authorization server (i.e. facebook).
Its much simple to secure the client app (with https) then the user-agent (browser).
Here is the original formulation from IETF-oauth (https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-threatmodel-08#section-3.4):
3.4. Authorization Code
An authorization code represents the intermediate result of a
successful end-user authorization process and is used by the client
to obtain access and refresh token. Authorization codes are sent to
the client's redirection URI instead of tokens for two purposes.
Browser-based flows expose protocol parameters to potential
attackers via URI query parameters (HTTP referrer), the browser
cache, or log file entries and could be replayed. In order to
reduce this threat, short-lived authorization codes are passed
instead of tokens and exchanged for tokens over a more secure
direct connection between client and authorization server.
It is much simpler to authenticate clients during the direct
request between client and authorization server than in the
context of the indirect authorization request. The latter would
require digital signatures.
Theoretically,
Access Tokens cannot tell us if the user has authenticated but auth code does.
Auth code should not be used to gain access to an API but access token should be.
If you have a single page application or mobile application with no or minimum backend, your application may want to access user's FB data directly at frontend. Hence the access token is provided.
In another case, you may want a user to register/login to your app using some external auth service provider like Facebook, Google etc. In this case, your frontend will send the auth code to the backend that can be used to get access token from Facebook at serverside. Now your server becomes enabled to access user's FB data from the server.
Basically, as an extension of Lix's answer, the access code route allows a Resource Owner (i.e. the Facebook User) to revoke authorization for their User Agent (i.e. their browser), e.g. by logging off, without revoking authorization for an offline Client (i.e. Your Application).
If this is not important, then there is no need to use the access code route.
Furthermore, the access code is provided to ensure that the Token provided to a server is actually registered to the Resource Owner (i.e. the Facebook User), and not the User Agent (or a Man-in-the-Middle).
This seems similar to the question of either choosing the implicit vs authorization code grant flow. In fact, here is what looks like an opposite view point?!.
Also, as Drew mentioned,
When the access token expires, attempts to use it will fail, and a new access token must be obtained via a refresh token.
another piece is the refresh token, but I don't see that being explained too well in the FB Docs. If I'm correct, the implicit grant (the direct token) should be really short lived, but that is to-be-enforced and FB.js seems to hide a lot of that (this one I have not looked as deep into).
If I'm correct, the code%20token is an optimization allowing both the User Agent to have a token and allowing for the server to initiate the token exchange process in a single request (as anything over Network IO is considered expensive, especially to a User Agent).
In OAuth 2.0 with facebook, the overall concept is simple as follows.
Step 1. Obtain "Authorization Code" by a GET request
request URI: https://www.facebook.com/dialog/oauth
Params:
response_type=code
client_id={add your "App id" got by registering app}
redirect_uri={add redirect uri defined at the registration of app}
scope={add the scope needed in your app}
Headers: None
Step 2. Obtain the "Access Token" by sending the authorization code as a POST request
URI: https://graph.facebook.com/oauth/access_token
Params:
grant_type=authorization_code
client_id=<add your "App id" got by registering app>
redirect_uri=<add redirect uri defined at the registration of app>
code=<obtained authorization code from previous step>
Headers:
Authorization:Basic encode <App Id:App Secret> with base64
Content-Type:application/json
Step 3. Use the access token got from above step and retrieve user resources
It’s because the access token is given to an AUTHENTICATED client (third-party app) using a shared secret that only FB and the client knows. The only way that the user could directly request the access token is by knowing the shared secret, which would make the secret public and could lead to a man-in-the-middle attack. Further, while FB can guarantee a secure connection to the user, FB can’t guarantee the handoff of the token to the client is secure. However, FB (and OAuth2) does require a secure connection between the client and FB. The access token is tied to the client public ID (usually hashed), which means only the original client application can use it to request the token because the secret is sent along with the authorization code to get the access token.
You recieve a token when the user logs in. But you might want to change the token when you are performing other actions. EG posting as your app/page or posting as a user with offline_access.