cancel
Showing results for 
Search instead for 
Did you mean: 

IAuthentication forceLogoffUser(req,res,url) method not redirecting to URL

Former Member
0 Kudos

Hi,

I´m using the IAuthentication forceLogoffUser(req,res,url) method to implement a logoff from SAP Portal but the page that is redirected after the execution is not the one that I´m sending in the Method.

Also just the IFrame where I´m running the JSP into the Portal is been redirected to the wrong Page not the entire Page.

Here my code:

%@ page language="java" %>

<%@ page import="com.sap.security.api.UMFactory" %>

<%@ page import="com.sap.security.api.IAuthentication" %>

<%

UMFactory.getAuthenticator().forceLogoffUser(request, response,"http://vsededb.vitro.com:50000/RH_LoginKronos/login.jsp");

%>

Thanx in Advanced!

Kind Regards,

Gerardo J

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hi,

Yes, because the EP takes the page URL from the UME property ume.logoff.redirect.url

You can use the method forceLogoffUser effectively in non-EP code, e.g. in a standard J2EE application.

Kind regards,

Tsvetomir

Former Member
0 Kudos

Hi Tsvetomir,

I´m executing this code in a JSP and having the same results the JSP is deployed in the WAS Java and when I test it it does not redirect me to the page I specify, I implemented the logout and also removed the session cookie and after that I´m replacing the page to my custom Logon page and it is working but I´m geting an extra browser page with an error something about terminator, do you know if there is a way to avoid the execution of the Terminator?

Thanx in advanced for the Help!

Kind Regards,

Gerardo J

Former Member
0 Kudos

This is the error in the Window that is automatically opened:

Access denied (Object(s): com.sap.portal.system/security/sap.com/NetWeaver.Portal/low_safety/com.sap.portal.dsm/components/Terminator).

Exception id: 10:31_12/05/08_0001_7791250

See the details for the exception ID in the log file

Sigiswald
Contributor
0 Kudos

Hi Gerardo,

Please try this: /irj/portal > System Administration > Permissions > Portal Permissions > Security Zones > sap.com > NetWeaver.Portal > low_safety > com.sap.portal.dsm > components > Terminator > Open Permissions

and add "Anonymous Users" (group): Read + End User

Kind regards,

/Sigiswald

Former Member
0 Kudos

Hi,

Thanx for the answer, It is still sending a 500 Server Error but I think the error changed:

Full Message Text

Exception ID:09:14_19/05/08_0004_7791250

[EXCEPTION]

com.sapportals.portal.prt.runtime.PortalRuntimeException: Access is denied: pcd:portal_content/com.vitro.VitroContenido/com.vitro.vitro/com.vitro.desktop/VitroDesktopPortal/frameworkPages/frameworkpage/com.sap.portal.innerpage - user: Guest,

at com.sapportals.portal.prt.deployment.DeploymentManager.getPropertyContentProvider(DeploymentManager.java:1932)

at com.sapportals.portal.prt.core.broker.PortalComponentContextItem.refresh(PortalComponentContextItem.java:234)

at com.sapportals.portal.prt.core.broker.PortalComponentContextItem.getContext(PortalComponentContextItem.java:316)

at com.sapportals.portal.prt.component.PortalComponentRequest.getComponentContext(PortalComponentRequest.java:387)

at com.sapportals.portal.prt.connection.PortalRequest.getRootContext(PortalRequest.java:488)

at com.sapportals.portal.prt.core.PortalRequestManager.runRequestCycle(PortalRequestManager.java:607)

at com.sapportals.portal.prt.connection.ServletConnection.handleRequest(ServletConnection.java:240)

at com.sapportals.portal.prt.dispatcher.Dispatcher$doService.run(Dispatcher.java:522)

I assigned very helpfull cause now it is not leaving an open window when the logon ticket has been removed and it closes the window, do you know what does the terminator do when executing as anonymous? does it still ends the session and dependen objects or how will it identify what to do?

Kind Regards,

Gerardo J

Sigiswald
Contributor
0 Kudos

Hi Gerardo,

Actually, what exactly are you trying to achieve? As far as I get it, you have some portal application (running in the portal) that allows to log off a user. Either explicitly by the user clicking on a link or implicitly by checking some other event, e.g. a timer that fires. Anyway, isn't it possible to reuse the standard logoff functionality that's present in the masthead? That would be something like this:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <title>logoff</title>
    <s cript type="text/javas cript" src="/irj/portalapps/com.sap.portal.epcf.loader/s cript/optimize/js13_epcf.js"></s cript>
    <s cript type="text/javas cript">
// obviously, this function has to be called to be useful...
// e.g. on the page onload event or when a client-side javas cript timer expires
function logoff() {
  if (typeof EPCM == "undefined") {
    return; // you might try to close the browser window
  }

  EPCM.relaxDocumentDomain();

  if (EPCM.getUAType() == EPCM.MSIE) {
    window.parent.releaseProducerSessions();

    if (EPCM.getGlobalDirty()) {
      window.parent.disableWorkProtectCheck = true;
    }
  }

  window.parent.logoff();
}
    </s cript>
  </head>
  <body>
    <div>logoff</div>
  </body>
</html>

In our case, this is a KM document that's attached to an iView and that iView is included in our portal desktop innerpage. The html page also contains a client-side javas cript timer that's (re)started every time the page loads, i.e. when the user navigates in the portal. Basically the user is being logged out when not navigating in the portal for 25 minutes.

var TIME_TIMEOUT = 25 * 60 * 1000; // 25 minutes
...
<body on load="javas cript:window.setTimeout['logoff();', TIME_TIMEOUT);">

OK, finally succeeded in posting this; I had to use some typo's

Kind regards,

/Sigiswald

Former Member
0 Kudos

Hi Sigiswald,

