У меня есть следующая конфигурация безопасности и даже если я разрешаю кому-либо выполнять операцию входа в систему, она выдает несанкционированное исключение при отправке запроса через / путь входа в систему. В чем может быть причина?
применение jwtconfig к http также относится ко всем запросам allowAll?
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().disable()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/actuator/**").permitAll()
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/user/**").permitAll()
.antMatchers("/admin/**").hasAuthority("ROLE_ADMIN")
.anyRequest().authenticated()
.and()
.apply(new JwtConfig());
}
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("**/swagger-resources/**",
"/swagger-ui.html",
"/v2/api-docs",
"/webjars/**");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin")
.password(bCryptPasswordEncoder().encode("abcd123"))
.roles("ROLE_ADMIN");
}
Класс конфигурации JWT
public class JwtConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
@Autowired
JwtTokenProvider jwtTokenProvider;
@Override
public void configure(HttpSecurity http) {
JwtTokenFilter customFilter = new JwtTokenFilter();
http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class);
}
}
Фильтр токенов JWT
public class JwtTokenFilter extends GenericFilterBean {
@Autowired
JwtTokenProvider jwtTokenProvider;
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String token = jwtTokenProvider.resolveToken((HttpServletRequest) servletRequest);
try {
if (token != null && jwtTokenProvider.validateToken(token)) {
Authentication auth = jwtTokenProvider.getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(auth);
}
} catch (Exception e) {
e.printStackTrace();
}
filterChain.doFilter(servletRequest, servletResponse);
}
}
Поставщик токенов JWT
@Component
public class JwtTokenProvider extends UsernamePasswordAuthenticationFilter {
@Value("${security.jwt.token.secret-key:secret}")
private String secretKey = "secret";
@Value("${security.jwt.token.expire-length:3600000}")
private long validityInMilliseconds = 3600000;
@Autowired
ModelMapper modelMapper;
@Autowired
UserService userService;
@Override
@Autowired
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
super.setAuthenticationManager(authenticationManager);
}
@PostConstruct
protected void init() {
secretKey = Base64.getEncoder().encodeToString(secretKey.getBytes());
}
public String createToken(String username, Set<Role> roles) {
Claims claims = Jwts.claims().setSubject(username);
claims.put("roles", roles);
Date now = new Date();
Date validity = new Date(now.getTime() + validityInMilliseconds);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(now)
.setExpiration(validity)
.signWith(SignatureAlgorithm.HS256, secretKey)
.compact();
}
Authentication getAuthentication(String token) {
User user = userService.loadUserByUsername(getUsername(token));
return new UsernamePasswordAuthenticationToken(user, "", user.getAuthorities());
}
String getUsername(String token) {
return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject();
}
String resolveToken(HttpServletRequest req) {
String bearerToken = req.getHeader("Authorization");
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
return bearerToken.substring(7);
} else return null;
}
boolean validateToken(String token) throws Exception {
try {
Jws<Claims> claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token);
if (claims.getBody().getExpiration().before(new Date())) {
return false;
} else return true;
} catch (JwtException | IllegalArgumentException e) {
throw new Exception("Expired or invalid JWT token");
}
}
}
Субъект пользователя
@Entity
@JsonIgnoreProperties(value = {"createdAt", "updatedAt", "role", "enabled",
"authorities", "credentialsNonExpired", "accountNonLocked", "accountNonExpired"})
@Data
public class User extends Base implements UserDetails {
//@Length(min = 4, max = 20)
@NotNull
private String username;
//@Length(min = 4, max = 20)
@NotNull
private String password;
@NotNull
@Email
private String email;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name = "USER_ROLES", joinColumns = {
@JoinColumn(name = "USER_ID") }, inverseJoinColumns = {
@JoinColumn(name = "ROLE_ID") })
private Set<Role> roles = new HashSet<>();
@OneToMany
private List<Book> bookList = new ArrayList<>();
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<SimpleGrantedAuthority> simpleGrantedAuthorityList = new LinkedList<>();
roles.stream().forEach(role -> simpleGrantedAuthorityList.add(new SimpleGrantedAuthority(role.getName())));
return simpleGrantedAuthorityList;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}