Categories: ABAP

Change Password Web Service in SAP

Here is a post that I wrote in October 2009. I think the reason why I never published it was because I wanted to first investigate what other (standard) possibilities there were  for providing this functionality, and I was afraid I would be embarrassed by some naive statements made in here. Anyway, for what it’s worth, here it is. (I don’t know what happened to Illustration 1. If I find it, I will try and put it back).

Besides only connecting systems, people use web services to develop end-user applications that call web services on one or more backend systems. Unlike system users, however, end-users require a means to change passwords from time to time. The problem is that basic authentication (user and password) over HTTP does not include a means to tell the caller that their password has expired and allow them to change it, so SOAP calls to services secured with basic authentication suffer from the same problem. For SAP, I here present a possible solution you could use for client web service-based applications that use basic authentication.

The Brief

Different password policies are normally applied to system users and dialog users. A dialog user typically has to change his or her password every once in a while, and needs the ability to change their password when it expires. If this is not catered for, the user may get to a point where they can no longer access the system due to the expiration policy.

Now, when the only way you are interacting with a system is through web service calls and you require the user to enter a user name and password, you need to be able to notify the user of an expired password and allow them to change it through the same means, i.e. via web service calls. You especially need to be able to determine the status of your user, and if your user is locked out, you cannot do that.

To resolve this problem, we here make use of a pre-authenticated web service calling functions of the ABAP function group SUSO which contains function modules to check the status and allow you to reset your password.

Illustration 1: The different needs of system and dialog users

Detailed Solution

Here we have a detailed explanation of the above-mentioned solution for the SAP ABAP stack, that involves wrapping the function modules SUSR_LOGIN_CHECK_RFC and SUSR_USER_CHANGE_PASSWORD_RFC.

The first function allows you to check a user and password combination without actually logging in, (so multiple incorrect attempts won’t lock you out) and the second one allows you to change your password.

The solution described here works for releases below NW04s SP14, from which point onward there are some major changes, including the way web services are published and WSDLs generated, but I will discuss those later on.

Wrapping the Functions

The first step is to generate a web service that will wrap the two functions. Go to transaction SE80, choose a package, right-click on it and go to Create → Enterprise Service/Web Service → Web Service. This brings up the first page of the wizard. On the next page, supply a name and description for your virtual interface and choose Function Group for the endpoint type. The Name Mapping option simply affects the way the generated web service method names etc. are generated. For this example, I have left it off.

Click Continue to go to the next page on the wizard, where you enter the name of the function group: SUSO. Click Continue to proceed.

On the next page, you select the remote-enabled functions you want wrapped. For our solution, we choose only SUSR_LOGIN_CHECK_RFC and SUSR_USER_CHANGE_PASSWORD_RFC.

On the next page, you enter the properties of the web service definition: a name, description and profile, for which I just used Basic Authentication.

Continue and complete, creating an object directory entry and assigning a package as needed. This will have generated the web services and the definitions on the SOAP Runtime, which would have added the necessary nodes to the ICF.

Setting Anonymous Logon Data

Security Note: As I explain further down below, you should not expose these functions as anonymously authenticated web services directly in a real-world situation. You should write your own wrapper functions and expose those as web services with anonymous authentication instead. The reason is that this introduces a security risk in that a caller can call the service an unlimited number of times to try and crack a user’s password, because the policy of maximum number of incorrect attempts is bypassed. By wrapping the standard functions in your own, you can add a real authentication attempt. Consult the Extra Credit section below for a suggestion on how to possibly do this.

If all went well, you can now go to transaction SICF and find the generated service under /default_host/sap/bc/srt/rfc/sap/ in the ICF service tree.

What we will do now is to set a service user to log on to the service, i.e. no authentication will be required by the user. This is important because in order to check the password status you obviously cannot make use of the dialog user if they are locked out. To do this, we will maintain the service and add the credentials of the service user for Anonymous Logon Data. The alternative is to have the client application supply these credentials when logging on, but this means the client must have and store the service user credentials somewhere, which for security and maintainability, I think this is a bad idea.

Go to SICF and locate your service in the tree as described above. Double-click to edit the service, and in the dialog box that comes up, first click on the change icon at the bottom, and then in the Anonymous Logon Data section, enter the credentials of your service user. If you are planning on logging on to more than one SAP client, leave the Client field blank, provided the user has the same password on each client.

Now save the service.

Utilitizing the Web Services

With an example, I will now show how to use the web services.

The first thing you need to do is access the WSDLs of the generated services. This is trivial, as you can add a wsdl parameter to URL of the service. So for example http://<host>.<domain>:<port>/sap/bc/srt/rfc/sap/zbc_suso?sap-client=120 becomes http://<host>.<domain>:<port>/sap/bc/srt/rfc/sap/zbc_suso?sap-client=120 &wsdl and http://<host>.<domain>:<port>/sap/bc/srt/rfc/sap/zbc_suso becomes http://<host>.<domain>:<port>/sap/bc/srt/rfc/sap/zbc_suso ?wsdl .

Enter the new URL in a new browser window to test that the information is returned without requiring a login. You can now test the web services using something like the very handy soapUI application by eviware.

You can also build your client application using the WSDLs. In the example below, I am using Ruby with soap4r to access the web services. If you have Ruby installed, install soap4r with gem install soap4r , which should also install the required httpclient gem, but you may need to do that explicitly.

As pointed out in the security note above, we want to make sure that the policy for locking a user after the maximum number of failed attempts is enforced. This should really happen on the server for security reasons, in which case we would wrap these functions in our own and expose those instead of the standard functions.

NW04s SP14 and beyond

As mentioned above, there are some major changes as of NW04s SP14. The focus is now much more on the use of UDDI for publishing web services. Transactions like WSCONFIG and WSADMIN are obsolete, and instead, you must use SOAMANAGER, which brings up a WebDynpro ABAP application where you can manage the services.

Also, the WSDL that is returned by adding the wsdl parameter to the service URL returns only port definitions, and to get the proper WSDL that is usable by client applications, you must use SOAMANAGER to obtain the proper WSDL by going Business Administration → Web Service Administration , and on your selected service definition, clicking on Open WSDL document for selected binding.

The path to the proper WSDL is based on a different ICF service altogether, so to make the WSDLs accessible anonymously, you need to make the node /default_host/sap/bc/srt/wsdl accessible with anonymous logon, which will make all your WSDLs accessible without authentication. I don’t think this poses any security risks, but you should consider what your needs are.

The path to create web services in SE80 is also different, and so is the wizard. You now need to only go Create → Enterprise Service to bring up the wizard. On the first screen, choose the option Service Provider to create a web service.

I have not had any success using the new WSDLs in soap4r, but you should be able to test them successfully with soapUI and consume the services elsewhere, no doubt.

Extra Credit

  • To make the user check function really user friendly, you could wrap SUSR_LOGIN_CHECK_RFC in another function which takes the resulting message from the SY- variables and passes it back to the caller. This would allow the client program to return a more user-friendly message.
  • In this implementation, the security of the system is compromised because an attacker could try and crack a user’s password by sending an unlimited number of requests. To make the solution secure, you would have to wrap the standard functions in your own, in which you perform an actual login. I am not aware of any standard functions to do this, but you could follow the VIRSA Firefighter approach, which is to modify an RFC destination with the given credentials and then perform a local logon by calling function SYSTEM_REMOTE_LOGIN using the modified RFC destination (which just points to the currently logged on system).

Article info

Leave a Reply

Your email address will not be published. Required fields are marked *