Thanx alot for the post, it is really interesting what you did! I´m facing a challenge that I don´t know if this aproach will succed with that limitation, let me tell you why am I doing all this, the client have 3 different type of employees 2 of them has user and password and uses the standard login page of the portal, but 1 type of employee uses a credential to login sliding it in a card reader where we get the card number and retrieve user and pwd from the employee, so the Login page showed to this type of users is a special login page wich captures the Card number when the employee slides it into the card reader so in the begining we thought on how to do the login but later we realized that the user could not use the standard logoff link cause it will take the employee to the standar login page that asks for user and password and not the card number, so I´m trying to create a custom logoff which takes the employee to the custom login page, but also releasing the sessions, etc...

The aproach I´m taking at this moment is to redirect the user to a page, this will trigger the DSM Terminator, then deleting the Session Cookie redirectign to the custom login and after that and befor login the user to the portal, cleaning the logon ticket, what do you think?

Thanx alot for the Help!!

Kind Regards,

Gerardo J

Sigiswald
Contributor
0 Kudos

Hi Gerardo,

That's indeed an interesting use case you have While I was trying to come up with an answer, I realized I don't really understand what exactly you're trying to achieve... OK, you have two different ways to logon. But how do decide which one to use?

1st option

There's a single logon URL, used by all users. The (portal) application behind the logon URL either decides automatically which logon screen to show, or perhaps it's a single screen and the user can decide for himself (e.g. by clicking on a link in the "standard" logon screen that points to the cardreader logon application). Either way, I don't see a problem in this case. The custom logon screen, i.e. portal application, is defined as the frontendtarget in the [authschemes.xml|http://help.sap.com/saphelp_nw04s/helpdata/en/d3/1dd4516c518645a59e5cff2628a5c1/frameset.htm] file. And the standard logoff functionality properly logs off the user and redirects the user to the same URL, i.e. logon screen, he started with.

2nd option

There're two different logon URLs, each pointing to a different logon application. Each type of employee uses a different URL to access the logon screen. The difficulty is now to redirect the user to the proper logon screen after logging out. The following "solution" is probably way too simple, but why not define the logoff URL, using the ume.logoff.redirect.url UME property, as the customer's intranet site or some static html page? If the user wants to login again, he has to enter his specific logon URL again, which is maybe not that nice, but at least very, very simple.

The problem with using different logon URLs is also that there's only one default, as defined in the authschemes.xml file. This is the logon screen that'll be used when an anonymous user directly accesses a secure URL (e.g. by using a bookmark). The same will happen if there's a session timeout and the user clicks somewhere in the portal (on 2nd thought, that's not entirely true, it depends on the lifetime of the logon ticket; if still valid, new sessions will be created automatically).

In case of the 2nd option, you could enhance the logoff URL by using some simple application that redirects the user to the proper logon screen. This is not as easy as it looks... When the user is redirected to the logoff URL, he is already logged off. You can't simply determine the logon URL based on some session attribute because the sessions are already destroyed. Maybe by using a cookie? Set the cookie when the user logs on (but where exactly?). It should still be available when the user logs off.

I don't know any details about the following, but it might be helpful: "It is possible to send the parameter "logout_submit" containing any value to the EP to log a user off. This will NOT work if the request includes information which is used for logging users on (e.g. client certificate, basic authentication, NTLM, ...)" (see [JAAS - Leveraging External Authentication Based on Industry Standards|https://www.sdn.sap.com/irj/sdn/go/portal/prtroot/docs/library/uuid/17be8b32-0a01-0010-51bc-8fe5e11d204e])

3rd option

Maybe this option better reflects your scenario (and I got it all wrong before): you use a 3rd party authentication server to support the cardreader logon functionality. Something like this: a user authenticates himself on some external server using a cardreader. When the user accesses the portal, the portal knows the user is already authenticated (e.g. by checking some login ticket issued by the external server, possibly by using some specific JAAS login module). When the user logs off, you also want to close the logon session on the external authentication server. You could do this using the ume.logoff.redirect.silent UME property. If set to true, the ume.logoff.redirect.url is triggered in the background (to perform the logoff on the authentication server), all portal sessions are destroyed (and backend connections are closed etc.) and the user is redirected to the standard logon screen. If, as by default, ume.logoff.redirect.silent is false, the portal sessions are terminated (and backend connections are closed etc.) and the user is redirected to the ume.logoff.redirect.url (which can perform the logoff on the authentication server) and display some external page.

This is probably not the exact answer you're looking for, but I hope it at least gives you some ideas And if I misunderstood your scenario, let's try again tomorrow

Kind regards,

/Sigiswald

Former Member
0 Kudos

Hi Sigiswald,

Thanx Alot for the answers,

Actualy is number 2 but 1 of the logon screens is the standard one, here is the aproach that I´m using to see what you think,

1 type of users access the standard logon Screen and also the standard LogOff wich takes them to standar logon page.

1 type of users access a custom logon Screen and a custom LogOff wich takes them to the custom logon page.

The Standard ones works normaly with out any modifications in the procedure of logon and logoff

The other ones that uses the custom way are implemented this way.

A Logon Screen was developed and this screen is showed by default in the kiosk where they slide the card, this logon screen captures the card number, with an RFC we retrieve user and pwd and then post this parámeters to a standar page in Portal wich automátically authenticates the user, after this users are working now in the standard Portal, we created a diferent desktop wich does not show the masthead and instead we are showing an iView with a logoff link, this link triggers a location.replace in JavaScript to another page, since we are leaving the Portal, the SDM Terminator is triggered and sessions are killed(This is what I know but if you know the oposite please let me know), then in next screen we kill the session Cookie and redirect the page again to the custom logon page which waits for another user(or the same) to logon again, after the user logs on we are planing to delete the LogonTicket cookie as well since this one has not been deleted before and as we never close the browser and this is a session cookie then we need to manualy delete it. And then the user gets loged in again and so on....

What do you think?

thanx alot for the help already given!!

kind Regards,

Gerardo J

Sigiswald
Contributor
0 Kudos

Hi Gerardo,

My apologies for the delay, but it had the advantage I could think about some nice options...

First of all, no offense, but I think your solution is a little bit too dangerous and too complex. It relies on the DSM terminator being called when you do a javascript:window.location="some_uri";, assuming that triggers a clean logout (closing backend connections, destroying different sessions etc.) and it forces you to implement some custom logic to delete certain cookies. All of this may eventually work as expected, but I don't dare to guarantee that.

