JWT 认证成功,但是邮递员返回 404
Posted
技术标签:
【中文标题】JWT 认证成功,但是邮递员返回 404【英文标题】:JWT authenticated succesfully, but the postman return 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。
【问题讨论】:
【参考方案1】:尝试在之后定义过滤器。
@Override
public void addFilters(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception
http
.addFilterAfter(authenticationFilter(), UsernamePasswordAuthenticationFilter.class);
【讨论】:
感谢您的建议,我已经尝试过了,但仍然面临同样的问题。以上是关于JWT 认证成功,但是邮递员返回 404的主要内容,如果未能解决你的问题,请参考以下文章