# EAS Portal Login Bridge �� login_withForm.js Reference Reference for `kdshrsso` skill. Describes how `eassso/login` interacts with SHR SSO (Option A or B). ## Context EAS portal CAS flow sends unauthenticated users to: ``` /eassso/login?service=https://{shr-host}/shr/{path}?... ``` Loaded by `login_withForm.jsp`: ```jsp ``` Default behavior: show username/password form. Customizations intercept before `initLoginFormPattern()` runs. --- ## Pattern 1 �� Option B servlet bridge (YHPro) **Goal:** Hide eassso login for SHR; redirect to `OAToSHR` with target URL in `service` or `redirect`. ``` eassso/login?service=SHR_TODO_URL �� login_withForm.js IIFE (top of file) �� /shr/api/oAToSHR?service=encodeURIComponent(SHR_TODO_URL) �� OAToSHR puts target into OAuth state �� IDM �� index2sso.jsp �� SHR_TODO_URL ``` ### YHPro logic (simplified) ```javascript var ENV_CONFIG = { keepLoginPath: "/shr/home.do", // whitelist: show native login shrRootPath: "/shr/", test: { oaSsoUrl: "https://shr-test.example.com/shr/api/oAToSHR" } }; var serviceParam = getUrlParam("service"); var originalPath = getOriginalPathFromService(serviceParam); var isKeepLogin = originalPath === ENV_CONFIG.keepLoginPath || (serviceParam && serviceParam.includes(ENV_CONFIG.keepLoginPath)); var needRedirect = !isKeepLogin && (originalPath.includes("/shr/") || originalPath === "" || location.pathname.includes("/eassso/login")); if (needRedirect) { var callbackUrl = serviceParam || (shrBaseUrl + "/shr/"); location.replace(oaSsoUrl + "?service=" + encodeURIComponent(callbackUrl)); } ``` ### Parameter choice | Param to OAToSHR | OAToSHR reads | Recommendation | |------------------|---------------|----------------| | `redirect` | 1st priority | Preferred for portal direct links | | `service` | 2nd priority | Used by eassso CAS bridge | `state` in OAuth is **dynamic**: encoded value of redirect/service URL. ### UX additions (YHPro) - Full-screen mask `#sso-jump-mask` before redirect (avoid login page flash) - `window.onbeforeunload = null` �� prevent EAS blocking redirect - `location.replace()` �� no back-button to login page - 3s mask timeout �� fallback if redirect fails --- ## Pattern 2 �� Option A direct forward **Goal:** Let SHR CAS filters handle OAuth; no servlet. ```javascript if (isShrService(serviceParam) && !isKeepLogin) { window.top.location.replace(serviceParam); // go to SHR URL directly } ``` Flow: ``` eassso/login?service=https://shr/.../dynamic.do?... �� JS replace �� SHR URL �� KDPortalAuthenticationFilter (no assertion) �� IDM �� /shr?code= �� validation �� target page ``` Portal menus can also link **directly** to SHR URLs, skipping eassso/login entirely. --- ## Pattern 3 �� Option A adsso button (GYPro / Azure) `login_withForm.jsp` adds Office 365 button: ```javascript onclick="window.location.href='https://{host}/shr?adsso'" ``` Filter treats `/adsso` as force-OAuth entry; stores original URL in session before IdP redirect. --- ## Whitelist local login Keep emergency / admin path on native eassso form: | Path | Typical purpose | |------|-----------------| | `/shr/home.do` | Local DB login bypass (YHPro) | | Product default | Specific JSP paths in Filter `flag` (Option A) | Implement whitelist by **exact pathname match**, not loose `includes()`. --- ## Recommended implementation (either pattern) ### Do 1. Put custom logic in **separate** `login_sso_redirect.js`; include it in JSP **before** `login_withForm.js` 2. Inject config from server: ```jsp ``` 3. Keep source under project `src/` or overlay build �� not only `runtime/server/deploy/...` 4. Use one config file shared with Java (`OASSOConfig` / `adSsoConfig`) ### Do not | Anti-pattern | Risk | |--------------|------| | Hardcode dev/test/prod URLs in JS | Prod misconfig; triple maintenance with Java | | Edit 1500-line platform file in runtime war only | Lost on redeploy / upgrade | | `needRedirect` when `service` is empty | Bare `/eassso/login` forced to SHR SSO | | `serviceParam.includes(keepLoginPath)` | Loose match bypass | | Prod placeholder URL (`��������OA�����¼��ַ`) | Production outage | | Duplicate logout URLs in JS + Java + servlet | Inconsistent federated logout | --- ## logoutHR.js (Option B companion) SHR logout extended for IDM federated logout: ``` logoutHR() �� /eassso/logout + shr_loginout + easweb/logout (platform chain) �� clear cookies / storage �� redirect to idmLogoutUrl (or portal home) ``` IDM logout URL built per spec: ``` {idmBaseUrl}/token/code-logout?redirect_url={encodeURIComponent(authorizeUrlWithParams)} ``` **Prefer:** call `/shr/api/SHRToIDMLogout` servlet (server builds URL from properties) instead of rebuilding URL in JS. YHPro `logoutHR.js` currently duplicates IDM URL logic in frontend �� refactor to servlet JSON response. --- ## File locations (typical) | File | War | Role | |------|-----|------| | `common/js/login_withForm.js` | `sso_web.war` (eas.ear) | Portal login page logic | | `login_withForm.jsp` | `sso_web.war` | Loads JS | | `scripts/gui/logoutHR.js` | `shr_web.war` | SHR logout | | `sso/ssoParamemter.properties` | `shr_web.war` | CAS UrlPattern exclusions | --- ## Test checklist ``` - [ ] Portal menu �� SHR todo: lands on todo after IDM login - [ ] /shr/home.do (whitelist): shows eassso login form - [ ] Direct /shr URL without session: OAuth (A) or needs portal link (B) - [ ] Logout: SHR session cleared + IDM session cleared - [ ] Upgrade sso_web.war: custom JS preserved via overlay ```