{"record":{"id":"b1d48d29b3dcc606","repo":"jeecgboot/JeecgBoot","slug":"no-principal-was-found-in-the-response-from-the-ca","errorCode":null,"errorMessage":"No principal was found in the response from the CAS server.","messagePattern":"No principal was found in the response from the CAS server\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/cas/controller/CasClientController.java","lineNumber":72,"sourceCode":"\t\n\t@GetMapping(\"/validateLogin\")\n\tpublic Object validateLogin(@RequestParam(name=\"ticket\") String ticket,\n\t\t\t\t\t\t\t\t@RequestParam(name=\"service\") String service,\n\t\t\t\t\t\t\t\tHttpServletRequest request,\n\t\t\t\t\t\t\t\tHttpServletResponse response) throws Exception {\n\t\tResult<JSONObject> result = new Result<JSONObject>();\n\t\tlog.info(\"Rest api login.\");\n\t\ttry {\n\t\t\tString validateUrl = prefixUrl+\"/p3/serviceValidate\";\n\t\t\tString res = CasServiceUtil.getStValidate(validateUrl, ticket, service);\n\t\t\tlog.info(\"res.\"+res);\n\t\t\tfinal String error = XmlUtils.getTextForElement(res, \"authenticationFailure\");\n\t\t\tif(StringUtils.isNotEmpty(error)) {\n\t\t\t\tthrow new Exception(error);\n\t\t\t}\n\t\t\tfinal String principal = XmlUtils.getTextForElement(res, \"user\");\n\t\t\tif (StringUtils.isEmpty(principal)) {\n\t            throw new Exception(\"No principal was found in the response from the CAS server.\");\n\t        }\n\t\t\tlog.info(\"-------token----username---\"+principal);\n\t\t    //1. 校验用户是否有效\n\t  \t\tSysUser sysUser = sysUserService.getUserByName(principal);\n\t  \t\tresult = sysUserService.checkUserIsEffective(sysUser);\n\t  \t\tif(!result.isSuccess()) {\n\t  \t\t\treturn result;\n\t  \t\t}\n\t \t\tString token = JwtUtil.sign(sysUser.getUsername(), sysUser.getPassword(), CommonConstant.CLIENT_TYPE_PC);\n\t \t\t// 设置超时时间\n\t \t\tredisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);\n\t \t\tredisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME*2 / 1000);\n\n\t \t\t//获取用户部门信息\n\t\t\tJSONObject obj = new JSONObject();\n\t\t\tList<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());\n\t\t\tobj.put(\"departs\", departs);\n\t\t\tif (departs == null || departs.size() == 0) {","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/cas/controller/CasClientController.java#L54-L90","documentation":"CasClientController.validateLogin() validates a CAS service ticket. After confirming the CAS response has no 'authenticationFailure', it extracts the 'user' element (the principal). If empty/absent, it throws -- meaning the CAS server validated the ticket but returned no user identity.","triggerScenarios":"CAS server returns a success response without a 'user' element; the service registry on CAS doesn't release the username attribute; service param doesn't match the registered service; ticket was already consumed or expired (but produced an unexpected response shape).","commonSituations":"CAS attribute-release policy not configured for this service; service URL mismatch between request and CAS service registration; stale/replayed ticket; CAS server version returns attributes in a different element.","solutions":["Inspect the raw CAS response (the 'res.' log line) to see what was actually returned.","Configure the CAS service registry to release the username attribute (service attribute release policy).","Ensure the 'service' parameter exactly matches the registered CAS service URL.","Use a fresh, unconsumed ticket; do not replay a ticket across requests.","Verify prefixUrl + '/p3/serviceValidate' is the correct validation endpoint for the CAS version."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// pre-flight: confirm CAS service registration releases the user attribute\nString res = CasServiceUtil.getStValidate(validateUrl, ticket, service);\nString error = XmlUtils.getTextForElement(res, \"authenticationFailure\");\nString principal = XmlUtils.getTextForElement(res, \"user\");\nif (StringUtils.isEmpty(principal)) {\n    log.error(\"CAS 未返回 principal，原始响应: {}\", res);\n}","typeGuard":null,"tryCatchPattern":"try {\n    // validate CAS ticket\n} catch (Exception e) {\n    if (e.getMessage().contains(\"No principal was found\")) {\n        return Result.error(\"CAS 未返回用户信息，请检查服务注册的属性释放策略\");\n    }\n    throw e;\n}","preventionTips":["Register the exact service URL in CAS and enable attribute release.","Always use a fresh ticket per login attempt.","Log the raw CAS response for diagnostics."],"tags":["cas","sso","auth","xml","configuration"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}