IdentityIQ Web Services Unauthorized, HTTP Error Code: 401

Which IIQ version are you inquiring about?

8.4p1

Share all details about your problem, including any error messages you may have received.

I have a web services connector with operations set for GetObject, Create Account, Add Entitlment, and Reomve Entitlement.

I can add and remove entitlments for users that already exist in the target system. These are handle by submitting access request through the “Manage User Access” function.

The issue occurs when I submit for access for somebody that does not have an account in the target system. The overall process shows as a failure but when I check the target appication it does create the account but does not add the access.

It gives an error that the "The request requires user authentication. Below is part of the error I grabbed from logging.

2025-04-08T12:43:45,524 ERROR https-jsse-nio-443-exec-8 connector.webservices.v2.WebServiceFacadeV2:1360 - Exception while updating *****.Url: *****/osmc/admin/usergroups/518ef2fe-296a-4473-9e39-1b99a2e543c1, Message: 401 : Unauthorized, HTTP Error Code: 401
connector.sdk.webservices.exception.WebServicesSdkException: {"code":401,"contactEmail":null,"description":"The request requires user authentication","homeRef":"/","reasonPhrase":"Unauthorized","uri":"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2"}

What I think is the issue and what I have done to try and fix it.

So my assumption is that it needs authentication again when it is attempting to add the usergroup to the newly created user. So I added the Authorization: header and passed in the base64encoded value since we are using basic auth. I have also did these when we switched it to API Token auth type.

Is your create account merge with add entitlement request?

It might help if you can enable the tracing for WSConnector to see if header is getting passed in the /usergroups or not.

@sunnyajmera

Yes I think it is merge the two.

Here is another view of that error with response headers.

[url=*****/osmc/admin/usergroups/518ef2fe-296a-4473-9e39-1b99a2e543c1, errorCode=401, getMessage()={"code":401,"contactEmail":null,"description":"The request requires user authentication","homeRef":"/","reasonPhrase":"Unauthorized","uri":"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2"}, getCause()=null, responseHeaders={Transfer-Encoding=chunked, Accept-Ranges=bytes, X-Frame-Options=SAMEORIGIN, x-nomagic-twc-message=UUID string too large, Strict-Transport-Security=max-age=31536000; includeSubDomains, X-Content-Type-Options=nosniff, WWW-Authenticate=Token Basic realm="ESI DM Gateway", charset="UTF-8", Content-Security-Policy=default-src=none, Connection=keep-alive, X-XSS-Protection=1; mode=block, Date=Tue, 08 Apr 2025 18:43:45 GMT, Content-Type=application/json}]

Also I do have tracing turned on for the WSConnector. Which info would you like to see from it?

have you compared the calls, this one against the one via access request, have you seen any difference?

@sunnyajmera

I have compared and dont see any difference between access request for user with out an account in target application VS access request for a user that has an account already in target applicaiton.

The only difference of course is that one is trying to do multiple API calls (Create Account, Add Entitlment). Where the other is just single API call for Add Entitlment.

@GreeneT Do your API supports creating account and adding entitlement in same call? If yes, then you can try adding this entry at debug.

<entry key="createAccountWithEntReq">   
  <value> 
    <Boolean>true</Boolean> 
  </value> 
</entry> 

Also, enable loggers and see whether Authorization header getting passed in request payload

@Arpitha1 I’m not certain whether this API supports performing both operations within a single request. However, I have already tested setting "createAccountWithEntReq" to true, and the issue persists. The account is successfully created, but the subsequent GetObject call fails with the same error. Additionally, the entitlement is not assigned to the user.

Logging is currently enabled at the TRACE level. Could you clarify which specific log statement contains the request payload?

Thanks,
Travis

You can use Before Rule and After Rule for all 3 operations to print requestEndPoint and response payload.

@GreeneT , double check that all your operations are including the Authorization header.

You need that for most everything.

@paul_hilchey Each operation does have the authorizztion header. But seems like that it is not passing in during the calls.

I did take the URL from the payload that it used in the getObject operation. I posted that in a web browser and it does a popup window asking for username and password and verified what we are using works.

So in the authoratzation header I am passing Basic type as a base64 encoded username:password. But that does help either.

@GreeneT Try enabling debug logging by adding to your log4j2.properties:

logger.http.name=connector.common.http.client.ApacheHttpClient
logger.http.level=debug

@paul_hilchey @Arpitha1

I created before rule to capture the request end point details. See info below. This is what log from submitting a single access request for a user that does not exist in the target system. I shows 3 operations being completed Create User, Add Entitlement, and Get Object. The whole process errors out as stated in my orginal post but the user does get created.

