Arne Valued Contributor.
Valued Contributor.
177 views

Oauth2-error upon starting REST-driver

Jump to solution

I'm in the process of setting up a REST-driver using OAuth-authentication for the first time.

It seems the driver is trying to get a token upon driver start, but it fails, seemingly becuase the token endpoint is expecting a request formatted as JSON and I suspect the driver is sending it as XML.

Here's the trace, that also shows the subscriber config. Trace level is 10, but I don't see the request or response sent to/received from the token endpoint:

<nds dtdversion="4.0" ndsversion="8.x">
<source>
<product edition="Advanced" version="4.7.0.0">DirXML</product>
<contact>NetIQ Corporation</contact>
</source>
<input>
<init-params src-dn="\HRG\system\driverset1\MySite">
<driver-filter>
<allow-class class-name="User">
<allow-attr attr-name="userName"/>
<allow-attr attr-name="name.formatted"/>
<allow-attr attr-name="active"/>
<allow-attr attr-name="name.givenName"/>
<allow-attr attr-name="emails"/>
<allow-attr attr-name="addresses"/>
<allow-attr attr-name="phoneNumbers"/>
<allow-attr attr-name="name.familyName"/>
<allow-attr attr-name="title"/>
</allow-class>
</driver-filter>
<subscriber-options>
<subAuthMethod display-name="Authentication Method">OAuth</subAuthMethod>
<subAuthBasicID display-name="Authentication ID"></subAuthBasicID>
<subAuthBasicPwd display-name="Authentication Password" is-sensitive="true" type="password-ref"/>
<bearerToken display-name="Bearer Token">hide</bearerToken>
<bearerTokenID display-name="Bearer Token ID"></bearerTokenID>
<subOAuthURL display-name="Access Token URL">https://mysite.com/configapi/v2/oauth/token</subOAuthURL>
<subOAuthID display-name="User Name"></subOAuthID>
<subOAuthPwd display-name="User Password" is-sensitive="true" type="password-ref"/>
<query-name display-name="Query Name">grant_type</query-name>
<query-value display-name="Query Value">client_credentials</query-value>
<query-name display-name="Query Name">client_id</query-name>
<query-value display-name="Query Value">admin</query-value>
<query-name display-name="Query Name">client_secret</query-name>
<query-value display-name="Query Value">*****************************************</query-value>
<query-name display-name="Query Name">scope</query-name>
<query-value display-name="Query Value">mysite.com</query-value>
<header-name display-name="Header Name">content-type</header-name>
<header-value display-name="Header Value">application/xml</header-value>
<subTrustStoreFile display-name="Truststore file">E:\NetIQ\IdentityManager\RESTDriversKeystore.jks</subTrustStoreFile>
<mutualFields display-name="Set mutual authentication parameters">hide</mutualFields>
<subKeystoreFile display-name="Keystore file"></subKeystoreFile>
<subKeystorePassword display-name="Keystore password" is-sensitive="true" type="password-ref"/>
<connTimeOut display-name="Http Connection Timeout">1</connTimeOut>
<proxy display-name="Proxy host and port"></proxy>
<proxyFields display-name="Set proxy authentication parameters">hide</proxyFields>
<proxyUserName display-name="User name"></proxyUserName>
<proxyPassword display-name="Password" is-sensitive="true" type="password-ref"/>
<subHttpErrorsToRetry display-name="HTTP errors to retry">307 408 503 504</subHttpErrorsToRetry>
<subHttpRESTBASEURL display-name="Base URL for REST Resources">https://mysite.com/configapi/v2/scim/</subHttpRESTBASEURL>
<resrc-schemaName display-name="Schema name">User</resrc-schemaName>
<resrc-operationMode display-name="Configure Handlers">CUSTOM</resrc-operationMode>
<resrc-handlerConf display-name="Rest Handler Details">users/#0#1# users/&lt;association>&lt;filter>#2#0# users/&lt;association>/#1#3# users/&lt;association>#3#1#</resrc-handlerConf>
</subscriber-options>
</init-params>
</input>
</nds>
[10/07/19 15:13:39.220]:BP ST:MySite: RESTSubscriptionShim.init()
[10/07/19 15:13:39.220]:BP ST:MySite: Connecting to REST service via OAuth2
[10/07/19 15:13:39.957]:BP ST:SubscriptionShim.init() returned:
[10/07/19 15:13:39.957]:BP ST:
<nds dtdversion="3.5" ndsversion="8.x">
<source>
<product build="20180222_0635" instance="MySite" version="1.0.0.2">Identity Manager REST Driver</product>
<contact>NetIQ Corporation.</contact>
</source>
<output>
<status level="fatal" type="app-authentication">org.codehaus.jettison.json.JSONException: A JSONObject text must begin with '{' at character 1 of &lt;html>&lt;head>&lt;meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>&lt;title>Error 415 Unsupported Media Type&lt;/title>&lt;/head>&lt;body>&lt;h2>HTTP ERROR 415&lt;/h2>&lt;p>Problem accessing /configapi/v2/oauth/token. Reason:&lt;pre> Unsupported Media Type&lt;/pre>&lt;/p>&lt;hr>&lt;a href="http://eclipse.org/jetty">Powered by Jetty:// 9.4.12.v20180830&lt;/a>&lt;hr/>&lt;/body>&lt;/html></status>
</output>
</nds>

