#java #spring #spring-boot #spring-security #jwt
#java #spring #spring-boot #spring-безопасность #jwt
Вопрос:
Хорошо, допустим, у меня есть JwtAuthenticationFilter:
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
//blabla
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String jwt = extract(request);
if (StringUtils.hasText(jwt) amp;amp; tokenVerifier.verify(jwt)) {
UserCredential user = getUserCredential(jwt, getTokenSigningKey());
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, null, buildAuthorities(user));
SecurityContextHolder.getContext().setAuthentication(auth);
}
filterChain.doFilter(request, response);
}
}
И JwtAuthenticationEntryPoint:
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
AuthenticationException e) throws IOException {
log.error("Responding with unauthorized error.");
httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
httpServletResponse.getWriter().write("Unauthorized");
}
}
Затем WebSecurityConfig:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
securedEnabled = true,
jsr250Enabled = true,
prePostEnabled = true
)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private static final String[] AUTH_WHITELIST = {
"/v3/api-docs/**"
};
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter() {
return new JwtAuthenticationFilter();
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Bean(BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http
.cors().and().csrf().disable()
.exceptionHandling()
.authenticationEntryPoint(unauthorizedHandler)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
// No need authentication.
.antMatchers(AUTH_WHITELIST).permitAll();
registry.anyRequest().authenticated();
// Add our custom JWT security filter
http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
Все в порядке. Всякий раз, когда я делаю вызов любого API (кроме белого списка) без токена,
commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e)
будет выполнено, я увижу 401 ответ. Все в порядке.
НО дело в том, что после выполнения метода stegin цепочка фильтров будет прервана. Я имею в виду, что все оставшиеся фильтры НЕ будут выполнены. Как я могу заставить цепочку выполняться непрерывно, даже если метод begin выполняется? Или любой другой механизм безопасности JWT, позволяющий не останавливать цепочку фильтров даже при сбое аутентификации?
Комментарии:
1. вы всегда устанавливаете запрос как несанкционированный, поэтому нет необходимости продолжать цепочку фильтров, потому что ваш фильтр не удался. Я предполагаю, что если вы не установите статус на несанкционированный, он будет продолжаться
2. какой метод вы упоминаете?