Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.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 Boot REST Api JWT AuthorizationFilter不验证令牌_Java_Spring_Spring Boot_Jwt - Fatal编程技术网

Java Spring Boot REST Api JWT AuthorizationFilter不验证令牌

Java Spring Boot REST Api JWT AuthorizationFilter不验证令牌,java,spring,spring-boot,jwt,Java,Spring,Spring Boot,Jwt,我制作了一个示例spring boot应用程序,它实现了JWT令牌身份验证,部分工作正常。这意味着在通过使用/login url发送用户详细信息来生成令牌之前,它不允许请求访问端点。一旦接收到令牌,将使用名为Authorization的头发送令牌。因此,直到第一个url全部包含此标头,它才允许访问端点。但是在第一次呼叫之后,我可以在没有包含JWT令牌的授权头的情况下访问enpoints SecurityConfig.java @EnableWebSecurity @EnableGlobalMet

我制作了一个示例spring boot应用程序,它实现了JWT令牌身份验证,部分工作正常。这意味着在通过使用/login url发送用户详细信息来生成令牌之前,它不允许请求访问端点。一旦接收到令牌,将使用名为Authorization的头发送令牌。因此,直到第一个url全部包含此标头,它才允许访问端点。但是在第一次呼叫之后,我可以在没有包含JWT令牌的授权头的情况下访问enpoints

SecurityConfig.java

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final CustomUserDetailsService customUserDetailsService;

    @Autowired
    public SecurityConfig(CustomUserDetailsService customUserDetailsService) {
    this.customUserDetailsService = customUserDetailsService;
    System.out.println("from SecurityConfig constructor");
    System.out.println(this.customUserDetailsService.loadUserByUsername("batman").getUsername());
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
    System.out.println("from configure");
    http.cors().and().csrf().disable().authorizeRequests()

    .antMatchers(HttpMethod.POST, "/sign_up").permitAll()
    .antMatchers("/*/floor1/**").hasRole("USER")
    .antMatchers("/*/floor2/**").hasRole("ADMIN")
    .and()
    .addFilter(new JwtAuthenticationFilter(authenticationManager()))
    .addFilter(new JwtAuthorizationFilter(authenticationManager(), customUserDetailsService));
    }


}
JwtAuthenticationFilter.java

public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    private AuthenticationManager authenticationManager;

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
    this.authenticationManager = authenticationManager;
    }

    @Override
    // {"username":"batman","password":"123"}
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
    try {
        System.out.println(">>>>> AuthenticationFilter: checking user credentials....");
        ApplicationUser applicationUser = new ObjectMapper().readValue(request.getInputStream(), ApplicationUser.class);
        return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(applicationUser.getUsername(), applicationUser.getPassword()));
    } catch (IOException e) {
        System.out.println(">>>>> AuthenticationFilter: error in checking user credentials....");
        throw new RuntimeException(e);
    } catch (Exception e) {
        System.out.println(">>>>> AuthenticationFilter: error in checking user credentials....");
        throw new RuntimeException(e);
    }
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
    System.out.println(">>>>> AuthenticationFilter: successfulAuthentication creating token...");
    ZonedDateTime expirationTimeUTC = ZonedDateTime.now(ZoneOffset.UTC).plus(SecurityConstants.EXPIRATION_TIME, ChronoUnit.MILLIS);
    String token = Jwts.builder().setSubject(((User)authResult.getPrincipal()).getUsername())
        .setExpiration(Date.from(expirationTimeUTC.toInstant()))
        .signWith(SignatureAlgorithm.HS256, SecurityConstants.SECRET)
        .compact();
    response.getWriter().write(token);
    response.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX + token);
    System.out.println(">>>>> AuthenticationFilter: successfulAuthentication token created and added to response");
    }

}
public class JwtAuthorizationFilter extends BasicAuthenticationFilter {
    private final CustomUserDetailsService customUserDetailsService;


