You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot+Keycloak无Bearer Token时返回HTML页面及自定义响应需求

解决SpringBoot+Keycloak无Token请求返回登录页的问题

问题原因

默认情况下Keycloak适配器会在认证失败(比如缺失Bearer Token)时重定向到登录页面,这对REST接口不友好——我们需要返回标准化的JSON错误响应而非HTML内容。

解决方案

1. 自定义认证入口点

创建一个类实现AuthenticationEntryPoint,专门处理未认证场景,返回自定义JSON:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class CustomAuthEntryPoint implements AuthenticationEntryPoint {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
        response.setStatus(HttpStatus.UNAUTHORIZED.value());
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);

        Map<String, Object> errorResp = new HashMap<>();
        errorResp.put("code", 401);
        errorResp.put("msg", "请提供有效的Bearer Token进行认证");
        errorResp.put("detail", authException.getMessage());

        objectMapper.writeValue(response.getOutputStream(), errorResp);
    }
}

2. 配置Spring Security

在Security配置类中替换默认的认证入口点,同时禁用表单登录、HTTP Basic等会触发重定向的机制:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationEntryPoint;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final KeycloakAuthenticationProvider keycloakAuthProvider;

    public SecurityConfig(KeycloakAuthenticationProvider keycloakAuthProvider) {
        this.keycloakAuthProvider = keycloakAuthProvider;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // 注册Keycloak认证提供者
        http.authenticationProvider(keycloakAuthProvider);

        http
            .authorizeHttpRequests(auth -> auth
                .anyRequest().authenticated()
            )
            // 配置Keycloak作为OAuth2资源服务器(新版适配方式)
            .oauth2ResourceServer(oauth2 -> oauth2.jwt())
            // 替换为自定义认证入口点
            .exceptionHandling(exceptions -> exceptions
                .authenticationEntryPoint(customAuthEntryPoint())
            )
            // 禁用CSRF(REST接口通常不需要)
            .csrf(csrf -> csrf.disable())
            // 禁用默认表单登录和HTTP Basic,避免重定向到登录页
            .formLogin(form -> form.disable())
            .httpBasic(basic -> basic.disable());

        return http.build();
    }

    @Bean
    public AuthenticationEntryPoint customAuthEntryPoint() {
        return new CustomAuthEntryPoint();
    }
}

3. 关键配置补充(旧版Keycloak适配器)

如果你用的是spring-boot-starter-keycloak旧版适配器,需要在配置文件中添加以下参数,强制Keycloak以Bearer-only模式运行(不触发登录页重定向):

application.properties:
keycloak.bearer-only=true
keycloak.use-resource-role-mappings=true

验证

发送不带Bearer Token的请求到你的REST接口,此时应该收到401 Unauthorized状态码和自定义的JSON响应,不再返回Keycloak的HTML登录页面。

内容的提问来源于stack exchange,提问作者user2191287

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 12:45:35