But then again, what are the alternatives? The 2nd option I mention below seems the most apprioprate one to me, although that may depend.

option 1

Use the standard logoff functionality. Use the ume.logoff.redirect.url UME option to point to a custom application, probably a simple servlet (using a portal application would be another option), that redirects the user to a specific logon page. So far this guarantees all users are properly logged out (100% standard functionality) and after being logged, all users are redirected to a single URL/application, which in turn redirects to the correct logon page.

The complexity is of course how to implement that servlet: how can it decide what the correct logon page is? After all, it just receives a request from some anonymous user. You can't pass a parameter and you can't read some data from the session. The only option I see is by using a cookie. Set the cookie when the user logs in using the card reader application. The cookie will still be present when the user logs out and is redirected to the servlet. Based on the presence of the cookie, the servlet can decide the logon page to redirect to. Of course, all of this assumes it is not too complex to set the cookie...

option 2

Modify the masthead, i.e. com.sap.portal.navigation.masthead.par (which you can download at /irj/portal System Administration > Support > Support Desk > Portal Runtime > Browse deployment > ROOT/WEB-INF/deployment/temp). More specifically, modify the HeaderiView.jsp file by changing the implementation of the getExternalLogOffUrl method. Instead of always returning the URL defined in the ume.logoff.redirect.url UME option, you can return any URL you like, i.e. one of your two specific logon pages. BTW, the default logon page is <%=GetLoginURL(componentRequest)%> (as used in the logIn javascript method in the same jsp page).

Granted, you still need some logic to decide which logon page to use. But here, the user is logged in, which makes it a lot easier to decide. You can still use some cookie, but also some session parameter, or perhaps the userid (which is assigned some portal role, which you seem to know because you mentioned you 2 different desktops). The easiest way is probably to pass a specific parameter defined on the iView parameter. I understood you already use different portal desktops, one with and one without the masthead. So it shouldn't be that difficult to use the masthead in both cases, but with a different value of the iView parameter. I guess if you really don't want to display the masthead to the card reader users, you can find a way to remove most of its content or to copy/paste the functionality you need to your own very-lightweight-masthead-with-only-a-logoff-url.

BTW, I think you can read an iView parameter using <%=componentRequest.getComponentContext().getProfile().getProperty("my_iview_parameter")%>

Good luck!

Kind regards,

/Sigiswald

Former Member
0 Kudos

Hi Sigiswald,

Thanx Alot for all the help given! ofcouse I won´t offend :O) I really apreciate the help, I think with this last answer I have enough information to do what is needed for this requirement, when it´s implemented I´ll let you know!!

I think number 2 or something really like that is what I need to implement since I will assign a role to the users that uses the custom logon Page so I think as you say that I can use that to identify and then assign where to redirect the users.

Really nice to meet you and Thanx Again! I´ll let you know!!

Kind Regards,

Gerardo J

Former Member
0 Kudos

Hi Sigiswald,

How have you been?

I´m on my way of implementing the solution, I think this should work if Gods will!

I think your idea of sending a parameter in the iView is the easiest cause we have already created a different desktop to the employees that will use the card to access the Portal, I´ve been searching on how to send this parameter in the iView but can´t find where to do it, in some WD Standard iViews I can see where you can type in your parameters but can´t find where to do it in the MastHead iView or in iViews that I create for Webdynpro. Do you know how to do it?

Thanx in Advanced!

Gerardo J

Sigiswald
Contributor
0 Kudos

Hi Gerardo,

The iView parameters are separately defined in the dist/PORTAL-INF/portalapp.xml file (of the masthead PAR file).

<application>
  ...
  <components>
    <component name="mastHead">
      ...
      <component-profile>
        ...
        <property name="MyLogoffUrl" value="/irj/portal"><!-- some default value -->
          <property name="category" value="Navigation"/>
          <property name="plainDescription" value="My Custom Logoff URL"/>
        </property>
      </component-profile>
    </component>
    ...
  </components>
  ...
</application>

Then in the HeaderiView.jsp you can read the parameter value like this

<%
  // the following two lines are already there
  //IPortalComponentContext componentContext = componentRequest.getComponentContext();
  //IPortalComponentProfile profile = componentContext.getProfile();
  String logoffUrl = profile.getProperty("MyLogoffUrl");
%>

Kind regards,

/Sigiswald

Former Member
0 Kudos

Hi Sigiswald!

How you doing?

Thanx alot for the answer.

I remember that the porpouse of the iView parameters were to make a difference between the card users from the login and pwd users and to put in each desktop an iView one with one value in the parameter and the other one with a different value in the parameter, but maybe I got it Wrong, also I think using the isMemberOfRole Method should work fine and theHeaderiView.jsp already has imported the UMFactory.

What do you think?

Thanx alot and thanx for answering again!!

Kind Regards,

Gerardo J

P.D do you know how to edit my post before this one? I forgot tu put an apostrophe and I'd like to correct it :O)

Sigiswald
Contributor
0 Kudos

Hi Gerardo,

Indeed, the purpose of the iView parameter was to make the distinction between the two different user types (card reader users vs. regular uid/pwd users). Exactly as you describe it. You're correct you can also use something like UMFactory.getAuthenticator().getLoggedInUser().isMemberOfRole(); It doesn't matter, as long as you have an algorithm that can figure out which logoff URL to use.

As a matter of fact, personally I would simply define a LogoffUrl iView parameter. Then the URL is configurable. And it's probably the easiest algorithm you can use: simply use the parameter value

PS About editing a previous post; I don't know either. I think this was possible in the past, but I can't find it anymore...

Kind regards,

/Sigiswald

Former Member
0 Kudos

Hi Again Sigiswald,

How have you been?

I´m planning to change the Masthead tomorrow, I have been analyzing how to change the masthead.par, I remember that when I have modified PAR files in the past I just download it to my Laptop, remove the .bak extension, uncompress the File with winzip make the modification to the file, drag the folder with the modified file into the zip again, and then put the file back in the file system, is this a correct aproach?

