【发布时间】: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