{"record":{"id":"127802be79d3952b","repo":"apereo/cas","slug":"credential-attributes-do-not-include-an-attribute","errorCode":null,"errorMessage":"Credential attributes do not include an attribute for [{}]. This will prohibit CAS to construct a meaningful authenticated principal. Examine the released claims and ensure [{}] is allowed","messagePattern":"Credential attributes do not include an attribute for \\[(.+?)\\]\\. This will prohibit CAS to construct a meaningful authenticated principal\\. Examine the released claims and ensure \\[(.+?)\\] is allowed","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"support/cas-server-support-wsfederation/src/main/java/org/apereo/cas/support/wsfederation/authentication/principal/WsFederationCredentialsToPrincipalResolver.java","lineNumber":57,"sourceCode":"        LOGGER.debug(\"Credential attributes provided are: [{}]\", attributes);\n        val idAttribute = configuration.getIdentityAttribute();\n        if (attributes.containsKey(idAttribute)) {\n            LOGGER.debug(\"Extracting principal id from attribute [{}]\", this.configuration.getIdentityAttribute());\n            val idAttributeAsList = CollectionUtils.toCollection(attributes.get(this.configuration.getIdentityAttribute()));\n            if (idAttributeAsList.size() > 1) {\n                LOGGER.warn(\"Found multiple values for id attribute [{}].\", idAttribute);\n            } else {\n                LOGGER.debug(\"Found principal id attribute as [{}]\", idAttributeAsList);\n            }\n\n            val result = CollectionUtils.firstElement(idAttributeAsList);\n            if (result.isPresent()) {\n                val principalId = result.get().toString();\n                LOGGER.debug(\"Principal Id extracted from credentials: [{}]\", principalId);\n                return principalId;\n            }\n        }\n        LOGGER.warn(\"Credential attributes do not include an attribute for [{}]. \"\n            + \"This will prohibit CAS to construct a meaningful authenticated principal. \"\n            + \"Examine the released claims and ensure [{}] is allowed\", idAttribute, idAttribute);\n        return null;\n    }\n\n    @Override\n    protected Map<String, List<Object>> retrievePersonAttributes(final String principalId,\n                                                                 final Credential credential,\n                                                                 final Optional<Principal> currentPrincipal,\n                                                                 final Map<String, List<Object>> queryAttributes,\n                                                                 final Optional<Service> service,\n                                                                 final Optional<AuthenticationHandler> handler) throws Throwable {\n        val wsFedCredentials = (WsFederationCredential) credential;\n        if (this.configuration.getAttributesType() == WsFederationConfiguration.WsFedPrincipalResolutionAttributesType.WSFED) {\n            return wsFedCredentials.getAttributes();\n        }\n        if (this.configuration.getAttributesType() == WsFederationConfiguration.WsFedPrincipalResolutionAttributesType.CAS) {\n            return super.retrievePersonAttributes(principalId, credential, currentPrincipal, new HashMap<>(), service, handler);","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-wsfederation/src/main/java/org/apereo/cas/support/wsfederation/authentication/principal/WsFederationCredentialsToPrincipalResolver.java#L39-L75","documentation":"WsFederationCredentialsToPrincipalResolver could not build a principal id because the credential's attributes do not contain the configured principal id attribute (the WS-Federation claim). CAS logs this warning and returns null, meaning no meaningful authenticated principal can be constructed from the WS-Federation response. It typically indicates the ADFS/AD FS relying-party claim rules do not release the required claim to CAS.","triggerScenarios":"extractPrincipalId is called after extracting WS-Federation credential attributes; the configured principal id attribute name (e.g. a claim like NameID, UPN, or a custom attribute) is absent from the credential's attribute map, so the resolver lookup returns empty and this warn path is hit.","commonSituations":"ADFS/STS issuing organization not releasing the claim CAS is configured to use as the principal attribute; mismatch between cas.authn.wsfed.principal.principal-attribute value and the actual claim name (case/space differences); certificate/key-dependent claim transformation not applied for the CAS relying party trust.","solutions":["On the ADFS/STS server, add an issuance authorization/transform rule that releases the required claim (e.g. Name ID or LDAP attribute mapped to the expected claim) to the CAS relying-party trust.","Check the cas.authn.wsfed principal-attribute configuration value and make sure it exactly matches a claim released in the WS-Federation response (inspect the released claims in debug logs).","If the claim is intentionally unavailable, change the principal attribute to one that is always released, or set principal-attribute to NameID-style default so the default principal id is used.","Enable debug logging for WsFederationCredentialsToPrincipalResolver to see which claims are actually present on the credential and correct the mapping."],"exampleFix":"// before (application.properties)\ncas.authn.wsfed.principal.principal-attribute=email\n// after (claim actually released by the IdP)\ncas.authn.wsfed.principal.principal-attribute=http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn","handlingStrategy":"validation","validationCode":"// Before relying on WS-FED principal resolution, verify the claim is released:\nval attrs = credential.getAttributes();\nif (!attrs.containsKey(principalAttributeName)) {\n    logger.warn(\"Claim [{}] not released by IdP; fix ADFS issuance rules\", principalAttributeName);\n}\nreturn attrs.containsKey(principalAttributeName);","typeGuard":null,"tryCatchPattern":"try {\n    val principal = resolver.resolve(credentials, ...);\n    if (principal == null || principal.getId() == null) {\n        // treat as failed resolution, fall back to alternate attribute or reject\n    }\n} catch (PrincipalResolutionException e) {\n    logger.error(\"WS-FED principal resolution failed\", e);\n}","preventionTips":["Keep ADFS issuance rules documented alongside CAS wsfed principal-attribute settings so they stay in sync.","Log released claims at debug level during initial SSO integration testing.","Use exact claim URIs (not short names) when configuring principal attributes.","Add a startup/config test that authenticates a test user and asserts the principal attribute exists."],"tags":["ws-federation","principal-resolution","sso","claims"],"backgroundTag":"missing-required-config-field","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}