Also I will take and put back the masthead.par.bak file from /usr/sap/EDE/JC00/j2ee/cluster/server0/apps/sap.com/irj/servlet_jsp/irj/root/web-inf/deployment/pcd

is this correct? cause there are other two directories containing the masthead.par.bak file.

I Really apreciate your help.

Thanx in Advanced!

Kind Regards,

Gerardo J

Sigiswald
Contributor
0 Kudos

Hi Gerardo,

1. download com.sap.portal.navigation.masthead.par

a) /irj/portal > System Administration > Support > Support Desk > Portal Runtime > Browse deployment > ROOT/WEB-INF/deployment/temp > com.sap.portal.navigation.masthead.par.bak

b) Click on the view link instead of the download link; I know it sounds strange, but it's easier

c) Rename the downloaded file to com.sap.portal.navigation.masthead.par

d) Check if the zip file contains no unnecessary subdirectory ( file_list.txt should be in the root); this should be correct if you used the view link (if you used the download link, the par file itself is contained within the downloaded file).

2. in case you use NWDI (recommended)

a) Create a new DC of type Enterprise Portal / Portal Application Standalone

b) In the wizard, choose "Import project from a Par file" and select the downloaded com.sap.portal.navigation.masthead.par (deployment type should remain EAR SDA).

c) The project is created, but the wizard ignores the jar files in the par file. You have to add them manually. In this particular case, there's only one jar file: PORTAL-INF/private/lib/com.sap.portal.navigation.masthead_core.jar

d) It's a good idea to put some empty dummy.txt file in the empty src.api and src.core directories (to avoid build errors when someone else checks out the project).

e) By default, the par file is deployed as com.sap.portal.navigation.masthead.par (because you imported the original par file), which means it'll overwrite the original version. You most likely don't want to do this. Instead, you want to deploy your custom masthead next to the standard one. The name of the generated par file is defined in the .dcdef file which you can modify: <pns1:par-archive-name xmlns:pns1="http://xml.sap.com/2004/06/PortalPlatform">com.sap.portal.navigation.masthead</pns1:par-archive-name>

3. in case you don't use NWDI

a) You can still create a local DC (same procedure as above), build it locally and deploy it from within NWDS. Or get the created par file from your local file system ( _comp\gen\default\deploy contains the sda file of the DC, which in turn contains the par file) and deploy it manually.

b) Or indeed, you can just unzip the downloaded par file, modify it, zip it again and deploy it manually: /irj/portal > System Administration > Support > Support Desk > Portal Runtime > Administration Console

c) Just be careful that when zipping, there's no subdirectory created. In Windows, select all files in the par file (not the root folder itself), right click and choose copy to / compressed folder.

4. use your custom masthead

That is, create a new iView that points to your custom masthead par file and include the iView in the frameworkpage (of the portal desktop).

Usually it's not required to restart the portal server to see any changes after a new deployment. If you don't see any changes, you can try to clear your browser cache first. If you simply change the par file on the file system of the server, you definitely need to restart the server. And that's not exactly an efficient way of development

Kind regards,

Sigiswald

Former Member
0 Kudos

Hi Again Sigiswald,

Thanx alot for the answer, reading your reply I became with something but I don´t know if that can work, can I just download the .par file, modify it, change the name to Zmasthead.par and upload it and then create the iViews pointing to the Z par file so I don´t hit on the standard masthead.par file or we gain nothing doing this cause the par file will deploy the jsp´s etc files in the same path as the original? or this can work? and we can avoid hitting the standar development and the standard iView and in case something goes wrong in the Z par file it wont affect the people using the Portal with the standar par file at this moment? and once I test the Z par and new iViews I can change the whole portal to use those.

What do you think?

thanx again!!

Kind Regards,

Gerardo J

Sigiswald
Contributor
0 Kudos

Hi Gerardo,

Indeed, I would proceed exactly as you describe it.

If you rename the par file before uploading it, it will not overwrite the original version. Just as you describe it, you can/should create a new masthead View.

Usually, you also create a new desktop and a new frameworkpage. Then add the masthead iView in the frameworkpage. Eventually, when you're happy about the result, you can assign your custom desktop to all users in the master rule collection. Personally, I never actually modify any of the standard content (desktop/frameworkpage/page etc.), except the master rule collection to include a custom desktop. The first rule in my master rule collection is always to assign the default desktop to users of the Administrators group. Starting from the 2nd rule I assign a custom desktop to some portal role. If I have many rules of my own, I extract them to my own rule collection and include that one in the master rule collection (always after assigning the default desktop to the Administrators group).

Kind regards,

/Sigiswald

Former Member
0 Kudos

Hi Sigiswald,

I´m on my way on implementing the changes but when editing the dist/PORTAL-INF/portalapp.xml file and I realized that in my file there is no

Sigiswald
Contributor
0 Kudos

Hi Gerardo,

I compared your file with the default of 7.0 SP13. There're only some minor differences. There's no <component name="mastHead"> either, it's <component name="default"> instead. The default is the one you need

Kind regards,

Sigiswald

Former Member
0 Kudos

Cool! I´ll try with that one then :O)

I´ll let you know!!!

Kind Regards!

And Thanx again!!!

Gerardo J

Former Member
0 Kudos

Hi Sigiswald,

How is everything on your side? I hope everything is just fine!

Here me again with a question, I´m modifying the HeaderiView.jsp and I´m following the part where I will read the iView parameter but I can´t find in the .jsp the two lines that should be there:

<%
// the following two lines are already there
//IPortalComponentContext componentContext = componentRequest.getComponentContext();
//IPortalComponentProfile profile = componentContext.getProfile();
String logoffUrl = profile.getProperty("MyLogoffUrl");
%>

I don´t know if I´m missing something or those lines are in an include but I could not find a jsp included in the file either.

I put the code in there but I don´t know if it will send an error because the invocation in those two lines are not there, should I just include those lines in my code?

