# Azure AD OAuth2 � Overlay Deploy Reference (GYPro Example) Reference for `kdshrsso` skill **Option A** (Azure/OIDC). For IDM on Filter overlay see [idm-filter-reference.md](idm-filter-reference.md). For portal eassso bridge see [portal-login-reference.md](portal-login-reference.md). ## Source layout (GYPro) ``` src/com/kingdee/bos/sso/client/ ������ filter/ �� ������ ConfigAddressUtil.java �� ������ authentication/KDPortalAuthenticationFilter.java �� ������ validation/ �� ������ KDPortalTicketValidationFilter.java �� ������ OAuth20CodeValidata.java src/com/kingdee/customer/Auth/handler/ ������ ConfigAddressServletUtil.java # workflow portal only, not /shr main chain login_withForm.jsp # EAS login "Office 365" button -> /shr?adsso ``` ## Call chain ``` login_withForm.jsp onclick -> https://{host}/shr?adsso KDPortalAuthenticationFilter.doFilter() ������ /adsso -> flag=false, force OAuth ������ ConfigAddressUtil.getProperty("authUrl|client_id|url") ������ session.isAdauth = true ������ session.urlToMap = original URL (redirect after login) ������ redirect -> login.microsoftonline.com/.../authorize?... Callback GET /shr?code=xxx KDPortalTicketValidationFilter ������ retrieveTicketFromRequest() -> code ������ getTicketValidatorToSso() -> new OAuth20CodeValidata() ������ super.doFilter() // AbstractTicketValidationFilter template OAuth20CodeValidata.validate(code, url) ������ getToken() -> POST tokenUrl ������ getUser() -> GET userUrl (Graph /me) ������ user = part before @ in userPrincipalName ������ return AssertionImpl(AttributePrincipalImpl) onSuccessfulValidation() ������ check T_PM_USER exists ������ mobile -> index2.do?eid=&appid=¶m= ������ PC -> session.urlToMap.urlTo ``` ## KDPortalAuthenticationFilter highlights - Redirect to IdP (~252-268): when `!flag`, build authorize URL from `authUrl` - `retrieveTicketFromRequest` (~276-278): use `code` param as ticket - `flag` whitelist (~109-128): local login paths excluded; `/adsso` forces OAuth ## KDPortalTicketValidationFilter highlights - `getTicketValidatorToSso` (~94-99): if `code` present -> `new OAuth20CodeValidata()` - `retrieveTicketFromRequest` (~51-71): call `setTicketValidator` before validate - Excluded paths still use CAS validator: viewProcessDiagram.jsp, dynamicPage.do, common/tree.do ## OAuth20CodeValidata highlights - `validate()`: code -> access_token -> userPrincipalName -> Assertion - Assertion attrs: dataCenter, locale, userAuthPattern=aseAD, sso.user.mapping=true - Fix hardcoded client_id/secret in `refreshToken()` �� use config ## Platform classes (in jars, do not patch) | Class | Jar | Relation | |-------|-----|----------| | SHRTicketValidationFilter | shr_syssetting_web.jar | extends KDPortalTicketValidationFilter | | AbstractTicketValidationFilter | cas-client | unchanged parent template | ## Environment URLs (GTIIT example) | Env | redirect_uri | client_id | |-----|--------------|-----------| | Test | https://gtiit.test.kdeascloud.com/shr | test app registration | | Prod | https://gtiit.kdeascloud.com/shr | prod app registration | Tenant example: `28f285d8-5c78-4d60-9c7f-993071841cbd` ## web.xml (on server) In `shr.war/WEB-INF/web.xml` find Authentication and Validation filters; Authentication must run before Validation. ## ConfigAddressUtil vs ConfigAddressServletUtil | Class | Purpose | |-------|---------| | ConfigAddressUtil | SSO Filter chain (authUrl, token, OAuth) | | ConfigAddressServletUtil | UserEasAuthServlet workflow; only dataCenter/locale | Both read `adSsoConfig.properties`; different entry points. ## Related docs | Doc | When | |-----|------| | [idm-filter-reference.md](idm-filter-reference.md) | Same Option A pattern for ?? IDM | | [portal-login-reference.md](portal-login-reference.md) | eassso/login_withForm.js bridge | | [migration-guide.md](migration-guide.md) | Switch between Option A and B |