【问题标题】:JWT authenticated succesfully, but the postman return 404JWT 认证成功,但是邮递员返回 404
【发布时间】:2020-11-17 03:45:06
【问题描述】:

所以,这是我第一次使用 jwt 作为我的 API 的身份验证,我从其他来源看到了很多示例,最后我写进了我的代码,如下所示。 (请不要介意那里未使用的变量)。

我的目标是使用从登录阶段生成的 jwt 与我的 sso 对来自 /engagement/** 端点的任何请求进行身份验证,然后解码该 jwt 并在点击参与 API 时对其进行验证,直到此时,当我看到我的日志时,当我点击我的参与 API 时,任何身份验证都运行顺利。

但是,最后,不是返回我的 json 数据(是的,我的数据库中有参与数据),邮递员总是给我错误 404,我不知道为什么。 这有什么问题?

AuthenticationFilter.java

public class AuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    @Value("${fintax.app.client_secret}")
    private String clientSecret;
    
    private static final Logger logger = LoggerFactory.getLogger(AuthenticationFilter.class);
    private final ObjectMapper objectMapper = new ObjectMapper();
    private static final String ERROR_MESSAGE = "Something went wrong while parsing /login request body";
    private AuthenticationManager authManager;
    
    AuthenticationFilter(final RequestMatcher requiresAuth) {
        super(requiresAuth);
    }
    
  @Override
  public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException {

      
      String token  = httpServletRequest.getHeader("Authorization");      
      String secret = clientSecret;
      
      String bearer = token.replace("Bearer", "").trim();

      Algorithm algorithm = Algorithm.HMAC512(Base64.getDecoder().decode(secret));
      JWTVerifier verifier = JWT.require(algorithm)
         .withSubject("xxxx-xxxx@xxxx.id") //i'm hardcoded this for testing
          .build();

      DecodedJWT jwt = verifier.verify(bearer);
      
      UserModel user = new UserModel();
      user.setUserId(jwt.getSubject());
      
      List<GrantedAuthority> authorities =  AuthorityUtils.commaSeparatedStringToAuthorityList("");
      return new UsernamePasswordAuthenticationToken(user, null, authorities);

  }
    
    
    
    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult)
            throws IOException, ServletException {
        super.successfulAuthentication(request, response, chain, authResult);

        // As this authentication is in HTTP header, after success we need to continue the request normally
        // and return the response as if the resource was not secured at all
        chain.doFilter(request, response);
    }
    
    
}

WebSecurityConfig.java

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


 private static final RequestMatcher PROTECTED_URLS = new OrRequestMatcher(
  new AntPathRequestMatcher("/engagement/**")
 );


 @Override
 public void configure(final WebSecurity webSecurity) {
  webSecurity.ignoring()
      .antMatchers("/api/v1/auth/login")
      .antMatchers("/api/v1/auth/logout");
 }

 @Override
 public void configure(HttpSecurity http) throws Exception {
      http.sessionManagement()
       .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
       .and()
       .exceptionHandling()
       .and()
       .addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter.class)
       .authorizeRequests()
       .requestMatchers(PROTECTED_URLS)
       .authenticated()
       .and()
       .cors().and().csrf().disable();
     
 }

 @Bean
 AuthenticationFilter authenticationFilter() throws Exception {
  final AuthenticationFilter filter = new AuthenticationFilter(PROTECTED_URLS);
  filter.setAuthenticationManager(authenticationManager());
  //filter.setAuthenticationSuccessHandler(successHandler());
  return filter;
 }

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

WebConfig.java

@Configuration
public class WebConfig {

    @Bean
    public ServletWebServerFactory servletContainer() {

        var tomcat = new TomcatServletWebServerFactory() {

            @Override
            protected void postProcessContext(Context context) {

                var securityConstraint = new SecurityConstraint();
                securityConstraint.setUserConstraint("CONFIDENTIAL");

                var collection = new SecurityCollection();
                collection.addPattern("/*");
                securityConstraint.addCollection(collection);
                context.addConstraint(securityConstraint);
            }
        };

        tomcat.addAdditionalTomcatConnectors(redirectConnector());
        return tomcat;
    }

    private Connector redirectConnector() {

        var connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setScheme("http");
        connector.setPort(8080);
        connector.setSecure(false);
        connector.setRedirectPort(8443);

        return connector;
    }
     
}

邮递员日志

{
    "timestamp": "2020-07-28T06:10:52.881+00:00",
    "status": 404,
    "error": "Not Found",
    "message": "",
    "path": "/"
}

更新

所以我检查了邮递员控制台,它有像这张图片一样的可疑日志,我的发布方法总是以某种方式丢失,然后邮递员重定向到获取方法和根 url。

【问题讨论】:

    标签: java spring-boot authentication jwt http-status-code-404


    【解决方案1】:

    尝试在之后定义过滤器。

        @Override
        public void addFilters(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {
            http
                .addFilterAfter(authenticationFilter(), UsernamePasswordAuthenticationFilter.class);
        }
    

    【讨论】:

    • 感谢您的建议,我已经尝试过了,但仍然面临同样的问题。
    猜你喜欢
    • 1970-01-01
    • 2020-03-26
    • 1970-01-01
    • 2020-05-25
    • 1970-01-01
    • 2021-07-03
    • 2018-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多