Really apreciate it!!

Kind Regards,

Gerardo J

> Hi Gerardo,

>

> The iView parameters are separately defined in the dist/PORTAL-INF/portalapp.xml file (of the masthead PAR file).

>

<application>
>   ...
>   <components>
>     <component name="mastHead">
>       ...
>       <component-profile>
>         ...
>         <property name="MyLogoffUrl" value="/irj/portal"><!-- some default value -->
>           <property name="category" value="Navigation"></property>
>           <property name="plainDescription" value="My Custom Logoff URL"></property>
>         </property>
>       </component-profile>
>     </component>
>     ...
>   </components>
>   ...
> </application>

> Then in the HeaderiView.jsp you can read the parameter value like this

>

<%
>   // the following two lines are already there
>   //IPortalComponentContext componentContext = componentRequest.getComponentContext();
>   //IPortalComponentProfile profile = componentContext.getProfile();
>   String logoffUrl = profile.getProperty("MyLogoffUrl");
> %>

> Kind regards,

> /Sigiswald

Sigiswald
Contributor
0 Kudos

Hi Gerardo,

You're absolutely right! I copy/pasted some code snippets from a customized masthead par file. My excuses for the confusion.

1. The standard portalapp.xml file contains the default component (and not the mastHead component as I mentioned in a previous post).

2. The previous post where I mentioned "the following two lines are already there" is not correct either. To read iView parameters, you can do the same as where the HelpUrl parameter (defined in portalapp.xml ) is read:

private String getHelpUrl(IPortalComponentRequest request)
{
  String value = (String)request.getNode().getValue(HELP_URL);
  return value;
}

Kind regards,

Sigiswald

Former Member
0 Kudos

Hi Sigiswald,

How is everything going over there?

As usual Thanx alot for the Help!!

I´ll try this that you sent me and I´ll let you know how it goes!

Really apreciate all the time and help!!!

Kind Regards,

Gerardo J

Former Member
0 Kudos

Hi again Sigiswald,

How is everything?

I´m doing the following:

I realized that the request is not been passed to the getExternalLogOffUrl, so when it is been called I modyfied the calls like this:


getExternalLogOffUrl(componentRequest)

Also in the function I made this modifications:


private String getExternalLogOffUrl(IPortalComponentRequest request)
{
     
   //return UMFactory.getProperties().get("ume.logoff.redirect.url");
	//Customización para cumplir requerimiento de LogOff de usuarios con credencial
	String value = (String)request.getNode().getValue(LOGOFF_MY_URL);
	return value;
}

Also modified the XML file.

and I´m about to upload the file but I came with a question, inside PORTAL-INFprivatelib there is a file named com.sap.portal.navigation.masthead_core.jar, should I rename this one also to be com.sap.portal.navigation.Zmasthead_core.jar to avoid any modification on the standard or it is safe and it will be placed in a different place anyway?

Kind Regards,

and as always, Thanx Alot!

Gerardo J

Sigiswald
Contributor
0 Kudos

Hi Gerardo,

There's no need to rename that particular jar file. It's part of your modified masthead par file and it won't overwrite anything. As long as you changed the name of the par file itself, you're safe.

Kind regards,

Sigiswald

Former Member
0 Kudos

Hi Sigiswald,

How are you doing?

I did the modifications and some tests and I´m facing 2 issues and I can´t find the reason, I have modified the XML File,

also I have included the code to retrieve the value from the iView, the iView allows me to type in the URL and when I

save it it remains in the iView configuration so that seems to be Ok, but in the jsp the value that I get when calling the iView parameter is "null",

what could that be?

Also I put the URL value Hard coded in the getExternalLogOffUrl but it is not doing the redirect to the page, looking at the code

it seems that GetLogoffURL is the one playing in this case unles I´m missing some other configuration this are the issues I´m facing,

let me post in here the XML and the jsp code,

Thanx alot and really apreciate the help, hope I´m not bothering you too much.

the new property name in the iView is MyLogoffUrl

Kind Regards!

Gerardo J


final String LOGOFF_MY_URL			= "MyLogoffUrl";

//Get the external logoff URL
private String getExternalLogOffUrl(IPortalComponentRequest request)
{
     
   //return UMFactory.getProperties().get("ume.logoff.redirect.url");
	//Customización para cumplir requerimiento de LogOff de usuarios con credencial para Kiosco RH.
String value = (String)request.getNode().getValue(LOGOFF_MY_URL);
	return value;
}