Labels (1)
0 Likes
1 Solution

Accepted Solutions
Arne Valued Contributor.
Valued Contributor.

Re: Oauth2-error upon starting REST-driver

Jump to solution

So, the REST-driver doesn't seem to support OAuth token handling as part of the provisioning flows handled by the REST driver, at least not out of the box.

However, it turned out to be fairly straight-forward to add this token management to the driver. I'll sketch the solution (with thanks to Rodrigo at Microfocus for providing good know-how on how to do this 🙂 ) in case others are looking for the same answers I was.

  • Have two driver variables (don't need to be GCVs), one that stores the token itself and one that stores the timestamp for when the token expires. Epoch timestamp worked well for me
  • Have a GCV that says how long a token should last. Seconds is a suitable time unit for this, especially when the timestamps represent epoch time
  • In the driver configuration, have a separate resource/schema for token-generation only, with suitable settings for URL and other things
  • When you have established that you are going to make a call to the endpoint (e.g. during event transformation on the subscriber channel), check the token expiry. If it's unset or the timestamp has expired, generate a query, with the token-generation class (as defined above) and send it away.
  • On the publisher channel, e.g. during input transform, make sure to have a policy that catches and parses the result of a token request. Have it put the token itself in the driver variable mentioned above and update the token expiry variable to a value of "now" + the value of the token lifetime GCV.
  • In driver configuration, set the subscriber channel to be using anonymous (no) authentication, but make sure the token is added to all regular requests you are generating. Personally, I did this in the policy that tranforms XDS to JSON for the various requests, but I imagine there are more elegant ways to do it as well

That should be the main gist of it. Let me know if you want for details or if there are ways to improve on this approach! 🙂

0 Likes
4 Replies
Arne Valued Contributor.
Valued Contributor.

Re: Oauth2-error upon starting REST-driver

Jump to solution

To clarify, this is the error message from the token service:

<status level="fatal" type="app-authentication">org.codehaus.jettison.json.JSONException: A JSONObject text must begin with '{' at character 1 of <html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Error 415 Unsupported Media Type</title>
</head>
<body>
<h2>HTTP ERROR 415</h2>
<p>Problem accessing /configapi/v2/oauth/token. Reason:<pre> Unsupported Media Type</pre>
</p>
<hr>
<a href="http://eclipse.org/jetty">Powered by Jetty:// 9.4.12.v20180830</a>
<hr/>
</body>
</html>
</status>

Is there some way to make sure that the request-body for the token call is formatted as json? And is there some way to get debug info for these parts of the driver communications?

 

0 Likes
pdeneu Super Contributor.
Super Contributor.

Re: Oauth2-error upon starting REST-driver

Jump to solution

Hey Arne,

you can define the Headers in the subscriber channel options in driver configuration.

Set Header to "Content-Type" with value "application/json"

Regards,

Philipp


--
https://www.lanworks.de
0 Likes
Arne Valued Contributor.
Valued Contributor.

Re: Oauth2-error upon starting REST-driver

Jump to solution

Hi Philipp

I've tried setting that, but it seems more to be a statement about what is in token request rather than actually affect what is being sent. I.e. the request now says that the payload is json, but it's still being sent as XML (seemingly).

Still wondering, though, how I can "up" the debug written to the trace log for this part of the driver operation. Even at trace level 10, there is nothing logged between the reading of config variables and the driver saying a fatal error has occurred 

0 Likes
Arne Valued Contributor.
Valued Contributor.

Re: Oauth2-error upon starting REST-driver

Jump to solution

So, the REST-driver doesn't seem to support OAuth token handling as part of the provisioning flows handled by the REST driver, at least not out of the box.

However, it turned out to be fairly straight-forward to add this token management to the driver. I'll sketch the solution (with thanks to Rodrigo at Microfocus for providing good know-how on how to do this 🙂 ) in case others are looking for the same answers I was.

  • Have two driver variables (don't need to be GCVs), one that stores the token itself and one that stores the timestamp for when the token expires. Epoch timestamp worked well for me
  • Have a GCV that says how long a token should last. Seconds is a suitable time unit for this, especially when the timestamps represent epoch time
  • In the driver configuration, have a separate resource/schema for token-generation only, with suitable settings for URL and other things
  • When you have established that you are going to make a call to the endpoint (e.g. during event transformation on the subscriber channel), check the token expiry. If it's unset or the timestamp has expired, generate a query, with the token-generation class (as defined above) and send it away.
  • On the publisher channel, e.g. during input transform, make sure to have a policy that catches and parses the result of a token request. Have it put the token itself in the driver variable mentioned above and update the token expiry variable to a value of "now" + the value of the token lifetime GCV.
  • In driver configuration, set the subscriber channel to be using anonymous (no) authentication, but make sure the token is added to all regular requests you are generating. Personally, I did this in the policy that tranforms XDS to JSON for the various requests, but I imagine there are more elegant ways to do it as well

That should be the main gist of it. Let me know if you want for details or if there are ways to improve on this approach! 🙂

0 Likes
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.