    public JwtAuthorizationFilter(AuthenticationManager authenticationManager, CustomUserDetailsService customUserDetailsService) {
    super(authenticationManager);
    this.customUserDetailsService = customUserDetailsService;
    }


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
    String header = request.getHeader(SecurityConstants.HEADER_STRING);
    System.out.println(">>>>> AuthorizationFilter doFilterInternal: checking the availability of toke header...");
    if(header == null || !header.startsWith(SecurityConstants.TOKEN_PREFIX)){
        System.out.println(">>>>> AuthorizationFilter doFilterInternal: header is null or not start with token prefix");
        chain.doFilter(request, response);
        return;
    }
    UsernamePasswordAuthenticationToken authenticationToken = getAuthenticationToken(request);
    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
    chain.doFilter(request, response);
    }

    private UsernamePasswordAuthenticationToken getAuthenticationToken(HttpServletRequest request){
    System.out.println(">>>>> AuthorizationFilter UsernamePasswordAuthentication: validating the token...");
    String token = request.getHeader(SecurityConstants.HEADER_STRING);
    if(token == null){
        System.out.println(">>>>> AuthorizationFilter UsernamePasswordAuthentication: error: token is null");
        return null;
    }
    String username = Jwts.parser().setSigningKey(SecurityConstants.SECRET).parseClaimsJws(token.replace(SecurityConstants.TOKEN_PREFIX, "")).getBody().getSubject();
    UserDetails userDetails = customUserDetailsService.loadUserByUsername(username);
    ApplicationUser applicationUser = customUserDetailsService.loadApplicationUserByUsername(username);
    return username != null ? new UsernamePasswordAuthenticationToken(applicationUser, null, userDetails.getAuthorities()) : null;
    }


}
JwtAuthorizationFilter.java

public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    private AuthenticationManager authenticationManager;

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
    this.authenticationManager = authenticationManager;
    }

    @Override
    // {"username":"batman","password":"123"}
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
    try {
        System.out.println(">>>>> AuthenticationFilter: checking user credentials....");
        ApplicationUser applicationUser = new ObjectMapper().readValue(request.getInputStream(), ApplicationUser.class);
        return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(applicationUser.getUsername(), applicationUser.getPassword()));
    } catch (IOException e) {
        System.out.println(">>>>> AuthenticationFilter: error in checking user credentials....");
        throw new RuntimeException(e);
    } catch (Exception e) {
        System.out.println(">>>>> AuthenticationFilter: error in checking user credentials....");
        throw new RuntimeException(e);
    }
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
    System.out.println(">>>>> AuthenticationFilter: successfulAuthentication creating token...");
    ZonedDateTime expirationTimeUTC = ZonedDateTime.now(ZoneOffset.UTC).plus(SecurityConstants.EXPIRATION_TIME, ChronoUnit.MILLIS);
    String token = Jwts.builder().setSubject(((User)authResult.getPrincipal()).getUsername())
        .setExpiration(Date.from(expirationTimeUTC.toInstant()))
        .signWith(SignatureAlgorithm.HS256, SecurityConstants.SECRET)
        .compact();
    response.getWriter().write(token);
    response.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX + token);
    System.out.println(">>>>> AuthenticationFilter: successfulAuthentication token created and added to response");
    }

}
public class JwtAuthorizationFilter extends BasicAuthenticationFilter {
    private final CustomUserDetailsService customUserDetailsService;


    public JwtAuthorizationFilter(AuthenticationManager authenticationManager, CustomUserDetailsService customUserDetailsService) {
    super(authenticationManager);
    this.customUserDetailsService = customUserDetailsService;
    }


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
    String header = request.getHeader(SecurityConstants.HEADER_STRING);
    System.out.println(">>>>> AuthorizationFilter doFilterInternal: checking the availability of toke header...");
    if(header == null || !header.startsWith(SecurityConstants.TOKEN_PREFIX)){
        System.out.println(">>>>> AuthorizationFilter doFilterInternal: header is null or not start with token prefix");
        chain.doFilter(request, response);
        return;
    }
    UsernamePasswordAuthenticationToken authenticationToken = getAuthenticationToken(request);
    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
    chain.doFilter(request, response);
    }

    private UsernamePasswordAuthenticationToken getAuthenticationToken(HttpServletRequest request){
    System.out.println(">>>>> AuthorizationFilter UsernamePasswordAuthentication: validating the token...");
    String token = request.getHeader(SecurityConstants.HEADER_STRING);
    if(token == null){
        System.out.println(">>>>> AuthorizationFilter UsernamePasswordAuthentication: error: token is null");
        return null;
    }
    String username = Jwts.parser().setSigningKey(SecurityConstants.SECRET).parseClaimsJws(token.replace(SecurityConstants.TOKEN_PREFIX, "")).getBody().getSubject();
    UserDetails userDetails = customUserDetailsService.loadUserByUsername(username);
    ApplicationUser applicationUser = customUserDetailsService.loadApplicationUserByUsername(username);
    return username != null ? new UsernamePasswordAuthenticationToken(applicationUser, null, userDetails.getAuthorities()) : null;
    }


}
在JwtAuthorizationFilter.java中,如果令牌为check for null,则返回true。因此,应该防止访问端点 并给客户端一个错误。但事实并非如此。它允许请求通过过滤器 并访问端点。如果我遗漏了什么,请帮助我


完整的示例项目:

在这里使用两个身份验证过滤器有什么意义?一个是通过验证用户名和密码来验证用户身份。另一个用于验证令牌