Я пытаюсь реализовать аутентификацию и авторизацию с использованием токена JWT в SpringBoot REST API.
В моем классе JWTAuthentication
@Override
protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res,
FilterChain chain, Authentication auth) throws IOException, ServletException {
String token = Jwts.builder().setSubject(((User) auth.getPrincipal()).getUsername())
.claim("roles", ((User) auth.getPrincipal()).getAuthorities())
.setExpiration(new Date(System.currentTimeMillis() + SecurityConstants.EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS512, SecurityConstants.SECRET.getBytes()).compact();
res.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX + token);
chain.doFilter(req, res);
System.out.println("Token:"+token);
}
Когда я проверяю свой код, отправляя, отправляя следующее сообщение на URL 127.0.0.1:8080/login, я вижу, что аутентификация прошла успешно.
{"username":"admin", "password":"admin"}
И тогда Spring вызывает мой класс авторизации JWT
@Override
protected void doFilterInternal(
HttpServletRequest req, HttpServletResponse res, FilterChain chain)
throws IOException, ServletException {
String header = req.getHeader(SecurityConstants.HEADER_STRING);
if (header == null || !header.startsWith(SecurityConstants.TOKEN_PREFIX)) {
if (header == null) {
System.out.println("header null");
} else if (!header.startsWith(SecurityConstants.TOKEN_PREFIX)) {
System.out.println("token prefix missing in header");
}
chain.doFilter(req, res);
return;
}
UsernamePasswordAuthenticationToken authentication = getAuthentication(req);
SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(req, res);
}
Он печатает сообщение: «Префикс токена отсутствует в заголовке»
Хотя я добавляю TOKEN_PREFIX в успешной аутентификации метод, он не может найти его в заголовке в методе doFilterInternal.
Кстати, моя конфигурация безопасности выглядит следующим образом:
@EnableWebSecurity(debug = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired private UserDetailsService userDetailsService;
@Autowired private BCryptPasswordEncoder bCryptPasswordEncoder;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors()
.and()
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/admin/**")
.hasRole("ADMIN")
.anyRequest()
.authenticated()
.and()
.addFilter(new JWTAuthenticationFilter(authenticationManager()))
.addFilter(new JWTAuthorizationFilter(authenticationManager()))
// this disables session creation on Spring Security
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(
"/v2/api-docs",
"/configuration/ui",
"/swagger-resources/**",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**");
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
return source;
}
}
Я проверил книги SpringBoot, но не смог найти книга, которая описывает внутренние детали структуры безопасности. Поскольку я не понимал, как работает фреймворк, я не мог решить проблемы, просто просматривая блоги. Есть ли книга, в которой вы можете предложить подробные сведения о безопасности SpringBoot?
Спасибо