Technology Blog Posts by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
984

Preparation steps

  1. Create a new technical user in SAP AS Java for connecting via the SPML protocol; the 'Administrator' user cannot be used for this purpose;
  2. Create one or two new roles and include the following actions:
    1. UME.Spml_Read_Action – provides read-only access via the SPML protocol.
    2. UME.Spml_Write_Action – grants full access to the SPML service's functionality when added.
  3. Assign the role(s) to the user.

 

Examples of SPML requests

Once the preparation steps are complete, SPML requests can be sent to the SAP Java server.

Method: POST
URL: http[s]://<host>:<port>/spml/spmlservice
(e.g. http://yoursapjava:57000/spml/spmlservice)
Authorization: Basic authorization – use your SPML technical user ID (see details above)

The request body depends on the operation being performed.
Below is an example request body for retrieving all users.

<?xml version='1.0' encoding='UTF-8'?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
<SOAP-ENV:Header/> 
<SOAP-ENV:Body> 
<spml:searchRequest xmlns:spml='urn:oasis:names:tc:SPML:1:0' xmlns:dsml='urn:oasis:names:tc:DSML:2:0:core'>
  <spml:searchBase type='urn:oasis:names:tc:SPML:1:0#GUID'>
    <spml:id>sapuser</spml:id>
  </spml:searchBase>
  <dsml:filter>
    <dsml:or>
      <dsml:substrings name='logonname'>
        <dsml:initial>a</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>b</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>c</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>d</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>e</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>f</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>g</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>h</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>i</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>j</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>k</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>l</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>m</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>n</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>o</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>p</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>q</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>r</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>s</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>t</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>u</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>v</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>w</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>x</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>y</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>z</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>1</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>2</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>3</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>4</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>5</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>6</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>7</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>8</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>9</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='logonname'>
        <dsml:initial>0</dsml:initial>
      </dsml:substrings>
    </dsml:or>
  </dsml:filter>
  <spml:attributes>
    <dsml:attribute name='country'/>
    <dsml:attribute name='uniquename'/>
    <dsml:attribute name='firstname'/>
    <dsml:attribute name='city'/>
    <dsml:attribute name='timezone'/>
    <dsml:attribute name='certificate'/>
    <dsml:attribute name='description'/>
    <dsml:attribute name='locale'/>
    <dsml:attribute name='title'/>
    <dsml:attribute name='password'/>
    <dsml:attribute name='assignedgroups'/>
    <dsml:attribute name='orgunit'/>
    <dsml:attribute name='accessibilitylevel'/>
    <dsml:attribute name='company'/>
    <dsml:attribute name='streetaddress'/>
    <dsml:attribute name='state'/>
    <dsml:attribute name='id'/>
    <dsml:attribute name='department'/>
    <dsml:attribute name='fax'/>
    <dsml:attribute name='allassignedroles'/>
    <dsml:attribute name='email'/>
    <dsml:attribute name='lastmodifydate'/>
    <dsml:attribute name='zip'/>
    <dsml:attribute name='assignedroles'/>
    <dsml:attribute name='jobtitle'/>
    <dsml:attribute name='ispassworddisabled'/>
    <dsml:attribute name='oldpassword'/>
    <dsml:attribute name='mobile'/>
    <dsml:attribute name='telephone'/>
    <dsml:attribute name='securitypolicy'/>
    <dsml:attribute name='allassignedgroups'/>
    <dsml:attribute name='passwordchangerequired'/>
    <dsml:attribute name='lastname'/>
    <dsml:attribute name='pobox'/>
    <dsml:attribute name='datasource'/>
    <dsml:attribute name='displayname'/>
    <dsml:attribute name='salutation'/>
    <dsml:attribute name='isserviceuser'/>
    <dsml:attribute name='logonname'/>
    <dsml:attribute name='islocked'/>
    <dsml:attribute name='validfrom'/>
    <dsml:attribute name='validto'/>
  </spml:attributes>
</spml:searchRequest>
</SOAP-ENV:Body> 
</SOAP-ENV:Envelope>

Below is an example request body for retrieving all roles.

<?xml version='1.0' encoding='UTF-8'?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
<SOAP-ENV:Header/> 
<SOAP-ENV:Body> 
<spml:searchRequest xmlns:spml='urn:oasis:names:tc:SPML:1:0' xmlns:dsml='urn:oasis:names:tc:DSML:2:0:core'>
  <spml:searchBase type='urn:oasis:names:tc:SPML:1:0#GUID'>
    <spml:id>saprole</spml:id>
  </spml:searchBase>
  <dsml:filter>
    <dsml:or>
      <dsml:substrings name='uniquename'>
        <dsml:initial>a</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>b</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>c</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>d</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>e</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>f</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>g</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>h</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>i</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>j</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>k</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>l</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>m</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>n</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>o</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>p</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>q</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>r</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>s</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>t</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>u</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>v</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>w</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>x</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>y</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>z</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>1</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>2</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>3</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>4</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>5</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>6</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>7</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>8</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>9</dsml:initial>
      </dsml:substrings>
      <dsml:substrings name='uniquename'>
        <dsml:initial>0</dsml:initial>
      </dsml:substrings>
    </dsml:or>
  </dsml:filter>
  <spml:attributes>
    <dsml:attribute name='uniquename'/>
    <dsml:attribute name='datasource'/>
    <dsml:attribute name='displayname'/>
    <dsml:attribute name='member'/>
    <dsml:attribute name='description'/>
    <dsml:attribute name='id'/>
    <dsml:attribute name='lastmodifydate'/>
  </spml:attributes>
</spml:searchRequest>
</SOAP-ENV:Body> 
</SOAP-ENV:Envelope>

The following screenshot shows how the request is executed in Postman.postman_request_1.png

 

If you encounter the following error:
The HTTP request is not valid. For details see SAP Security Note 1631354.

You can refer to the SAP note 1631354 for further information.

The note provides two options:

  • Option 1: Disable this check at the server level (note that this may decrease the security of the SAP Java server).
  • Option 2: Add the following HTTP header to all requests:
X-Requested-WithXMLHttpRequest

A postman example screenshot in this case.postman_request_with_header.png

 

Java library: connector-sap-ume

If you are connecting to SAP UME from a Java code, you can use the following open-source library: https://github.com/Evolveum/connector-sap-ume

Although the library does not include a README file, you can find useful code examples in the following file: https://github.com/Evolveum/connector-sap-ume/blob/master/src/test/java/com/evolveum/polygon/TestCli...

If you encounter the error "HTTP request is not valid" (as mentioned above), the library cannot resolve it automatically, and you will need to adjust the code manually before compilation.

For example, in this file: https://github.com/Evolveum/connector-sap-ume/blob/master/src/main/java/com/evolveum/polygon/connect...

Before line 93, add the following line of code:

httpURLConnection.setRequestProperty("X-Requested-With", "XMLHttpRequest");

 After that, recompile the library and use the recompiled version in your project.

 

Conclusion

I’ve shared the information that was not easy to gather. I hope it will be helpful to others.

2 Comments