portal-login-reference.md 6.0 KB

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:

<script src="<%= EASWebContextUtil.render(request,"/common/js/login_withForm.js") %>"></script>

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)

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.

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:

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:
<script>
window.SSO_PORTAL_CONFIG = {
    oaSsoUrl: "<%= ssoUrl from properties %>",
    keepLoginPath: "/shr/home.do",
    mode: "servlet"  // or "direct"
};
</script>
<script src="/common/js/login_sso_redirect.js"></script>
<script src="/common/js/login_withForm.js"></script>
  1. Keep source under project src/ or overlay build �� not only runtime/server/deploy/...
  2. 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