|
1 | 1 | --- |
2 | 2 | outline: [2, 4] |
3 | 3 | --- |
4 | | -# abap2UI5 — Logoff guide for Launchpad, ICF handler, and BSP |
| 4 | +# Logout |
5 | 5 |
|
6 | | -> **TL;DR** The `SYSTEM_LOGOUT` client event behaves differently depending on **how the app was started**, because SAP exposes three independent session layers (FLP shell, ICF/SSO, BSP context) and no single browser-side action terminates all three. This guide explains each layer, what `SYSTEM_LOGOUT` does in each startup context, and which options you have to customize the behavior. |
| 6 | +A logout button isn't a single action. Depending on how an abap2UI5 app was started, the user may have one, two, or three SAP sessions open at the same time, and each lives in a different place. abap2UI5 ships a built-in client event, `system_logout`, that terminates whichever sessions exist for the current app. See sample `Z2UI5_CL_DEMO_APP_361` for a working example. |
7 | 7 |
|
8 | | -See sample `Z2UI5_CL_DEMO_APP_361` for a working example that triggers the `system_logout` client event. |
9 | | - |
10 | | ---- |
11 | | - |
12 | | -## 1. The three startup contexts |
13 | | - |
14 | | -abap2UI5 can be launched in three ways. The JavaScript that runs on the client is the **same** in all three — the difference is which session layers exist around it. |
15 | | - |
16 | | -| Context | Typical URL | Server runtime | FLP shell loaded? | |
17 | | -|---|---|---|---| |
18 | | -| **Fiori Launchpad tile** | `…/sap/bc/ui2/flp#Z2UI5-display` | ICF + UI2 services | ✅ yes | |
19 | | -| **ICF HTTP handler** (e.g. `Z2UI5_CL_HTTP_HANDLER`, `Z2UI5_CL_LP_HANDLER`) | `…/sap/bc/<your-service>` | Plain ICF | ❌ no | |
20 | | -| **BSP application** (`Z2UI5`, `Z2UI5_V2`) | `…/sap/bc/bsp/sap/z2ui5/index.html` | BSP runtime, **stateful** by default | ❌ no | |
21 | | - |
22 | | ---- |
23 | | - |
24 | | -## 2. The three SAP session layers |
25 | | - |
26 | | -Different cookies, different lifetimes, different ways to terminate. |
27 | | - |
28 | | -| Layer | What it represents | Cookie / identifier | Lifetime / scope | |
29 | | -|---|---|---|---| |
30 | | -| **A. FLP shell session** | The Fiori Launchpad UI runtime in the browser | In-memory `sap.ushell.Container` state, plus underlying ICF session | Tab-bound, only exists if FLP was loaded | |
31 | | -| **B. ICF / SSO logon** | AS ABAP authenticated session | `MYSAPSSO2`, `SAP_SESSIONID_<sid>_<client>` | Path-scoped to `/sap/`, killed by `/sap/public/bc/icf/logoff` | |
32 | | -| **C. BSP stateful context** | BSP runtime app state on the application server (visible in `SM04` as Plugin HTTP) | `sap-contextid` scoped to `/sap/bc/bsp/sap/<app>/` | Per-app, killed by `?sap-sessioncmd=logoff` on a URL inside that BSP app | |
33 | | - |
34 | | -**Crucial:** these are independent. Killing one does **not** kill the others. And in any **SSO / IdP** setup (SAML, Kerberos, X.509, custom OIDC) the next request to a protected SAP URL silently re-authenticates regardless — see §6. |
35 | | - |
36 | | ---- |
37 | | - |
38 | | -## 3. What `SYSTEM_LOGOUT` actually does |
39 | | - |
40 | | -The button on the demo `Z2UI5_CL_DEMO_APP_361` triggers the client event `cs_event-system_logout`. The JS handler is identical across all three runtimes; pseudocode: |
41 | | - |
42 | | -``` |
43 | | -SYSTEM_LOGOUT(args): |
44 | | - logoutUrl = args[1] || '/sap/public/bc/icf/logoff' |
45 | | -
|
46 | | - try: |
47 | | - if z2ui5.oLaunchpad?.Container?.logout: # only inside FLP shell |
48 | | - z2ui5.oLaunchpad.Container.logout() # terminates layer A |
49 | | - else: |
50 | | - redirectToLogoff() # fallback path |
51 | | - catch: redirectToLogoff() |
52 | | -
|
53 | | -
|
54 | | -redirectToLogoff(): |
55 | | - # NEW (since the BSP fix): also handle layer C when running inside BSP |
56 | | - if window.location.pathname.startsWith('/sap/bc/bsp/'): |
57 | | - # Hit the BSP path with sap-sessioncmd=logoff via a hidden iframe. |
58 | | - # BSP runtime calls server->session->terminate( ). |
59 | | - <fire iframe to "<bsp-path>?sap-sessioncmd=logoff"> |
60 | | - <on iframe load, OR after 1.5s safety timeout:> |
61 | | - window.location.href = logoutUrl # then go drop layer B |
62 | | - else: |
63 | | - window.location.href = logoutUrl # ICF/handler stays as before |
| 8 | +### The Logout Event |
| 9 | +Fire the event from any controller method to log the user off: |
| 10 | +```abap |
| 11 | +client->_event_client( val = client->cs_event-system_logout ). |
64 | 12 | ``` |
65 | 13 |
|
66 | | -### What this terminates per startup context |
67 | | - |
68 | | -| Context | A – FLP shell | B – ICF/SSO | C – BSP context | |
69 | | -|---|---|---|---| |
70 | | -| Fiori Launchpad tile | ✅ via `Container.logout()` | depends on FLP shell wiring | n/a | |
71 | | -| ICF HTTP handler | n/a | ✅ via `/sap/public/bc/icf/logoff` | n/a | |
72 | | -| BSP application | n/a | ✅ via `/sap/public/bc/icf/logoff` | ✅ via `?sap-sessioncmd=logoff` *(new)* | |
73 | | - |
74 | | -**This is the whole feature** — there is no client-side mechanism that can terminate a layer that wasn't loaded into the page. A BSP page cannot log out the FLP shell, because no FLP shell is mounted on it. The same constraint holds in reverse. |
75 | | - |
76 | | ---- |
77 | | - |
78 | | -## 4. Why the BSP fix was needed |
79 | | - |
80 | | -`/sap/public/bc/icf/logoff` invalidates layer B only. The BSP runtime keeps its **layer C** stateful context alive on the server (you'd see it in `SM04` as a Plugin HTTP session) and the cookie `sap-contextid` stays scoped to `/sap/bc/bsp/sap/<app>/`. Returning to the BSP URL (or any cached state) re-attaches to that context. |
81 | | - |
82 | | -The canonical SAP-standard mechanism for terminating a BSP context is `?sap-sessioncmd=logoff` on a request inside the BSP namespace. SAP itself uses exactly this pattern in `CL_BSP_LOGIN_APPLICATION`, `CL_BSP_LOGOFF_APPL_TAG`, the CRM IC framework, and several `*.wapa.leave.htm` BSP pages — typically delivered via a hidden 1×1 element so the redirect happens silently. |
83 | | - |
84 | | -The patched JS does the same: a hidden iframe → `?sap-sessioncmd=logoff` → on load, redirect to `logoutUrl`. The non-BSP branch is unchanged. |
85 | | - |
86 | | ---- |
87 | | - |
88 | | -## 5. Where this lives in the code |
89 | | - |
90 | | -When you customize, edit only one of these — pick the one that matches your runtime. |
91 | | - |
92 | | -| Object | Type / Package | Role | |
93 | | -|---|---|---| |
94 | | -| `Z2UI5_CL_APP_VIEW1_JS` | CLAS / `$ZLK_00_01_03` | Generates the JS for the **ICF handler** runtime | |
95 | | -| `Z2UI5` (`controller/View1.controller.js`) | WAPA / `$ZLK_01_02` | JS served from MIME repository for **BSP V1** | |
96 | | -| `Z2UI5_V2` (`cc/Actions.js`) | WAPA / `$ZLK_02` | JS served from MIME repository for **BSP V2** | |
97 | | -| `Z2UI5_CL_DEMO_APP_361` | CLAS / `$ZLK_06_02` | Demo that fires the `system_logout` client event | |
98 | | -| `Z2UI5_IF_CLIENT` | INTF | Defines the `cs_event-system_logout` constant | |
99 | | - |
100 | | -> **Important:** the JS is duplicated in three places. If you change the logoff behavior, change it in all three so the runtime you're not testing today doesn't drift. |
101 | | -
|
102 | | ---- |
103 | | - |
104 | | -## 6. Your customization options |
105 | | - |
106 | | -There are exactly four levers. Pick based on what you want, not all of them at once. |
107 | | - |
108 | | -### Lever 1 — Override the post-logoff URL per call |
109 | | - |
110 | | -Pass any same-origin URL as `args[1]` of the `system_logout` event. The JS uses it instead of `/sap/public/bc/icf/logoff`. |
111 | | - |
| 14 | +Optionally pass a same-origin URL as the first argument to control where the user lands afterwards. The default is `/sap/public/bc/icf/logoff`: |
112 | 15 | ```abap |
113 | 16 | client->_event_client( |
114 | 17 | val = client->cs_event-system_logout |
115 | 18 | t_arg = VALUE #( ( `/sap/public/bsp/sap/system/logoff.htm` ) ) ). |
116 | 19 | ``` |
117 | 20 |
|
118 | | -Use this when you want, e.g., the SAP standard BSP logoff confirmation page rather than wherever your customized ICF logoff redirects. |
119 | | - |
120 | | -> Constraint: same origin only. The JS rejects cross-origin redirects. |
121 | | -
|
122 | | -### Lever 2 — Customize what `/sap/public/bc/icf/logoff` does (SICF) |
123 | | - |
124 | | -Default behavior of this endpoint is system-level customizing. Common patterns: |
125 | | - |
126 | | -| What you want | SICF setup | |
127 | | -|---|---| |
128 | | -| Show SAP's standard "you have logged off" page | leave default (ships out of the box) | |
129 | | -| Redirect to the FLP login | Service → Error Pages → Logoff Page → Redirect to URL = `…/sap/bc/ui2/flp` | |
130 | | -| Redirect to a custom company logoff page | Same path, set Redirect to URL = your page | |
131 | | -| Land on a fresh login dialog (force re-prompt) | Combine with disabling SSO for that path | |
132 | | - |
133 | | -This is a **Basis / system-administrator** task. abap2UI5 cannot influence it from the app. If your symptom is "I logged out and came back into the launchpad," this lever is almost certainly the cause. |
| 21 | +### How It Works |
| 22 | +abap2UI5 can be launched in three ways. Each one creates a different combination of SAP sessions, so the same logout event has to do different things in each case. |
134 | 23 |
|
135 | | -### Lever 3 — Run inside the FLP shell when you want shell logout |
136 | | - |
137 | | -If your goal is to always go through `Container.logout()` (the cleanest user experience), run the app **as an FLP tile**, not via a BSP URL. From a BSP URL there is no shell to log out from — that's not a bug, that's by design of how FLP works. |
138 | | - |
139 | | -### Lever 4 — Replace the JS entirely |
140 | | - |
141 | | -If none of the above fits, edit the `_evSystemLogout` / `SYSTEM_LOGOUT` handler in the file matching your runtime (table in §5) and add whatever sequence you need: extra `fetch()` calls, custom IdP single-logout, post-logoff messages, etc. Keep the default branch intact so the existing demos keep working. |
142 | | - |
143 | | ---- |
144 | | - |
145 | | -## 7. The SSO truth |
146 | | - |
147 | | -In any SAP landscape with single sign-on, "logoff" from a single SAP app is inherently **soft**: |
| 24 | +#### Startup Contexts |
| 25 | +| Context | Typical URL | Fiori Launchpad shell? | |
| 26 | +|---|---|---| |
| 27 | +| Fiori Launchpad tile | `…/sap/bc/ui2/flp#Z2UI5-display` | yes | |
| 28 | +| ICF HTTP handler (e.g. `Z2UI5_CL_HTTP_HANDLER`) | `…/sap/bc/<your-service>` | no | |
| 29 | +| BSP application (`Z2UI5`, `Z2UI5_V2`) | `…/sap/bc/bsp/sap/z2ui5/index.html` | no | |
148 | 30 |
|
149 | | -- Killing layers A + B + C in the browser deletes the SAP-side session |
150 | | -- The IdP session (Active Directory, SAML provider, OIDC, certificate-based auth) is **untouched** |
151 | | -- The next request to any protected SAP URL re-authenticates silently |
152 | | -- The user experience is "I clicked logoff, I came right back in" |
| 31 | +#### Session Layers |
| 32 | +Up to three independent SAP sessions can exist at once. Different cookies, different lifetimes, different ways to end them: |
153 | 33 |
|
154 | | -This is not abap2UI5 behavior, it's SAP NetWeaver behavior. Real "log out everywhere" requires either: |
| 34 | +- **Fiori Launchpad shell** — the launchpad UI running in the browser, accessed through `sap.ushell.Container`. Only exists if the app was opened from a tile. |
| 35 | +- **ICF / SSO session** — the authenticated AS ABAP session. Cookies `MYSAPSSO2` and `SAP_SESSIONID_*`. Killed by the standard endpoint `/sap/public/bc/icf/logoff`. |
| 36 | +- **BSP stateful context** — the per-app server-side state that BSP applications keep alive by default. Cookie `sap-contextid`, scoped to `/sap/bc/bsp/sap/<app>/`. Visible in `SM04` as a Plugin HTTP session. Killed by appending `?sap-sessioncmd=logoff` to a URL inside the BSP app. |
155 | 37 |
|
156 | | -1. **IdP-initiated single logout (SLO)** — your IdP's logout endpoint, not SAP's |
157 | | -2. **Closing the browser tab/window** so the IdP session cookies are lost |
158 | | -3. **A server-side logout-everywhere flow** that you build per landscape |
| 38 | +The sessions are independent. Ending one does not end the others, and the client can only end sessions that the current page actually loaded. |
159 | 39 |
|
160 | | -If users complain "logoff doesn't really log me off," explain this constraint. The fix is at the IdP, not in the app. |
| 40 | +#### What `system_logout` Does |
| 41 | +The event terminates whichever layers the current startup context owns: |
161 | 42 |
|
162 | | ---- |
| 43 | +| Started from | Launchpad shell | ICF / SSO | BSP context | |
| 44 | +|---|---|---|---| |
| 45 | +| Fiori Launchpad tile | calls `Container.logout()` | handled by the shell | — | |
| 46 | +| ICF handler URL | — | redirect to `/sap/public/bc/icf/logoff` | — | |
| 47 | +| BSP URL | — | redirect to `/sap/public/bc/icf/logoff` | hidden iframe to `?sap-sessioncmd=logoff` first | |
163 | 48 |
|
164 | | -## 8. Decision tree |
| 49 | +### Customization |
| 50 | +There are four ways to influence what happens on logout. Pick the one that matches your goal. |
165 | 51 |
|
166 | | -``` |
167 | | -User clicks Logout |
168 | | -│ |
169 | | -├─ App is in FLP shell? ───YES──▶ Container.logout() [layer A killed] |
170 | | -│ FLP-managed redirect afterward |
171 | | -│ (typically to a logoff page) |
172 | | -│ |
173 | | -└─ NO (ICF handler or BSP) |
174 | | - │ |
175 | | - ├─ App is on /sap/bc/bsp/…? ───YES──▶ hidden iframe to ?sap-sessioncmd=logoff |
176 | | - │ [layer C killed] |
177 | | - │ THEN ↓ |
178 | | - │ |
179 | | - └─ window.location.href = logoutUrl (default /sap/public/bc/icf/logoff) |
180 | | - [layer B killed by ICF logoff service] |
181 | | - afterward: SICF redirect target |
182 | | - (your system administrator decides) |
183 | | -``` |
| 52 | +#### Custom Post-Logoff URL |
| 53 | +Pass any same-origin URL as `t_arg`. The browser navigates there once the SAP sessions are ended (see the second example in [The Logout Event](#the-logout-event)). Useful when you want a specific landing page — for instance, the standard BSP logoff confirmation page — without changing any system settings. |
184 | 54 |
|
185 | | ---- |
| 55 | +::: warning |
| 56 | +The URL must be same-origin. Cross-origin redirects are rejected. |
| 57 | +::: |
186 | 58 |
|
187 | | -## 9. Common scenarios and what to expect |
| 59 | +#### SICF Configuration |
| 60 | +The endpoint `/sap/public/bc/icf/logoff` is part of the SAP system, not abap2UI5. What it shows or redirects to is configured in transaction `SICF` under **Service → Error Pages → Logoff Page**. Common patterns: |
188 | 61 |
|
189 | | -| Scenario | A | B | C | Where you land | |
190 | | -|---|---|---|---|---| |
191 | | -| Started from FLP, click Logout | ✅ | depends on FLP wiring | n/a | FLP "you have signed out" page | |
192 | | -| Started from ICF handler URL, click Logout | n/a | ✅ | n/a | Whatever `/sap/public/bc/icf/logoff` redirects to | |
193 | | -| Started from BSP URL, click Logout *(after fix)* | n/a | ✅ | ✅ | Whatever `/sap/public/bc/icf/logoff` redirects to — could be FLP if your SICF says so | |
194 | | -| Started from BSP URL, click Logout *(before fix)* | n/a | ✅ | ❌ context lingered in `SM04` | Same as above, but BSP context lived on | |
195 | | -| Any of the above, on an SSO-enabled system | as above | as above | as above | If the redirect target is itself protected, SSO re-authenticates — looks like "didn't log out" | |
| 62 | +| Goal | SICF setting | |
| 63 | +|---|---| |
| 64 | +| Show SAP's "you have logged off" page | leave default | |
| 65 | +| Redirect to the Fiori Launchpad | Redirect to URL = `…/sap/bc/ui2/flp` | |
| 66 | +| Redirect to a custom company page | Redirect to URL = your page | |
| 67 | +| Force a fresh login prompt | combine with disabling SSO for that path | |
196 | 68 |
|
197 | | ---- |
| 69 | +This is a Basis task. If "I logged out and came right back into the launchpad" is the symptom, this setting is almost always the cause. |
198 | 70 |
|
199 | | -## 10. Recommended config matrix |
| 71 | +#### Run Inside the Fiori Launchpad |
| 72 | +If the goal is the cleanest user experience — going through `Container.logout()` and the FLP's own logoff flow — launch the app as an FLP tile, not from a BSP or handler URL. There is no shell to log out from on a non-FLP URL. |
200 | 73 |
|
201 | | -| You want… | Lever 1 (`args[1]`) | Lever 2 (SICF) | Lever 3 (start in FLP) | Lever 4 (edit JS) | |
202 | | -|---|---|---|---|---| |
203 | | -| Standard "you have logged off" page after logout | — | leave default | — | — | |
204 | | -| Redirect to your company logoff page | optionally `args[1]` to that page | OR set in SICF | — | — | |
205 | | -| Always go through FLP shell logout | — | — | ✅ run as FLP tile | — | |
206 | | -| Hard logout including the IdP | — | combine with IdP SLO | — | possibly extra calls | |
207 | | -| Replace mechanism entirely (e.g. mobile app) | — | — | — | ✅ | |
| 74 | +#### Custom JavaScript |
| 75 | +For anything the four levers above don't cover (extra `fetch` calls, an Identity Provider single-logout call, post-logoff messaging), override the JavaScript handler in [Custom JS](/advanced/extensibility/custom_js). |
208 | 76 |
|
209 | | ---- |
| 77 | +### Single Sign-On |
| 78 | +On any system with SSO (SAML, Kerberos, X.509, OIDC, …), the logout event ends the SAP sessions in the browser, but the Identity Provider session stays untouched. The next request to a protected SAP URL silently re-authenticates, and the user perceives "the logout didn't work." |
210 | 79 |
|
211 | | -## 11. Glossary |
| 80 | +This is SAP NetWeaver behavior, not abap2UI5 behavior. A true "log out everywhere" needs one of the following: |
212 | 81 |
|
213 | | -- **FLP / Fiori Launchpad** — the SAP shell UI that hosts Fiori tiles; provides `sap.ushell.Container`. |
214 | | -- **ICF** — Internet Communication Framework, the AS ABAP HTTP server (transactions `SICF`, `SMICM`). |
215 | | -- **BSP** — Business Server Pages, an older SAP web technology that runs **stateful** by default and has its own session layer on top of ICF. |
216 | | -- **SSO / IdP** — Single Sign-On / Identity Provider; the external auth system (AD, SAML, OIDC, etc.). Logging out of SAP locally does **not** log you out of the IdP. |
217 | | -- **`sap-contextid`** — the BSP runtime's stateful-session cookie, scoped to `/sap/bc/bsp/sap/<app>/`. |
218 | | -- **`sap-sessioncmd=logoff`** — URL parameter that instructs the BSP runtime to call `server->session->terminate( )`. |
| 82 | +- Trigger the Identity Provider's own Single Logout (SLO) endpoint |
| 83 | +- Close the browser tab so the IdP cookies are dropped |
| 84 | +- Build a server-side logout-everywhere flow specific to your landscape |
0 commit comments