Oauth2-error upon starting REST-driver

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">
<product edition="Advanced" version="">DirXML</product>
<contact>NetIQ Corporation</contact>
<init-params src-dn="\HRG\system\driverset1\MySite">
<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"/>
<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>
[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">
<product build="20180222_0635" instance="MySite" version="">Identity Manager REST Driver</product>
<contact>NetIQ Corporation.</contact>
<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>

  • 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>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
    <title>Error 415 Unsupported Media Type</title>
    <h2>HTTP ERROR 415</h2>
    <p>Problem accessing /configapi/v2/oauth/token. Reason:<pre> Unsupported Media Type</pre>
    <a href="http://eclipse.org/jetty">Powered by Jetty:// 9.4.12.v20180830</a>

    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?


  • Hey Arne,

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

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



  • 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 

  • Verified Answer

    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! 

  •  is this deficiency addressed for you in the 1.1.0 and later shims?

    There were aparrently major changes made in those versions.