src/main/java/hexlet/code/config/SecurityConfig.java
package hexlet.code.config;
import hexlet.code.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Autowired
private JwtDecoder jwtDecoder;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private UserService userService;
/**
* Get configuration for different security levels.
* @param http allows configuring web based security for specific http requests
* @param introspector gets information from the HandlerMapping that would serve a specific request
* @return filter chain which is capable of being matched against an HttpServletRequest
* in order to decide whether it applies to that request
*/
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http, HandlerMappingIntrospector introspector)
throws Exception {
var mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector);
return http
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(auth -> auth
.requestMatchers(mvcMatcherBuilder.pattern("/")).permitAll()
.requestMatchers(mvcMatcherBuilder.pattern("/api/login")).permitAll()
.requestMatchers(mvcMatcherBuilder.pattern("/index.html")).permitAll()
.requestMatchers(mvcMatcherBuilder.pattern("/assets/**")).permitAll()
.requestMatchers(mvcMatcherBuilder.pattern("/swagger-ui/**")).permitAll()
.requestMatchers(mvcMatcherBuilder.pattern("/v3/api-docs/**")).permitAll()
.anyRequest().authenticated())
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.oauth2ResourceServer(rs -> rs.jwt(jwt -> jwt.decoder(jwtDecoder)))
.httpBasic(Customizer.withDefaults())
.build();
}
/**
* Get authentication manager.
* @param http allows configuring web based security for specific http requests
* @return authentication manager that processes an authentication request
*/
@Bean
public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception {
return http.getSharedObject(AuthenticationManagerBuilder.class)
.build();
}
/**
* Get authentication provider.
* @return authentication provider that can process a specific authentication implementation
*/
@Bean
public AuthenticationProvider daoAuthProvider() {
var provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(userService);
provider.setPasswordEncoder(passwordEncoder);
return provider;
}
}