<?xml version="1.0" encoding="utf-8"?>
<application>
  <application-config>
    <property name="Vendor" value="sap.com"></property>
    <property name="SecurityArea" value="NetWeaver.Portal"></property>
    <property name="SharingReference" value=",com.sap.portal.htmlb,com.sap.portal.pagebuilder,com.sap.portal.themes.lafservice,com.sap.portal.navigation.service,com.sap.portal.navigation.helperservice,com.sap.portal.license.runtime,com.sap.portal.common.commonservices,SAPJ2EE::library:com.sap.portal.common"></property>
    <property name="releasable" value="true"></property>
    <property name="PrivateSharingReference" value="com.sap.portal.htmlb"></property>
  </application-config>
  <components>
    <component name="default">
      <component-config>
        <property name="ClassName" value="com.sapportals.portal.navigation.HeaderiView"></property>
        <property name="ResourceBundleName" value="headeriView_nls"></property>
        <property name="SafetyLevel" value="no_safety"></property>
      </component-config>
      <component-profile>
        <property name="tlhtmlb" value="/SERVICE/com.sap.portal.htmlb/taglib/htmlb.tld ">
          <property name="propPermission" value="FINAL"></property>
          <property name="personalization" value="NONE-ALL"></property>
        </property>
        <property name="com.sap.portal.pcm.Title" value="Header iView"></property>
        <property name="com.sap.portal.iview.HeightType" value="FIXED"></property>
        <property name="com.sap.portal.iview.HeightScale" value="PIXELS"></property>
        <property name="com.sap.portal.iview.Height" value="35"></property>
        <property name="com.sap.portal.iview.WidthType" value="FIXED"></property>
        <property name="com.sap.portal.iview.WidthScale" value="PERCENT"></property>
        <property name="com.sap.portal.iview.Width" value="100"></property>
        <property name="com.sap.portal.iview.TrayType" value="BORDERLESS"></property>
        <property name="com.sap.portal.iview.ShowTray" value="false"></property>
        <property name="com.sap.portal.iview.ShowTitle" value="false"></property>
        <property name="com.sap.portal.iview.ShowRefresh" value="false"></property>
        <property name="com.sap.portal.iview.ShowMaximize" value="false"></property>
        <property name="com.sap.portal.iview.ShowCollapseExpand" value="false"></property>
        <property name="com.sap.portal.iview.ShowPersonalize" value="false"></property>
        <property name="com.sap.portal.iview.ShowRemove" value="false"></property>
        <property name="com.sap.portal.reserved.iview.IsolationMode" value="EMBEDDED"></property>
        <property name="com.sap.portal.iview.Availability" value="MANDATORY"></property>
        <property name="CachingLevel" value="None"></property>
        <property name="ValidityPeriod" value="3600000"></property>
        <property name="ShowPersonalizeLink" value="true">
              <property name="validvalues" value="4/true5/false"></property>
              <property name="plainDescription" value="Show Link in Masthead: Personalize"></property>
              <property name="longDescription" value="Show or hide the 'Personalize' link displayed in the masthead iView at runtime."></property>
              <property name="category" value="Navigation"></property>
		</property>
		<property name="ShowHelpLink" value="true">
			  <property name="validvalues" value="4/true5/false"></property>
			  <property name="plainDescription" value="Show Link in Masthead: Help"></property>
              <property name="longDescription" value="Show or hide the 'Help' link displayed in the masthead iView at runtime."></property>	
              <property name="category" value="Navigation"></property>
       	</property>
		<property name="ShowNewWindowLink" value="false">
			  <property name="validvalues" value="4/true5/false"></property>
			  <property name="plainDescription" value="Show Link in Masthead: New Session"></property>
              <property name="longDescription" value="Show or hide the 'New Session' link displayed in the masthead iView at runtime."></property>
              <property name="category" value="Navigation"></property>
		</property>
		<property name="ShowLogInLogOffLink" value="true">
			  <property name="validvalues" value="4/true5/false"></property>
			  <property name="plainDescription" value="Show Link in Masthead: Log In / Log Off"></property>
              <property name="longDescription" value="Show or hide the 'Log In' / Log Off' link displayed in the masthead iView at runtime."></property>
              <property name="category" value="Navigation"></property>
		</property>
	<property name="HelpUrl" value="http://help.sap.com/content/documentation/netweaver/docu_nw_04s.htm">
      		<property name="plainDescription" value="Help Link URL"></property>
      		<property name="category" value="Navigation"></property>
	</property>
        <property name="ShowAnonymousLanguage" value="false">
          <property name="validvalues" value="4/true5/false"></property>
          <property name="plainDescription" value="Show Dropdown List in Masthead: Language Personalization for Anonymous Users"></property>
          <property name="longDescription" value="Show or hide the 'Language' dropdown list in the masthead. This enables anonymous users to personalize the language of the portal at runtime"></property>
          <property name="category" value="Navigation"></property>
        </property>
	<property name="MyLogoffUrl" value="/irj/servlet/prt/portal/prtroot/com.sap.portal.navigation.masthead.LogOutComponent">
          <property name="category" value="Navigation"></property>
          <property name="plainDescription" value="My Custom Logoff URL"></property>
        </property>
      </component-profile>
    </component>

     <component name="lightHeader">
       <component-config>
         <property name="ClassName" value="com.sapportals.portal.navigation.LightHeaderiView"></property>
         <property name="ResourceBundleName" value="headeriView_nls"></property>
         <property name="SafetyLevel" value="no_safety"></property>
       </component-config>
       <component-profile>
         <property name="tlhtmlb" value="/SERVICE/com.sap.portal.htmlb/taglib/htmlb.tld ">
           <property name="propPermission" value="FINAL"></property>
           <property name="personalization" value="NONE-ALL"></property>
         </property>
         <property name="tlframework" value="/SERVICE/com.sap.portal.pagebuilder/taglib/framework.tld"></property>
         <property name="EPCFLevel" value="0"></property>
         <property name="com.sap.portal.pcm.Title" value="Header iView"></property>
         <property name="com.sap.portal.iview.HeightType" value="FIXED"></property>
         <property name="com.sap.portal.iview.HeightScale" value="PIXELS"></property>
         <property name="com.sap.portal.iview.Height" value="35"></property>
         <property name="com.sap.portal.iview.WidthType" value="FIXED"></property>
         <property name="com.sap.portal.iview.WidthScale" value="PERCENT"></property>
         <property name="com.sap.portal.iview.Width" value="100"></property>
         <property name="com.sap.portal.iview.TrayType" value="BORDERLESS"></property>
         <property name="com.sap.portal.iview.ShowTray" value="false"></property>
         <property name="com.sap.portal.iview.ShowTitle" value="false"></property>
         <property name="com.sap.portal.iview.ShowRefresh" value="false"></property>
         <property name="com.sap.portal.iview.ShowMaximize" value="false"></property>
         <property name="com.sap.portal.iview.ShowCollapseExpand" value="false"></property>
         <property name="com.sap.portal.iview.ShowPersonalize" value="false"></property>
         <property name="com.sap.portal.iview.ShowRemove" value="false"></property>
         <property name="com.sap.portal.reserved.iview.IsolationMode" value="EMBEDDED"></property>
         <property name="com.sap.portal.iview.Availability" value="MANDATORY"></property>
         <property name="CachingLevel" value="None"></property>
         <property name="EPCMLevel" value="0"></property>
         <property name="ValidityPeriod" value="3600000"></property>
         <property name="ShowPersonalizeLink" value="true">
               <property name="validvalues" value="4/true5/false"></property>
               <property name="plainDescription" value="Show Link in Masthead: Personalize"></property>
               <property name="longDescription" value="Show or hide the 'Personalize' link displayed in the masthead iView at runtime."></property>
               <property name="category" value="Navigation"></property>
 		</property>
 		<property name="ShowHelpLink" value="true">
 			  <property name="validvalues" value="4/true5/false"></property>
 			  <property name="plainDescription" value="Show Link in Masthead: Help"></property>
               <property name="longDescription" value="Show or hide the 'Help' link displayed in the masthead iView at runtime."></property>	
               <property name="category" value="Navigation"></property>
        	</property>
 		<property name="ShowNewWindowLink" value="false">
 			  <property name="validvalues" value="4/true5/false"></property>
 			  <property name="plainDescription" value="Show Link in Masthead: New Session"></property>
               <property name="longDescription" value="Show or hide the 'New Session' link displayed in the masthead iView at runtime."></property>
               <property name="category" value="Navigation"></property>
 		</property>
 		<property name="ShowLogInLogOffLink" value="true">
 			  <property name="validvalues" value="4/true5/false"></property>
 			  <property name="plainDescription" value="Show Link in Masthead: Log In / Log Off"></property>
               <property name="longDescription" value="Show or hide the 'Log In' / Log Off' link displayed in the masthead iView at runtime."></property>
               <property name="category" value="Navigation"></property>
 		</property>
 	<property name="HelpUrl" value="http://help.sap.com/nw04 ">
       		<property name="plainDescription" value="Help Link URL"></property>
       		<property name="category" value="Navigation"></property>
 	</property>
        <property name="ShowAnonymousLanguage" value="false">
          <property name="validvalues" value="4/true5/false"></property>
          <property name="plainDescription" value="Show Dropdown List in Masthead: Language Personalization for Anonymous Users"></property>
          <property name="longDescription" value="Show or hide the 'Language' dropdown list in the masthead. This enables anonymous users to personalize the language of the portal at runtime"></property>
          <property name="category" value="Navigation"></property>
        </property> 	
       </component-profile>
     </component>
    
    <component name="logoffConfirmMsg">
      <component-config>
        <property name="ClassName" value="com.sapportals.portal.navigation.LogoffConfirmMsg"></property>
        <property name="ResourceBundleName" value="headeriView_nls"></property>
        <property name="SafetyLevel" value="no_safety"></property>
      </component-config>
      <component-profile>
        <property name="com.sap.portal.pcm.Title" value="Log off"></property>
        <property name="AuthScheme" value="anonymous"></property>
      </component-profile>
    </component>
    <component name="logInComponent">
      <component-config>
        <property name="ClassName" value="com.sapportals.portal.navigation.LogInComponent"></property>
        <property name="ResourceBundleName" value="headeriView_nls"></property>
        <property name="SafetyLevel" value="no_safety"></property>
      </component-config>
      <component-profile>
        <property name="com.sap.portal.pcm.Title" value="Log In"></property>
      </component-profile>
    </component>
    <component name="LogOutComponent">
      <component-config>
        <property name="ClassName" value="com.sapportals.portal.navigation.LogOutComponent"></property>
        <property name="SafetyLevel" value="no_safety"></property>
      </component-config>
      <component-profile>
        <property name="AuthScheme" value="anonymous"></property>
      </component-profile>
    </component>
  </components>
  <services></services>
