Aras Innovator introduced an Authentication Server feature in 11.0 SP12 and has been fleshing it out with each new service pack. In 11.0 SP15, it is possible to request an OAuth token from this server that can be used with the RESTful API as an alternative to basic authentication. Using tokens is preferred for external apps as they don't require you to keep your users' passwords in memory while your app runs. Because tokens expire after a set time, you can also rest assured that if a malicious party later acquires the token, they won't have access to your system.
In this blog post, we'll be going over examples of both requesting an OAuth token from the Aras Innovator server as well as using that token to authenticate additional requests. You can also check out this Authentication Example on GitHub for a simple app that will request a token and use that token to query the Parts in a database.
Register Your App
One of the features of the Authentication Server is to limit what apps can request a token. The Authentication Server keeps a list of registered apps that are able to request tokens, so external applications cannot get tokens by default. If you don't wish to do any additional configuration, you can use the default "IOMApp" client registry. However, we recommend adding a new client registry to register your app with the server by following the steps below.
- Open the OAuthServerOAuth.config in your preferred text editor
- Scroll down to the bottom until you see <clientRegistry id="IOMApp">
- Copy this node and all of its child nodes
- Paste them as a new section just below the original node
- Give a new ID to this registry corresponding to the purpose of your app
- Make sure this new registry has enabled="true"
Make note of the ID you give this new registry. You will need to use it in the body of your request for a token which is covered later in this blog.
Get the OAuthServer URL
The first thing we'll want to do is query for the location of the OAuthServer. Because Aras Innovator allows most of its components to exist on separate servers, the OAuthServer may not be available from the same server as our Instance URL. However, the Innovator Server does have a way to query for this information by appending /Server/OAuthServerDiscovery.aspx to the end of your Instance URL: http://localhost/InnovatorServer/Server/OAuthServerDiscovery.aspx .
If you're using something like Postman to follow along with this blog, you can simply perform a get request on this URL with an empty body. The result of this request should look something like below.
{
"locations": [
{
"uri": "http://localhost/InnovatorServer/oauthserver/"
}
]
}
The URL we will use is stored in the uri property of the JSON returned from our request. The JSON path you can use to retrieve this information is locations[0].uri.
Get the Token Endpoint
Now that we have the URL of the OAuthServer, we will need to retrieve the exact URL that we can use to query for the token. This next URL is based on the OpenID discovery specification. We will take the OAuthServer URL from our previous step and append .well-known/openid-configuration to the end of it: http://localhost/InnovatorServer/oauthserver/.well-known/openid-configuration. Again, we can query on this URL with a simple GET request without passing anything through the body.
The response to this request is significantly longer, but it should contain our token endpoint somewhere near the top.
{
"issuer": "OAuthServer",
"jwks_uri": "http://localhost/InnovatorServer/oauthserver/.well-known/openid-configuration/jwks",
"authorization_endpoint": "http://localhost/InnovatorServer/oauthserver/connect/authorize",
"token_endpoint": "http://localhost/InnovatorServer/oauthserver/connect/token"
,
"userinfo_endpoint": "http://localhost/InnovatorServer/oauthserver/connect/userinfo",
"end_session_endpoint": "http://localhost/InnovatorServer/oauthserver/connect/endsession",
...
The JSON path to retrieve this data is simply token_endpoint.
Get Token
The final request we'll use to retrieve our token will use the token endpoint URL retrieved in the previous step. Because this token will be linked to a user's credentials, we will need to pass in additional information before making our request. If you're following along with Postman, you can use the Multipart Form to specify the following pieces of information in your body.
- grant_type : "password"
- Currently, I believe "password" is the only authentication type allows. Aras as a whole is moving towards more types of authentication in 12.0, so this is likely to change in the upcoming releases.
- scope : "Innovator"
- The scope of information this token will be able to access. "Innovator" will be used for almost all purposes.
- client_id : "IOMApp"
- The ID of your client app you configured in the first step of this blog.
- username : "YOUR_USER_NAME"
- Any requests made using the returned token will share the same permissions as this user
- password : "YOUR_MD5_HASHED_PASSWORD"
- database : "YOUR_DATABASE_NAME"
- This should be the name of the database that this token will be able to access. "InnovatorSolutions" is the default name of Aras databases.
After configuring your body, you can send a POST request to the token endpoint URL with the body containing the properties defined above. The response will contain both the OAuth token as well as how long you will have until that token expires.
{
"access_token": "YOUR_TOKEN",
"expires_in": 3600,
"token_type": "Bearer"
}
The JSON path to this token will be access_token. By default, the IOMApp token expires in 3600 seconds or 1 hour.
Make Request with Token
If you've ever used our previous RESTful blog, you'll know that we authenticated previously by passing in the username and hashed password into the AUTHUSER and AUTHPASSWORD headers respectively. With the token, we will authenticate using the standard HTTP Authorization header. Token authentication using this header follows the format below.
Authorization : Bearer {YOUR_TOKEN}
Note that the word "Bearer" must come before your token in the header. If you're using Postman, there should be a way to configure authentication differently than other headers which should automatically add in this word for you. Alternatively, depending on the programming language you're using to perform this request, there may be a special authentication class or library which will automatically add "Bearer" into the header for you as well.
Regardless, once you have your Authorization header configured, you can follow along with our previous RESTful blog, and you should notice that you can query for all of the same information. You can also confirm that the permission model is still in place by querying for items to which you do not have access.
LOOKING FOR MORE ARAS INSPIRATION?
Subscribe to our blog and follow @ArasLabs on Twitter for more helpful content! You can also find our latest open-source projects and sample code on the Aras Labs GitHub page.