Java Spring 401未经授权

时间:2020-09-21 18:36:21

标签: java spring spring-security config http-status-code-401

我正在关注有关Java Spring的教程,并找到了jwt的身份验证代码。到目前为止,没有问题,我可以生成令牌并登录/注册,并将这些令牌用于发布/获取请求的路由。但是问题是,两分钟后,我收到一个401未经授权的错误。而且我解决不了。

我正在关注的教程中的代码:

JwtAuthEntryPoint.java

public class JwtAuthEntryPoint implements AuthenticationEntryPoint {
 
    private static final Logger logger = LoggerFactory.getLogger(JwtAuthEntryPoint.class);
    
    @Override
    public void commence(HttpServletRequest request,
                         HttpServletResponse response,
                         AuthenticationException e) 
                             throws IOException, ServletException {
      
        logger.error("Unauthorized error. Message - {}", e.getMessage());
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Error -> Unauthorized");
    }
}

UserDetailsS​​erviceImpl.java

public class JwtAuthTokenFilter extends OncePerRequestFilter {
 
    @Autowired
    private JwtProvider tokenProvider;
 
    @Autowired
    private UserDetailsServiceImpl userDetailsService;
 
    private static final Logger logger = LoggerFactory.getLogger(JwtAuthTokenFilter.class);
 
    @Override
    protected void doFilterInternal(HttpServletRequest request, 
                    HttpServletResponse response, 
                    FilterChain filterChain) 
                        throws ServletException, IOException {
        try {
          
            String jwt = getJwt(request);
            if (jwt!=null && tokenProvider.validateJwtToken(jwt)) {
                String username = tokenProvider.getUserNameFromJwtToken(jwt);
 
                UserDetails userDetails = userDetailsService.loadUserByUsername(username);
                UsernamePasswordAuthenticationToken authentication 
                    = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
 
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        } catch (Exception e) {
            logger.error("Can NOT set user authentication -> Message: {}", e);
        }
 
        filterChain.doFilter(request, response);
    }
 
    private String getJwt(HttpServletRequest request) {
        String authHeader = request.getHeader("Authorization");
          
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
          return authHeader.replace("Bearer ","");
        }
 
        return null;
    }
}

JwtProvider.java

public class JwtProvider {
 
    private static final Logger logger = LoggerFactory.getLogger(JwtProvider.class);
 
    @Value("${grokonez.app.jwtSecret}")
    private String jwtSecret;
 
    @Value("${grokonez.app.jwtExpiration}")
    private int jwtExpiration;
 
    public String generateJwtToken(Authentication authentication) {
 
        UserPrinciple userPrincipal = (UserPrinciple) authentication.getPrincipal();
 
        return Jwts.builder()
                    .setSubject((userPrincipal.getUsername()))
                    .setIssuedAt(new Date())
                    .setExpiration(new Date((new Date()).getTime() + jwtExpiration))
                    .signWith(SignatureAlgorithm.HS512, jwtSecret)
                    .compact();
    }
 
    public String getUserNameFromJwtToken(String token) {
        return Jwts.parser()
                      .setSigningKey(jwtSecret)
                      .parseClaimsJws(token)
                      .getBody().getSubject();
    }
 
    public boolean validateJwtToken(String authToken) {
        try {
            Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
            return true;
        } catch (SignatureException e) {
            logger.error("Invalid JWT signature -> Message: {} ", e);
        } catch (MalformedJwtException e) {
            logger.error("Invalid JWT token -> Message: {}", e);
        } catch (ExpiredJwtException e) {
            logger.error("Expired JWT token -> Message: {}", e);
        } catch (UnsupportedJwtException e) {
            logger.error("Unsupported JWT token -> Message: {}", e);
        } catch (IllegalArgumentException e) {
            logger.error("JWT claims string is empty -> Message: {}", e);
        }
        
        return false;
    }
}