</application>

Sigiswald
Contributor
0 Kudos

Hi Gerardo,

First of all, I don't have a clue why you receive null when reading the iView parameter. Strange. I don't see a typo in your code either. Can you read the value of the HelpUrl parameter? You could try the following instead:

//Get the external logoff URL
private String getExternalLogOffUrl() {
  return request.getComponentContext().getProfile().getProperty("MyLogoffUrl");
}

Second, I had a closer look at the standard SAP masthead (NW7.0 SP12 version). And I'm afraid I didn't notice a quite important fact: the actual redirect to the logoff URL is done somewhere else, not in the HeaderiView.jsp...

When clicking on the logoff link, eventually the javascript logoffFinalCall() method is called in the HeaderiView.jsp. This method first calls logoffThirdParty();, which makes a request to the logoff URL in a hidden iFrame when the logoff mode is silent (defined by the ume.logoff.redirect.silent UME property and used to logoff from an external system). You're probably not interested in this feature, i.e. in your case it probably doesn't do anything and that's fine. The important thing is what happens after the call to logoffThirdParty();. It is document.forms\["logoffForm"\].submit();. The form is defined at the end of the HeaderiView.jsp:

<form name="logoffForm" style="display:none;position:absolute;top:-5000;left:-5000"
  action="<%=GetLogoffURL(componentRequest)%>" method="POST">
  <input type="hidden" name="logout_submit" value="true"></input>
</form>

That GetLogoffURL method is also part of the HeaderiView.jsp:

private String GetLogoffURL(IPortalComponentRequest request) {
  String componentName = request.getComponentContext().getComponentName();
  componentName = componentName.substring(0, componentName.lastIndexOf(".") + 1);
  IPortalComponentURI msgURI = request.createPortalComponentURI();
  msgURI.setContextName(componentName + LOGOFF_REDIRECT_COMPONENT);
  return msgURI.toString();
}

Basically it points to the LogOutComponent component defined in the portalapp.xml, which defines it as the com.sapportals.portal.navigation.LogOutComponent. This class is part of the com.sap.portal.navigation.masthead_core.jar file and this is the implementation (decompiled):

package com.sapportals.portal.navigation;

import com.sap.security.api.UMFactory;
import com.sap.security.api.util.IUMParameters;
import com.sapportals.portal.prt.component.*;
import com.sapportals.portal.prt.pom.IEvent;
import com.sapportals.portal.prt.runtime.IPortalRuntimeResources;
import com.sapportals.portal.prt.runtime.PortalRuntime;

public class LogOutComponent extends AbstractPortalComponent {
  public LogOutComponent() {
  }

