Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否可以覆盖spring安全身份验证错误消息_Java_Spring_Spring Boot_Spring Security_Basic Authentication - Fatal编程技术网

Java 是否可以覆盖spring安全身份验证错误消息

Java 是否可以覆盖spring安全身份验证错误消息,java,spring,spring-boot,spring-security,basic-authentication,Java,Spring,Spring Boot,Spring Security,Basic Authentication,我们使用的是SpringBoot2.2.2 当用户输入错误的凭据时,我希望在json响应中返回自定义错误消息以及401状态代码,我是按照以下步骤操作的 WebSecurityConfig.java: @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { private final UserDetailsService userDeta

我们使用的是SpringBoot2.2.2

当用户输入错误的凭据时,我希望在json响应中返回自定义错误消息以及401状态代码,我是按照以下步骤操作的

WebSecurityConfig.java:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private final UserDetailsService userDetailsService;

    private final RestAuthenticationEntryPoint restAuthenticationEntryPoint;

    public WebSecurityConfig(RepositoryUserDetailsService userDetailsService RestAuthenticationEntryPoint restAuthenticationEntryPoint) {
        this.userDetailsService = userDetailsService;
        this.restAuthenticationEntryPoint = restAuthenticationEntryPoint;
    }

    @Override
    public void configure(final WebSecurity web) {
        web.ignoring()
                .antMatchers(HttpMethod.OPTIONS, "/**")
                .antMatchers("/proj-name/**/*.{js,html}")
                .antMatchers("/test/**");

    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
                .csrf()
                .disable()
                .exceptionHandling()
                .authenticationEntryPoint(restAuthenticationEntryPoint)
                .and()
                .headers()
                .frameOptions()
                .disable()
                .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.GET, "/login").permitAll()
                .antMatchers("/error").permitAll()
                .anyRequest().authenticated()
                .and()
                .httpBasic();
    }

 @Bean
    RestAuthenticationEntryPoint authenticationEntryPoint() {
        return new RestAuthenticationEntryPoint();
    }

    @Bean
    AuthenticationEntryPoint forbiddenEntryPoint() {
        return new HttpStatusEntryPoint(FORBIDDEN);
    }

    @Bean
    public CustomAuthenticationProvider customDaoAuthenticationProvider() throws Exception {
        CustomAuthenticationProvider customDaoAuthenticationProvider = new CustomAuthenticationProvider();
        customDaoAuthenticationProvider.setPasswordEncoder(new PasswordEncoderConfig().encoder());
        customDaoAuthenticationProvider.setUserDetailsService(userDetailsService);
        return customDaoAuthenticationProvider;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(customDaoAuthenticationProvider());
    }
}
重新验证EntryPoint.java

@Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        httpServletResponse.addHeader("WWW-Authenticate", "Basic realm=" + "");
        httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        PrintWriter writer = httpServletResponse.getWriter();
        writer.println("HTTP Status 401 - " + e.getMessage());
    }
}
CustomAuthenticationProvider.java

public class CustomAuthenticationProvider extends DaoAuthenticationProvider {

    @Autowired
    private PasswordEncoder passwordEncoder;

@Override
    protected void additionalAuthenticationChecks(UserDetails userDetails,
                                                  UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        if (authentication.getCredentials() == null) {
            logger.debug("Authentication failed: no credentials provided");
            throw new BadCredentialsException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "test bad credentials"));
        }

        String presentedPassword = authentication.getCredentials().toString();
        if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
            throw new BadCredentialsException(
                    messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials","Invalid credentials"));
        }
        
        }
        }
当我点击
/login
api时,返回以下响应:
需要完全身份验证才能访问此资源

如果我添加
.antMatchers(“/error”)。permitAll()
将返回以下响应

{
    "timestamp": 1594970514264,
    "status": 401,
    "error": "Unauthorized",
    "message": "Unauthorized",
    "path": "/login"
}
我尝试在CustomAuthenticationProvider上添加@Component注释,然后在服务器启动时抛出以下错误:
java.lang.IllegalArgumentException:必须设置UserDetails服务


我尝试按照添加CustomAuthenticationFailureHandler,但没有成功。我看过几篇文章,但这些例子也不起作用。我还尝试创建了一个带有@ControllerAdvice注释的异常处理程序类,但仍然没有成功。是否有其他方法覆盖默认错误消息,或者我是否缺少任何注释或配置?提前感谢您的帮助

您可以使用控制器建议来处理服务引发的错误:

@ControllerAdvice
@Order(HIGHEST_PRECEDENCE)
public class AppointmentErrorController {

    @ExceptionHandler(BadCredentialsException.class)
    public ResponseEntity<ApiError> handleError(HttpServletRequest request, BadCredentialsException ex) {
    ApiError apiError = new ApiError(...); //retrieve info from BadCredentialsException
    return ResponseEntity.status(HttpStatus.UNAUTHORIZED, apiError);
}
@ControllerAdvice
@顺序(最高优先级)
公共类任命错误控制器{
@ExceptionHandler(BadCredentialsException.class)
公共响应句柄错误(HttpServletRequest请求,BadCredentialsException ex){
APIRROR APIRROR=新APIRROR(…);//从BadCredentialsException检索信息
返回ResponseEntity.status(HttpStatus.UNAUTHORIZED,apiError);
}

您可以使用控制器建议来处理服务引发的错误:

@ControllerAdvice
@Order(HIGHEST_PRECEDENCE)
public class AppointmentErrorController {

    @ExceptionHandler(BadCredentialsException.class)
    public ResponseEntity<ApiError> handleError(HttpServletRequest request, BadCredentialsException ex) {
    ApiError apiError = new ApiError(...); //retrieve info from BadCredentialsException
    return ResponseEntity.status(HttpStatus.UNAUTHORIZED, apiError);
}
@ControllerAdvice
@顺序(最高优先级)
公共类任命错误控制器{
@ExceptionHandler(BadCredentialsException.class)
公共响应句柄错误(HttpServletRequest请求,BadCredentialsException ex){
APIRROR APIRROR=新APIRROR(…);//从BadCredentialsException检索信息
返回ResponseEntity.status(HttpStatus.UNAUTHORIZED,apiError);
}

尝试将
antMatchers(HttpMethod.GET,“/login”).permitAll()更改为
antMatchers(“/login”).permitAll()
谢谢您的建议。我尝试过,它仍然返回
“消息”:“Unauthorized”,
。尝试将
antMatchers(HttpMethod.GET,“/login”).permitAll()更改为
antMatchers(“/login”).permitAll()
谢谢你的建议。我试过了,它仍然会返回
“消息”:“未经授权”,