API Security
The subset of APIs available in the API Specification page have no authentication needed in order to make them easier to explore and understand. When you access the same APIs in the Infor Cloud the Infor ION API Gateway will always enforce OAuth2 type authentication to any client trying to access the APIs. The information below is provided to help you understand how to programmatically authenticate to the APIs in the Infor Cloud.
Choosing a Grant Type
OAuth2 supports different flows to securely consume APIs for different access patterns. Of the various grants, the ION API Gateway supports the following grants –
- Authorization code Grant – suitable for Native mobile/desktop apps, Web Apps
- Implicit Grant – suitable for single page/user agent-based applications
- Resource Owner Grant – suitable for server-to-server access i.e. backend service client. In these cases, the user/resource owner is not present for authorization so service accounts are used for backchannel authentication and authorization.
- SAML Bearer Grant – suitable for applications plugged in with Infor Ming.le (i.e. apps that have SSO with Ming.le federation hub).
Based on your client’s access pattern, you need to implement the appropriate OAuth2 Grant. Here is a decision flow to help you choose an OAuth2 grant:
Backend Applications (Java, .Net or Golang)
For backend applications, those applications that do not have a user available to authenticate, the recommended grant to use is resource owner. Given the disparity in the location of the Infor Ming.le identities, a new set of credentials is being used for the resource owner grant. Through the resource owner grant, only service accounts will be authenticated. A Service Account can be associated with a user, therefore, making the call to the backend application on behalf of the user. The administrator of the Infor ION API gateway will create the service account in IFS and register your application.
Registering your Backend Application to Obtain an OAuth ClientID and Secret In addition to a Service Account to act as the “user” your backend Application will have to be registered. During the process of registering your backend application, an OAuth ClientID and Client-Secret will be generated for your application. You will need all of the following four pieces of information when contacting the Infor Authorization Server in order to obtain an OAuth 2.0 Bearer token that your backend application can you to make API requests via the ION API Gateway:
- Application ClientID
- Application Client-Secret
- Service Account AccessKey
- Service Account SecretKey
Example HTTP Request for OAuth2 Resource Owner grant OAuth2 resource owner grant facilitates obtaining access token for backend services using backchannel HTTP POST request to auth server token endpoint (e.g. as/token or connect/token) using following params-
- grant_type = password (fixed)
- username = service account accesskey
- password = service account secretkey
- client_id = authorized app
- client id client_secret = authorized app
- client secret scope = oauth2 scope (Optional)
.NET Applications
There are multiple OAuth2.0 libraries available but one that could be used is: http://www.nuget.org/packages/Thinktecture.IdentityModel.Client/ It provides a library with utility functions to implement the OAuth2.0 protocol. The client application can leverage the library to construct the correct url query parameters and the form post required as part of the interaction with the Authorization service.
Sample Application
A .NET sample application is provided in this SDK and leverages the Thinktecture library in order to obtain/refresh/revoke tokens and call a webservice client with the token. The sample client showcases the functionality available by the library. The Sample application has been inspired by the samples from the Thinktecture team located at: https://github.com/IdentityServer/IdentityServer3.Samples/tree/master/source/Clients
The sample app tries to showcase the interaction of the client with the authorization service. This sample app does not treat the access_token or refresh_token securely. Maintaining the access_token and refresh_token secure is the responsibility of the final application and should be secured as any other existing secret.
Key interactions Create client
_oauth2 = new OAuth2Client(new Uri(OAuth2TokenEndpoint), ResourceOwnerClientId, ResourceOwnerClientSecret);
With the provided token_endpoint, ClientId and ClientSecret it is possible to construct a client to use in further interactions. It will be able to make requests authenticating using the ClientId and ClientSecret.
Obtain access_token
_oauth2.RequestResourceOwnerPasswordAsync(ServiceAccountAccessKey, ServiceAccountSecretKey).Result;
With the service account accessKey and secretKey it is possible to request an access token. The response will be of type TokenResponse. This will contain whether has been an error in obtaining the token. If successful then it will include the access_token and if available for the client the refresh_token. Calling service With the token from the TokenResponse it is possible to call the service by passing the access token as a bearer token.
var client = new HttpClient
{
BaseAddress = new Uri(IONAPIBaseUrl)
};
client.SetBearerToken(token);
var response = client.GetAsync("M3/m3api-rest/execute/CRS610MI/ChgFinancial?CUNO=Y30000&BLCD=0").Result;
Refresh token If a refresh token is available as part of the response it is possible to obtain a new access_token and refresh_token without requiring the service account credentials.
_oauth2.RequestRefreshTokenAsync(refreshToken).Result;
Revoke refresh token If a refresh token is provided and there is no longer the need to make calls to the webservice without providing the service account credentials then the refresh token should be revoked.
Currently, the Thinktecture library does not provide a method to revoke the token. But this can be achieved with a method like:
private static void RevokeToken(string token, string tokenType)
{
var client = new HttpClient();
client.SetBasicAuthentication(ResourceOwnerClientId, ResourceOwnerClientSecret);
var postBody = new Dictionary<string, string>
{
{ "token", token },
{ "token_type_hint", tokenType }
};
var result = client.PostAsync(OAuth2TokenRevocationEndpoint, new FormUrlEncodedContent(postBody)).Result;
}
In order to revoke a refresh token, it should be called with the following parameters:
RevokeToken(token.RefreshToken, OAuth2Constants.RefreshToken);
Go applications
Golang provides the package golang.org/x/oauth2 to implement the OAuth2.0 protocol.
Make OAuth 2.0 configuration
The first step is to define a configuration. Reference to downloaded credentials properties will be used in all code examples.
conf := &oauth2.Config{
ClientID: <Application ClientID>,
ClientSecret: <Application Client-Secret>,
Scopes: []string{
"openid profile",
},
Endpoint: oauth2.Endpoint{
AuthURL: <pu> + <oa>,
TokenURL: <pu> + <ot>,
},
}
Obtain tokens
Now it is ready to obtain tokens. The token struct in Go contains both access and refresh tokens.
tok, err := conf.PasswordCredentialsToken(oauth2.NoContext, <Service Account AccessKey>, <Service Account SecretKey>)
if err != nil {
// handle error
}
Create HTTP client and make a request
OAuth 2.0 configuration struct has also a method to create HTTP client for you.
client := conf.Client(oauth2.NoContext, tok)
resp, err := client.Get(<Request URL>)
if err != nil {
// handle error
}
Note: you do not need to refresh the token manually, the client cares about it and will do it automatically.
Revoke tokens
The package does not provide methods to revoke any token. You can do it, by calling revoke service directly.
resp, err := http.Get(<pu> + <or> + "?token=" + tok.RefreshToken)
if err != nil {
// handle error
}
Demonstration
The following demonstration shows how to call an Infor API from a client like Postman.