Spring Authorization Server授权同意后返回access_denied问题排查
以下是可能导致该错误的几个关键配置缺失或错误点:
客户端注册时未配置精确匹配的重定向URI
Spring Authorization Server对重定向URI采用严格的精确匹配规则,哪怕路径末尾多一个斜杠、端口差异、协议(http/https)不一致,都会触发验证失败。请确保授权请求中的redirect_uri参数值,与客户端注册时redirectUris()配置的字符串完全一致,包括大小写、斜杠、协议和端口。SPA客户端认证方式配置错误
SPA属于公开客户端,无法安全存储客户端密钥,必须将客户端认证方式设置为NONE,同时开启PKCE验证:@Bean public RegisteredClientRepository registeredClientRepository() { RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString()) .clientId("your-spa-client-id") .clientAuthenticationMethod(ClientAuthenticationMethod.NONE) .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) .redirectUri("http://localhost:3000/callback") // 与授权请求的redirect_uri完全一致 .scope("openid") .scope("profile") .clientSettings(ClientSettings.builder() .requireAuthorizationConsent(true) .requireProofKey(true) // 强制开启PKCE验证 .build()) .build(); return new InMemoryRegisteredClientRepository(registeredClient); }若错误配置了
client_secret_basic等需要密钥的认证方式,会导致同意提交时无法正确验证客户端身份,触发client_id相关错误。授权请求中
client_id参数传递异常
虽然能进入同意页,但需确认访问/authorize端点时的初始授权请求中,client_id参数值与注册的客户端ID完全一致。部分SPA框架可能在跳转时意外丢失该参数,可通过浏览器开发者工具查看请求的Query参数,确认client_id存在且正确。SecurityFilterChain配置拦截了同意提交请求
默认Spring Security开启CSRF防护,若自定义了SecurityFilterChain,需确保/oauth2/consent端点的POST请求(提交同意的请求)能正常通过验证。默认同意页会自动携带CSRF令牌,若配置中错误拦截该端点,会导致参数丢失或验证失败。可参考以下基础配置:@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) .formLogin(withDefaults()) .oauth2AuthorizationServer(oauth2 -> oauth2 .authorizationEndpoint(authz -> authz.consentPage("/oauth2/consent")) ); return http.build(); }
内容的提问来源于stack exchange,提问作者Josh

