【问题标题】:Spring Boot + jjwt security return nothing on bad requestSpring Boot + jwt security 在错误请求时不返回任何内容
【发布时间】:2022-01-25 15:02:26
【问题描述】:

我的问题是,在使用错误的登录凭据发送请求后或在未经身份验证的情况下访问端点时,我没有得到任何响应。 这是我发送一个好的请求时的样子: Good Response screen

这就是请求正文无效时的样子: Invalid credentials request

MyUserDetails 类:

public class MyUserDetailService implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return new User("foo", "foo", List.of());
    }
}

安全配置类:

public class SecurityConfigurer extends WebSecurityConfigurerAdapter {
    @Autowired
    private MyUserDetailService myUserDetailService;
    @Autowired
    private JwtFilter jwtFilter;

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailService);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/auth").permitAll()
                .anyRequest().authenticated()
                .and().sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().csrf().disable();
        http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
    }
}

Jwt 过滤器类:

@Component
public class JwtFilter extends OncePerRequestFilter {

    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private MyUserDetailService myUserDetailService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        final String authHeader = request.getHeader("Authorization");
        String username = null;
        String requestToken = null;

        if(authHeader != null && authHeader.startsWith("Bearer ")) {
            requestToken = authHeader.substring(7);
            username = jwtUtil.getUsernameFromToken(requestToken);
        }
        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = myUserDetailService.loadUserByUsername(username);
            if(jwtUtil.validateToken(requestToken, userDetails)) {
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
                        new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            }
        }
        filterChain.doFilter(request, response);
    }

最后是我的控制器:

@PostMapping("/auth")
    public AuthResponse auth(@RequestBody AuthRequest authRequest) throws Exception {
        try {
            authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(authRequest.getUsername(), authRequest.getPassword())
            );
        } catch (BadCredentialsException e) {
            throw new Exception("Invalid Credentials", e);
        }
        final UserDetails userDetails = myUserDetailService.loadUserByUsername(authRequest.getUsername());
        final String token = jwtUtil.generateToken(userDetails);
        return new AuthResponse(token);
    }

编辑: 我忘了粘贴依赖项。

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'io.jsonwebtoken:jjwt:0.9.1'
    implementation 'javax.xml.bind:jaxb-api:2.2.4'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

我还有 AuthRequest 和 AuthResponse 类,其中包含用户名、密码、jwt 令牌以及所有构造函数、getter 和 setter(imo 不值得在这里过去)

【问题讨论】:

    标签: java spring-boot spring-security


    【解决方案1】:

    你必须在验证时抛出一个异常(以下是我使用的,抓住这个概念,你的类和库可能不同):

    Jwts.parser().setSigningKey(your_jwt_secret).parseClaimsJws(token);
    

    因此,如果您的令牌无法被解析,则抛出此错误并发送错误响应:

      httpServletResponse.setContentType("application/json");
      httpServletResponse.getWriter().write("your_custom_error");
      httpServletResponse.getWriter().flush();
    

    【讨论】:

    • @DamianRecruit 你申请了吗?
    猜你喜欢
    • 1970-01-01
    • 2019-11-18
    • 1970-01-01
    • 2021-07-07
    • 2018-05-03
    • 2014-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多