paascloud/paascloud-master · error · UnapprovedClientAuthenticationException
请求头中无client信息
Error message
请求头中无client信息
What it means
PcAuthenticationSuccessHandler.onAuthenticationSuccess throws UnapprovedClientAuthenticationException("请求头中无client信息") when the Authorization header is missing or does not start with the Bearer token type. After successful form login, this handler expects the caller's Basic-style Bearer client credentials (base64 clientId:clientSecret) in the Authorization header to perform an OAuth2 token exchange; without it it cannot identify the OAuth2 client.
Solutions
- Send the Authorization header with the expected BEARER prefix and base64(clientId:clientSecret) value on every login request
- Verify any gateway/proxy (Zuul/Nginx) is not stripping the Authorization header
- Confirm the exact token type constant expected (BEARER_TOKEN_TYPE) and match the case/prefix
- If the client has no OAuth2 credentials, register a client in the uac_oauth_client_details table and use its clientId/clientSecret
Example fix
// before curl -X POST http://uac/login -d 'username=u&password=p' // after curl -X POST http://uac/login -H 'Authorization: Basic Y2xpZW50SWQ6Y2xpZW50U2VjcmV0' -d 'username=u&password=p'
Defensive patterns
Strategy: validation
Validate before calling
String header = request.getHeader(HttpHeaders.AUTHORIZATION);
boolean ok = header != null && header.startsWith("Basic ");
if (!ok) { /* attach client credentials before calling login */ } Try / catch
try { return authClient.login(user, pwd); } catch (UnapprovedClientAuthenticationException e) { log.warn("missing/invalid client header: {}", e.getMessage()); throw new ClientAuthException(e); } Prevention
- Centralize the Authorization-header construction in one HTTP interceptor
- Base64-encode clientId:clientSecret exactly as the server expects and reuse the constant
- Check gateway/Nginx configs for header stripping (underscores_in_headers, proxy_set_header Authorization)
- Document the required header in the login API contract
When it happens
Trigger: POSTing login credentials without an Authorization header, or sending an Authorization header not prefixed with the BEARER_TOKEN_TYPE constant (e.g. plain token, Basic instead of the expected scheme).
Common situations: Frontend clients calling the login endpoint directly without attaching the client credentials header; gateway stripping the Authorization header; developers using curl/Postman without the header configured; confusion between Bearer and Basic schemes after framework migration.
Related errors
AI-assisted analysis of paascloud/paascloud-master@781281a950 (2026-09-10).
Data as JSON: /api/errors/316b7b8ffa9738a8.
Report an issue: GitHub.
Appendix: source
Thrown at paascloud-provider/paascloud-provider-uac/src/main/java/com/paascloud/provider/security/PcAuthenticationSuccessHandler.java:56
@Resource
private ClientDetailsService clientDetailsService;
@Resource
private UacUserService uacUserService;
@Resource
private AuthorizationServerTokenServices authorizationServerTokenServices;
private static final String BEARER_TOKEN_TYPE = "Basic ";
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
logger.info("登录成功");
String header = request.getHeader(HttpHeaders.AUTHORIZATION);
if (header == null || !header.startsWith(BEARER_TOKEN_TYPE)) {
throw new UnapprovedClientAuthenticationException("请求头中无client信息");
}
String[] tokens = RequestUtil.extractAndDecodeHeader(header);
assert tokens.length == 2;
String clientId = tokens[0];
String clientSecret = tokens[1];
ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);
if (clientDetails == null) {
throw new UnapprovedClientAuthenticationException("clientId对应的配置信息不存在:" + clientId);
} else if (!StringUtils.equals(clientDetails.getClientSecret(), clientSecret)) {
throw new UnapprovedClientAuthenticationException("clientSecret不匹配:" + clientId);
}
TokenRequest tokenRequest = new TokenRequest(MapUtils.EMPTY_MAP, clientId, clientDetails.getScope(), "custom");
View on GitHub (pinned to 781281a950)