{"record":{"id":"6f7ba42ae584b8aa","repo":"apereo/cas","slug":"user-agent-is-rejected-for-authentication","errorCode":null,"errorMessage":"User agent [{}] is rejected for authentication","messagePattern":"User agent \\[(.+?)\\] is rejected for authentication","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/adaptive/DefaultAdaptiveAuthenticationPolicy.java","lineNumber":48,"sourceCode":"\n    private final AdaptiveAuthenticationProperties adaptiveAuthenticationProperties;\n\n    @Override\n    public boolean isAuthenticationRequestAllowed(final RequestContext requestContext, final String userAgent,\n                                                  final GeoLocationRequest location) throws Throwable {\n        val clientInfo = ClientInfoHolder.getClientInfo();\n        if (clientInfo == null || StringUtils.isBlank(userAgent)) {\n            LOGGER.warn(\"No client IP or user-agent was provided. Skipping adaptive authentication policy...\");\n            return true;\n        }\n        val clientIp = clientInfo.getClientIpAddress();\n        if (isIpAddressRejected(requestContext, clientIp)) {\n            LOGGER.warn(\"Client IP [{}] is rejected for authentication\", clientIp);\n            return false;\n        }\n\n        if (isUserAgentRejected(userAgent)) {\n            LOGGER.warn(\"User agent [{}] is rejected for authentication\", userAgent);\n            return false;\n        }\n        LOGGER.debug(\"User agent [{}] is authorized to proceed\", userAgent);\n        if (this.geoLocationService != null && location != null && StringUtils.isNotBlank(clientIp)\n            && StringUtils.isNotBlank(this.adaptiveAuthenticationProperties.getPolicy().getRejectCountries())) {\n            val loc = this.geoLocationService.locate(clientIp, location);\n            if (loc != null) {\n                LOGGER.debug(\"Determined geolocation for [{}] to be [{}]\", clientIp, loc);\n                if (isGeoLocationCountryRejected(loc)) {\n                    LOGGER.warn(\"Client [{}] is rejected for authentication based on country location\", clientIp);\n                    return false;\n                }\n            } else {\n                LOGGER.info(\"Could not determine geolocation for [{}]\", clientIp);\n            }\n        }\n        LOGGER.debug(\"Adaptive authentication policy has authorized client [{}] to proceed.\", clientIp);\n        return true;","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/adaptive/DefaultAdaptiveAuthenticationPolicy.java#L30-L66","documentation":"DefaultAdaptiveAuthenticationPolicy rejects the authentication request when the User-Agent string matches the rejected user-agent patterns configured under cas.authn.adaptive.policy.reject-browsers. The warning logs the rejected agent string.","triggerScenarios":"isUserAgentRejected(userAgent) matches the request's User-Agent header against the configured browser/agent patterns after IP checks pass.","commonSituations":"Aggressive bots/scripts hitting the login endpoint; browsers sending unusual User-Agent strings caught by over-broad regex; new browser versions matching stale patterns; API clients lacking a conventional User-Agent.","solutions":["Adjust cas.authn.adaptive.policy.reject-browsers patterns to stop matching the legitimate agent.","Whitelist the affected client's User-Agent or use a narrower, more specific regex.","Identify the offending client from the logged agent string and update your bot/monitoring to send a compliant header.","Review patterns after browser version upgrades to prevent accidental matches."],"exampleFix":"// before\ncas.authn.adaptive.policy.reject-browsers=.*Firefox.*\n// after: narrow to legacy Firefox only\ncas.authn.adaptive.policy.reject-browsers=Firefox/([0-9]|[1-9][0-9])\\.","handlingStrategy":"validation","validationCode":"val patterns = adaptiveProps.getPolicy().getRejectBrowsers();\nval ua = request.getHeader(\"User-Agent\");\nif (patterns.stream().anyMatch(p -> ua.matches(p))) {\n    LOGGER.warn(\"User agent {} will be rejected by adaptive policy\", ua);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Test reject-browsers regexes against real User-Agent samples before deploying.","Re-check patterns after major browser releases.","Keep patterns narrow (specific versions/products) to avoid false positives."],"tags":["adaptive-authentication","user-agent-rejection","access-control"],"backgroundTag":"permission-denied","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"}