It looks like the auth headers are being passed each time but it fails with 401 Unauthorized “This request requrires user authorazation”.

2025-04-11T08:07:03,114 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - jsonBody: {"enabled":true,"external":true,"otherAttributes":{"department":"ICS","email":"[email protected]","name":"User, Test"},"domain":"external","realm":"74686973-6973-6e74-7265-717569726564","userName":"usert"}
2025-04-11T08:07:03,132 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - voidFull URL      = https://ccameotest.com/osmc/admin/users
2025-04-11T08:07:03,133 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - voidContext URL   = /osmc/admin/users
2025-04-11T08:07:03,133 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - voidRequest Header = {Authorization=Basic *************************, Content-Type=application/json}
2025-04-11T08:07:03,134 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - voidHTTP Method   = POST
2025-04-11T08:07:03,134 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - voidOperationType = Create Account
2025-04-11T08:07:03,134 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - voidApp ID        = 0a884009955c1601819566fd69694e51

-----------------------------------------------------------------------------

2025-04-11T08:07:03,566 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - jsonBody: {
  "usernames": {
    "add": [
      "usert"
    ]
  }
}
2025-04-11T08:07:03,567 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - voidFull URL      = https://cameotest.com/osmc/admin/usergroups/264ca928-60c3-496e-9282-7dc397f7aa4d
2025-04-11T08:07:03,567 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - voidContext URL   = /osmc/admin/usergroups/264ca928-60c3-496e-9282-7dc397f7aa4d
2025-04-11T08:07:03,567 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - voidRequest Header = {Authorization=Basic *************************, Content-Type=application/json}
2025-04-11T08:07:03,567 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - voidHTTP Method   = PATCH
2025-04-11T08:07:03,568 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - voidOperationType = Add Entitlement
2025-04-11T08:07:03,568 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - voidApp ID        = 0a884009955c1601819566fd69694e51

-----------------------------------------------------------------------------

2025-04-11T08:07:03,810 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - jsonBody: null
2025-04-11T08:07:03,810 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - voidFull URL      = https://cameotest.com/osmc/admin/users/usert
2025-04-11T08:07:03,811 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - voidContext URL   = /osmc/admin/users/usert
2025-04-11T08:07:03,811 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - voidRequest Header = {Authorization=Basic *************************, Content-Type=application/json}
2025-04-11T08:07:03,811 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - voidHTTP Method   = GET
2025-04-11T08:07:03,811 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - voidOperationType = Get Object
2025-04-11T08:07:03,811 ERROR https-jsse-nio-443-exec-10 APP.rule.RequestEndpoint:166 - voidApp ID        = 0a884009955c1601819566fd69694e51

Yeah seems like Authorization header is getting passed in all 3 operations. Can you take complete value (Basic ) from requestEndPoint and test these in PostMan or in curl, by passing that Autorization header as exactly same as you copied from requestEndPoint.

I will give that a shot in the morning when I meet with the client. I will report back tomorrow.

Thanks!

1 Like

@Arpitha1 I’ve validated using both cURL and Postman that all operations execute successfully when the Authorization header is passed as currently configured.

As a sanity check, I also modified the value of the Authorization header, which resulted in a failure—confirming that the header is being correctly utilized in the request. I’ve updated all connector operations in SailPoint to use equivalent cURL calls for consistency and re-tested, but the issue persists.

Additionally, I set the createAccountWithEntReq flag to true, but since the target application does not support this operation, the entitlement assignment still fails. Specifically, the failure occurs during the GetObject operation, returning a 401 Unauthorized error.

Do you have any suggestions on how to properly handle this within SailPoint to prevent the failure, especially in scenarios where the account doesn’t yet exist?

Thanks!

@Arpitha1 @paul_hilchey

I think I have identified the issue as a session-based authentication limitation with the target application’s API. SailPoint is not correctly managing the session cookie across multiple provisioning operations.

The API creates a session on the first call and keeps it open for 15 minutes. When SailPoint attempts a second call (e.g., to add an entitlement after account creation), it fails because the API won’t allow a new session while one already exists—it expects the original session cookie to be reused.

I validated this using cURL by saving the cookie with -c cookie.txt on the first call and reusing it with -b cookie.txt on the second, which works. However, when I try to replicate this in SailPoint, the connector doesn’t throw an error but also doesn’t complete the account creation. If I remove the -c flag, it works, confirming the session is mishandled.

I’m looking for guidance on how to capture and reuse the session cookie across multiple API calls within SailPoint—ideally using rules like AfterOperation to persist and inject the cookie into subsequent requests.

Thanks!