  public void doOnNodeReady(IPortalComponentRequest request, IEvent event) {
    String externalUrl = UMFactory.getProperties().get(
      "ume.logoff.redirect.url");
    boolean silent = UMFactory.getProperties().getBoolean(
      "ume.logoff.redirect.silent", false);
    
    if (externalUrl != null && !externalUrl.equals("") && !silent) {
      request.redirect(externalUrl);
    } else {
      INavigationGenerator navigationService =
        (INavigationGenerator) PortalRuntime.getRuntimeResources().getService(
          "com.sap.portal.navigation.service.navigation");
      String URL = navigationService.getPortalURL(request, null);
      request.redirect(URL);
    }
  }

  public void doContent(IPortalComponentRequest iportalcomponentrequest,
    IPortalComponentResponse iportalcomponentresponse) {
  }
}

I guess you see the picture... Now there're probably a few options to get around this. But the best option is probably to either modify (decompile/modify/compile) the existing LogOutComponent or to define a new component. I don't see an easy and reliable possibility that involves only jsp files...

HeaderiView.jsp

First define a new java method.

private String urlEncode(String value) {
  String urlEncoded = null;

  try {
    urlEncoded = java.net.URLEncoder.encode(value, "UTF-8");
  } catch (java.io.UnsupportedEncodingException e) {
    e.printStackTrace();
    urlEncoded = value;
  }

  return urlEncoded;
}

Second, add an extra parameter in the logoffForm

<form name="logoffForm" style="display:none;position:absolute;top:-5000;left:-5000"
  action="<%=GetLogoffURL(componentRequest)%>" method="POST">
  <input type="hidden" name="logout_submit" value="true"></input>
  <input type="hidden" name="logoff_url" value="<%=urlEncode(getExternalLogOffUrl())%>"></input>
</form>

LogOutComponent.java

package com.sapportals.portal.navigation;

import com.sapportals.portal.prt.component.*;
import com.sapportals.portal.prt.pom.IEvent;

public class LogOutComponent extends AbstractPortalComponent {
  public LogOutComponent() {
  }

  public void doOnNodeReady(IPortalComponentRequest request, IEvent event) {
    request.redirect(request.getParameter("logoff_url"));
  }

  public void doContent(IPortalComponentRequest iportalcomponentrequest,
    IPortalComponentResponse iportalcomponentresponse) {
  }
}

To be able to compile this, you need prtapi.jar, which you can probably find somewhere on the file system or you can download it from the portal: /irj/portal > System Administration > Support > Support Desk > Portal Runtime > Browse deployment > ROOT/WEB-INF/portal/lib

com.sap.portal.navigation.masthead_core.jar

Unjar, replace the original LogOutComponent.class with your version and jar again.

And hopefully, it finally works like a charm

I guess it's more complex than I originally thought, but at least it's a challenge

Kind regards,

/Sigiswald

Former Member
0 Kudos

Hi Sigiswald,

As always Thanx alot for your responses.

I have done the test of reading the helpUrl and it works fine, but when reading the new one is not working, I´ll try the code that you sent me instead.

I was looking at your response and checking the whole process and I think that maybe this can work I´m looking that the LogOutComponent is just redirecting to the URL that you want to go after the LogOff process, but is not doing any session killing or something else, the action in the form is pointing to this LogOutComponent and when executed it just sends a redirect to the logOff URL that I is /irj/portal so you can type your user and pwd again so, if we just change the action in the form(inside HeaderiView.jsp) it should work just fine.

so we can just create a method that returns the iView parameter and replace it in


action="<%=GetLogoffURL(componentRequest)%>" method="POST">

for something like


action="<%=GetMyURL(componentRequest)%>" method="POST">

What do you think?

Kind regards and thanx in advanced!!

Gerardo J

Sigiswald
Contributor
0 Kudos

Hi Gerardo,

It might work, but I'm not 100% sure. In the original version, the POST is done towards the server itself while sending the logout_submit parameter. I'm not sure if this parameter is absolutely required to properly log out, but since it's there... I just didn't want to take the risk.

Kind regards,

Sigiswald

Former Member
0 Kudos

Hi Sigiswald,

How have you been? I hope evewrything is great on your side.

I have been analyzing the process and how it works and I think everything is going well except the part of the logout_submit that you mention on the last Post, I see that the Logout Component is just sending a Redirect to /irj/portal, and when sending the logout_submit=true to /irj/portal actualy triggers something that I guess that deletes the ticket or something like that, I have checked the process implemented with out sending the parameter to /irj/portal, with the DSM Logger & Process Troubleshooting and as far as I can see it does the same thing as the Standard, but something is weird If I click on a role that access some application and then use the logoff on the modifyed Zmasthead then it triggers as what I can asume the delete of sessions and other processes and when I try to access again /irj/portal then I get the login page, but If I just login into the portal and click the logoff on the modifyed Zmasthead then it does not trigger the end of sessions, and if I go to /irj/portal then it opens with the user I last loged into the portal.

I asume that the logon.par contains the components that receive the logout_submit parameter, do you know which component catches it? I would like to see what it does to see if I can implement something on the personalized code.

Here I paste you one of the out puts I get when attaching the DSM Logger & Process Troubleshooting when accessing the modifyed ZMasthead accesing some applications first.

-


DSM Terminator [ LOGOFF ]

Single URL=/webdynpro/dispatcher/sap.com/pb/PageBuilder;jsessionid=(J2EE7791200)ID1091483450DB10210460149072206946End?sap-ext-sid=z8qRtiPhAXWAsZd0RHNbOwZgaxKYDxN2tEYPrN8Za1hw&sap-wd-cltwndid=WID1216784448479&sap-sessioncmd=USR_LOGOFF&~SAPSessionCmd=USR_LOGOFF&SAPWP_ACTIVE=1&sap-ep-tstamp=1216784644001&dsmguid=1216784658447

-


.If I dont access any App I got this and if I go next to /irj/portal I access with the user that I got loged in before clicking the modifyed logoff

-


DSM Terminator [ LOGOFF ]

Finished ( 0 request(s) distributed, 2ms)

-


What do you think?

Thanx in advanced.

Kind Regards,

Gerardo J

Answers (0)