java spring security with jwt token returns 401 html page not json

fxnxkyjh  于 2023-05-27  发布在  Java
关注(0)|答案(1)|浏览(151)

为什么Spring返回401 HTML页面而不是我的自定义JSON API响应错误?什么是最好的方法来解决它(覆盖Spring配置)
安全性:

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .httpBasic().disable()
            .csrf().disable()
            .cors().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
            .authorizeRequests()
            .antMatchers("/v2/api-docs").permitAll()
            .antMatchers("/configuration/ui").permitAll()
            .antMatchers("/swagger-resources/**").permitAll()
            .antMatchers("/configuration/security").permitAll()
            .antMatchers("/swagger-ui.html").permitAll()
            .antMatchers("/swagger-ui/*").permitAll()
            .antMatchers("/webjars/**").permitAll()
            .antMatchers("/v2/**").permitAll()
            .antMatchers(LOGIN_ENDPOINT, REGISTER_ENDPOINT, "/v2/api-docs", "/swagger-ui.html", 
"/v2/swagger-ui.html").permitAll()
            .antMatchers(ADMIN_ENDPOINT).hasRole("ADMIN")
            .anyRequest().authenticated()
            .and()
            .apply(new JwtConfigurer(jwtTokenProvider));
}

过滤器:

public class JwtTokenFilter extends GenericFilterBean {
private final JwtTokenProvider jwtTokenProvider;

public JwtTokenFilter(JwtTokenProvider jwtTokenProvider) {
    this.jwtTokenProvider = jwtTokenProvider;
}

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain)
        throws IOException, ServletException {

    String token = jwtTokenProvider.resolveToken((HttpServletRequest) req);

    try {
        if (token != null && jwtTokenProvider.isTokenValid(token)) {
            var authentication = jwtTokenProvider.getAuthentication(token);

            if (authentication != null) {
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }
    } catch (JwtAuthenticationException e) {
        SecurityContextHolder.clearContext();
        ((HttpServletResponse) res).sendError(e.getHttpStatus().value());
        ((HttpServletResponse) res).setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        filterChain.doFilter(req, res);
        throw new JwtAuthenticationException("JWT token is expired or invalid", 
HttpStatus.UNAUTHORIZED);
    }
    filterChain.doFilter(req, res);
}
}

所以我实现了自定义异常处理程序和过滤器,我需要的是这种类型的错误

{
   "errorMessage": "Invalid username or password",
   "validationErrors": null
}

这是我在登录时得到的例子,成功的情况下得到令牌也是工作

{
"username": "vovaflex",
"token": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ2b3ZhZmxleCIsInJvbGVzIjpbIlJPTEVfVVNFUiJdLCJpYXQiOjE2MTk4NjQ2MDksImV4cCI6MTYxOTg2ODIwOX0.Oc7AG5ZncfAT3QB8l0mkYDkBr5ZjBfJ2MxLe3M12DF8",
"roles": [
    {
        "id": 1,
        "created": "2021-04-03T18:14:51.891+00:00",
        "updated": "2021-04-03T18:14:51.891+00:00",
        "status": "ACTIVE",
        "name": "ROLE_USER",
        "users": null
    }
]
}

但乳清例如令牌不正确或过期等,我得到401未经授权(正确),但不是JSON与消息,我设置我得到完整的HTML页面错误

<!doctype html>
<html lang="en">
<head>
    <title>HTTP Status 401 – Unauthorized</title>
</head>

<body>
    <h1>HTTP Status 401 – Unauthorized</h1>
</body>
</html>
tf7tbtn2

tf7tbtn21#

对于自定义JSON错误块,您需要做两件事
实现AuthenticationEntryPoint。

public class AuthExceptionEntryPoint implements AuthenticationEntryPoint
{
    @Override
    public void commence(
        HttpServletRequest request, 
        HttpServletResponse response, 
        AuthenticationException arg2
    ) throws IOException, ServletException {
        
    }
}

并在配置的websecurity设置中添加该引用(HttpSecurity http)

@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter
{   
    @Override
    public void configure(HttpSecurity http) throws Exception
    {
        http.exceptionHandling().authenticationEntryPoint(new AuthExceptionEntryPoint()) ;

    }
}

有关详细信息,请查看这两个资源
JSON custom authentication
JSON custom error response

相关问题