spring 引导安全异常消息本地化

spring boot security exception messages localization

我正在尝试对 spring 安全异常消息使用其他语言。参考下面的文档,我创建了 messageSource 但它不起作用。

有人可以帮忙吗?提前致谢。

java_version=11
spring_boot_version=2.5.0 (with spring security: version 5.2.8)
spring_dependency_management_version=1.0.11.RELEASE
javax_validation_version=2.0.1.Final

https://docs.spring.io/spring-security/site/docs/current/reference/html5/#localization

Request Header:
Accept-Language: zh 

回复总是英文,不是中文。

{
    "timestamp": "2021-05-27T14:00:46.098+00:00",
    "status": 401,
    "error": "Unauthorized",
    "message": "Bad credentials",
    "path": "/api/login"
}

LocaleConfig源码如下。这适用于 JPA 验证,但不适用于 spring 安全异常消息。

@Configuration
public class LocaleConfig {


    @Bean
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.addBasenames("classpath:locales/messages", "classpath:org/springframework/security/messages");
        messageSource.setDefaultEncoding(StandardCharsets.UTF_8.toString());
        return messageSource;
    }

    @Bean
    public LocaleResolver localeResolver() {
        AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver();
        resolver.setDefaultLocale(Locale.ENGLISH);
        resolver.setSupportedLocales(Arrays.asList(Locale.ENGLISH, Locale.CHINESE));
        return resolver;
    }

    @Bean
    public LocalValidatorFactoryBean validator() {
        LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
        bean.setValidationMessageSource(messageSource());
        return bean;
    }

}

此问题已通过实施 authenticationEntryPoint 解决。因为我正在使用 jwt 身份验证。以下是 HttpSecurity 配置中的解决方案。

// Set unauthorized requests exception handler
    http = http.exceptionHandling().authenticationEntryPoint(
            (request, response, ex) -> {
                if (ex instanceof BadCredentialsException)
                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
                            messageSource.getMessage("error.authentication.badCredentials", null, LocaleContextHolder.getLocale()));
                else if (ex instanceof InsufficientAuthenticationException)
                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
                            messageSource.getMessage("error.authentication..noAuthority", null, LocaleContextHolder.getLocale()));
                else
                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, ex.getLocalizedMessage());
            }
    ).and();