WCEM: Central User Login
How to route my users to the right WCEM application?
In some projects it is just not enough to use product views to give different web shop users a different view on the shop. It requires more as the users should use e.g. country specific shops with different styling.
Now as you have 10, 20 or more WCEM applications users by itself are not able to select the right one, or shouldn’t even see different shops.
For that it might be useful to have some central login in place which routes the user to the correct WCEM application.
A concept for this could look like this. A new application based on WCEM framework containing only the core and user module. The user module must be extended to do the central logon. Additionally the application must run with ‘User Storage Setting’ ‘UME’ or ‘UME only’. Within the extended user module a new page should be created including a new login view. This new page should be marked as ‘startPage’ in the ui-repository.xml
<Page defaultLayout=“1column” name=“loginStartpage” startPage=“true” …
and used as such in the Web Channel builder configuration for this application.
Image 1: WCB-Settings
Now, to have control over the login process in the business object, the entry
File: businessobject-config.xml in customer namespace in extended user module
<businessObject name=“UserBO” className=“com.sap.wec.app.common.module.user.businessobject.impl.UserImpl” />
must be overridden. Within method ‘login’ you are now able to check on user credentials (reusing method ‘UMELogin’ of the base class UserCoreImpl). After method ‘UMELogin’ returned with ‘OK’, you can forward to the view showing the application list (‘sap.wcf/com.sap.common/components/applicationList.xhtml’). To use this view after login, you need to extend module ‘com.sap.common’ (namespace “sap.wcf”) and adding a new module interface for this view
File: interface-definition.xml in customer namespace
<module-interface name=“com.cust.wcf.appllist”>
<uiInclude name=“appllist” />
</module-interface>
File: metadata.xml in customer namespace
<public-part>
<interfaceImplementations>
<interfaceImplementation interfaceName=“com.cust.wcf.appllist”>
<uiInclude name=“appllist” usedUiInclude=“applicationList” />
</interfaceImplementation>
</interfaceImplementations>
</public-part>
Use this new module interface as part of your navigation target.
File: metadata.xml in customer namespace of extended user module
<dependencies>
<interfaceDependency dependencyType=“soft”
interfaceName=“com.cust.wcf.appllist” namespace=“cust”/>
File: ui-repository.xml in customer namespace
<UIInclude name=“appllist” moduleInterfaceInclude=“appllist”
moduleInterface=“com.cust.wcf.appllist” />
<NavigationTarget name=“toAppllist”
targetComposition=“Area:appllist” />
The view handler of ‘applicationList.xhtml’ must also be extended to overwrite method ‘getApplications’. This method allows to filter out all applications which are not relevant for the user.
Once a user clicks on one of the application links, he will be routed to that WCEM application. As this WCEM application runs on the same J2ee Server / web container the parameter “com.sap.wec.appidchange.enable” must be set to ‘true’ (default value if not changed via web.xml). Now the HTTP session of the leaving WCEM application will be destroyed and a new one for the target WCEM application will be created.
In case the application list includes only one application, you might want to directly route the user the target application. This could be done overwritting method ‘prepareData()’ of the view handler like this.
public void prepareData() {
super.prepareData();
if (getApplications().size() == 1) {
AppDetailsBean singleApp = apps.get(0);
String redirectUrl = singleApp.getApplicationLink();
try {
FacesContext.getCurrentInstance().getExternalContext().redirect(redirectUrl);
FacesContext.getCurrentInstance().responseComplete();
}
catch (IOException e) {
String msg = “No redirect possible to given URL ‘” + redirectUrl + “‘”;
throw new ApplicationBaseRuntimeException(msg, e);
}
}
}
This assumes that method ‘getApplications()’ is already implemented in a way to only return appropriated applciations for the user. Now, in case only one application is in the list, an immediate redirect will take place the that application. Sessionhandling will work the same as discribed above.
To smooth the user experience the logon credentials from the first user logon can be used to single sign on to the target WCEM application. To do so the Web Channel Builder parameter ‘policy configuration’ in module ‘user’ should be set to ‘ticket’ for all WCEM applications. By that while logon on to your new central application, an appropriated SAP Logon ticket will be issued, which is than consumed by the target WCEM application, allowing seamless logon process.
Even the registration process is not detailed here, it could work similar. Just using the anonymous data like the local to determine the WCEM application where the registration should take place.
The processes for ‘Forgot Password’ and ‘Forgot User’ might not work in such a scenario, due to on the complexity of the shop finding strategy (e.g. different WCEM application using different SAP ABAP backends).
Hi Ralf
Thanks for this post, very interesting, in particular the part about the web deployment config parameter that eliminates the session when switching to another application.
I've got a related question on that: is it possible to destroy a WCEM session "remotely" from another NW AS Java or destroy it when switching to another (non-WCEM) web application?
In our scenario, we are using SSO tickets issued by WCEM to facilitate the login to another Java web application on another AS Java. To this end, we added a link to this other application to the WCEM user interface. Now, it would be good if a logoff from the other application could delete the WCEM session as well. Curently, a logoff from the other application will remove the SSO cookie but the WCEM session is still intact so navigating back to WCEM will not cause the user to log in again (which is irritating, because the user thinks he has already "logged off"). Basically, we would like to achieve not only Single Sign-On, but also "Single Log-Off".
I was thinking that maybe it would be possible to use a similar approach to what you have presented in your article, namely to have the WCEM session killed as soon as we leave the web shop via the link to the external app. As long as the SSO cookie is still present, we should be able to return and continue where we left off, right?
Thanks for any pointers and best regards,
Matt
Hi Matt.
Simply to fullfil the user experience I would tend to remove the session cookie too (JSESSIONID). Now the user would also be logged off from WCEM. Disadvantage, session would still exist on the server, but with a short session timeout period, this shouldn't be an issue.
Kind regards,
Ralf
Hi Ralf,
Great job, Thanks for this post. I have got a question on that, too. Is it also possible to forward to a specific WCEM application after the central user login?
In our scenario we will specify the information in the backend about the WCEM applications which are relevant for the user. The corresponding function modules returns the wec-appid and the wec-locale. However, in our most cases only one WCEM application fits for the user. Therefore it would be fine if the central login directly redirects to the relevant WCEM application instead of the application list. Which extension steps are necessary in this case?
Thanks and
best regards,
Daniel
Hello Daniel.
Thanks for your feedback. I added this use case to the initial post. You will find it at the end of chapter dealing with the 'applicationList'.
Kind regards,
Ralf
Hi Ralf,
Thanks for the update. We have implement the selection of the correct WCEM application defining own backend objects, business objects and the required module access objects.
However, a new implementation of a login view is not easy. For that I try to reuse the existing userLoginDetailsView view component. I simply try to extend the method login in the responsible UserLoginVCHandler to redirect to the view showing the application list as described. Unfortunately, the user module has only an 'internal' public part which contains the responsible handler UserLoginVCHandler. We are not allowed to use them. Why sap has this restriction? Is there an easy way to extend the existing login views and handlers?
Best regards,
Daniel
Hello Daniel.
Could you please check that you have implemented notes 1754488 and 1797961 in your system. Actually all view handlers are suppose to be in the public part 'ExtensionRestricted'.
Kind regards,
Ralf
Hi Ralf,
Thanks for the notes. This helps. Now I am able to reuse the existing login view components and simply extend the UserLoginVCHandler to redirect to the application list. Furthermore I extend the AppListViewHandler which is responsible for the application list and overwrite the method prepareData(). I use your suggested code for that:
FacesContext.getCurrentInstance().getExternalContext().redirect(redirectUrl);
Due to the context of FacesContext.getCurrentInstance() was null we got a NullPointerException. I found out that the application-j2ee-engine.xml of dpu must have the following entry:
<!-- JSF 2 Implementation -->
<reference reference-type="hard" prepend="true">
<reference-target provider-name="sap.com"
target-type="library">wec~frw~tc~jsf~lib</reference-target>
</reference>
Now the forward works fine. Unfortunately, in the new application we have to login again. Thus I set the "Policy Configuration" property in the module user of the new application to "ticket". It does not help. I also did a permission trace at the backend. It seems to be no permission issue.
Why SSO does not work in this use case?
Best regards,
Daniel
Hello Daniel.
Did you also set the policy configuration of the targetting web application to 'ticket'. Both application need to be configured in this way (while 'ticket' is only an example and other SSO mechanism could also be used).
Kind regards,
Ralf
Hello Ralf,
Yes, I have also set the policy configuration of the target web application to 'ticket'. In the meantime I found out the reason why SSO does not work.
I used 'Preview HTML' to test my extensions. In the authentication logs I saw that in this case the ticket of the WCB user is used instead the ticket of the logged in user of the WC application. Therefore the SSO failed.
After activation of the WC application and using the direct link it works fine.
Thanks a lot! Our use case is implemented now.
Best regards,
Daniel
Hi Daniel
Actually, I think in the case of WCB preview, SSO is disabled altogether. I came across that when I was first testing SSO between our web shop and an external application.
There is a JSF phase listener called PhaseListenerSSOHandlerApp that contains the following code:
Maybe that should be documented somewhere in the Security Guide actually, since it appears to be tripping off a few people.
Regards,
Matt
Hi Ralf
Very good blog and I have similar requirement in my project, were Internet user /Customer to logon to his shop directly depending on the sales area he belongs to.
The challenges which I see in my scenario that internet user might be a contact person for many customer/Sold to of different sales area.
Step 1 User Log on
Step 2 Sold to party selected (in case more then one then standard popup)
Step 3 1 or multiple Sales area found then as per standard list of valid applications will be shown.
Query 1 How to handle the scenario where logged on user is having different sales area then sales area defined in com.sap.common’ ?
As for as my understanding goes application list is filtered on the basis of sales area maintained on com.sap.common and user sales area? Is that correct or worg ?
Query 1 you maintained that the application must run with ‘User Storage Setting’ ‘UME’ or ‘UME only’. In our scenario User Storage Setting is “UME and ABAP “
Is this must to use UME only?
Is this only for landing application or for all the applications?
Regards
Abhay
Hello Abhay.
Your use case is not that easy. First the easiest part of the answer about UME. UME & ABAP is fine for your use case. More complicated are the different sales areas.
I could imagine an approach like this. First use the solution of this blog to allow the user to select its sold-to party he want to work with. Now as the sold-to party defines the sales areas (even muliple sales areas could be assigned to a sold-to party) as second step is necessary to determine the web application fitting to the sales area of the choosen sold-to party. This all can be done within this central login application.
Now as the user has selected the sold-to party and the web application, you can navigate/redirect to the web application itself. In case the user has only one sold-to assigned (fitting to the sales areas of this web application) he will be automatically logged in (that's why in general UME is needed). If the user has more than one sold-to party assigned he would be again prompted to select one. If this application behaviour should be changed, you would need to adapt the PhaseListenerSSOHandlerApp.java
Kind regards,
Ralf
Thanks Ralf for your inputs.