WebSecurityConfig.java

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
    prePostEnabled = true
)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    UserDetailsServiceImpl userDetailsService;
 
    @Autowired
    private JwtAuthEntryPoint unauthorizedHandler;
 
    @Bean
    public JwtAuthTokenFilter authenticationJwtTokenFilter() {
        return new JwtAuthTokenFilter();
    }
 
    @Override
    public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder
                .userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder());
    }
 
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
 
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable().
                authorizeRequests()
                .antMatchers("/api/auth/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        
        http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    }
}

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

一切取决于您在//output from mongo client //ran below queries and compared the output from explain. I did not find any difference in //execution stats for performance > db.myCollection.explain("executionStats").update( ... {}, ... {$pull:{fruits:{$in:["Banana"]}}}, ... {multi: true} ... ); { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.myCollection", "indexFilterSet" : false, "parsedQuery" : { }, "winningPlan" : { "stage" : "UPDATE", "inputStage" : { "stage" : "COLLSCAN", "direction" : "forward" } }, "rejectedPlans" : [ ] }, "executionStats" : { "executionSuccess" : true, "nReturned" : 0, "executionTimeMillis" : 0, "totalKeysExamined" : 0, "totalDocsExamined" : 2, "executionStages" : { "stage" : "UPDATE", "nReturned" : 0, "executionTimeMillisEstimate" : 0, "works" : 4, "advanced" : 0, "needTime" : 3, "needYield" : 0, "saveState" : 0, "restoreState" : 0, "isEOF" : 1, "nMatched" : 2, "nWouldModify" : 2, "wouldInsert" : false, "inputStage" : { "stage" : "COLLSCAN", "nReturned" : 2, "executionTimeMillisEstimate" : 0, "works" : 4, "advanced" : 2, "needTime" : 1, "needYield" : 0, "saveState" : 2, "restoreState" : 2, "isEOF" : 1, "direction" : "forward", "docsExamined" : 2 } } }, "serverInfo" : { "host" : "XXXX", "port" : XXXX, "version" : "4.2.6", "gitVersion" : "XXXX" }, "ok" : 1 } > -- > db.myCollection.explain("executionStats").update( ... {}, ... {$pull: ... {fruits:{$elemMatch:{$in:["Banana"]}}} ... }, ... {multi: true} ... ); { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.myCollection", "indexFilterSet" : false, "parsedQuery" : { }, "winningPlan" : { "stage" : "UPDATE", "inputStage" : { "stage" : "COLLSCAN", "direction" : "forward" } }, "rejectedPlans" : [ ] }, "executionStats" : { "executionSuccess" : true, "nReturned" : 0, "executionTimeMillis" : 0, "totalKeysExamined" : 0, "totalDocsExamined" : 2, "executionStages" : { "stage" : "UPDATE", "nReturned" : 0, "executionTimeMillisEstimate" : 0, "works" : 4, "advanced" : 0, "needTime" : 3, "needYield" : 0, "saveState" : 0, "restoreState" : 0, "isEOF" : 1, "nMatched" : 2, "nWouldModify" : 2, "wouldInsert" : false, "inputStage" : { "stage" : "COLLSCAN", "nReturned" : 2, "executionTimeMillisEstimate" : 0, "works" : 4, "advanced" : 2, "needTime" : 1, "needYield" : 0, "saveState" : 2, "restoreState" : 2, "isEOF" : 1, "direction" : "forward", "docsExamined" : 2 } } }, "serverInfo" : { "host" : "XXXX", "port" : XXX, "version" : "4.2.6", "gitVersion" : "XXXX" }, "ok" : 1 } > 中为setExpiration设置的值。

在您的示例中,您需要更改从配置文件读取的jws.bulder

另一种方式可以替换一些代码,例如:

jwtExpiration

.setExpiration(Date.from(Instant.now() + "your_desired_time")) 文件中,而不是您的代码中。

* 请注意,您设置的值是毫秒 的到期时间。