SecurityConfig.java
package io.featureprobe.api.auth;
import io.featureprobe.api.config.JWTConfig;
import io.featureprobe.api.base.model.BaseResponse;
import io.featureprobe.api.base.util.JsonMapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
@Slf4j
@Configuration
@EnableWebSecurity
@AllArgsConstructor
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private LoginFailureHandler loginFailureHandler;
private LoginSuccessHandler loginSuccessHandler;
private JWTConfig jwtConfig;
private UserPasswordAuthenticationProvider userPasswordAuthenticationProvider;
private GuestAuthenticationProvider guestAuthenticationProvider;
private AccessTokenAuthenticationProvider accessTokenAuthenticationProvider;
UserPasswordAuthenticationProcessingFilter userPasswordAuthenticationProcessingFilter(
AuthenticationManager authenticationManager) {
UserPasswordAuthenticationProcessingFilter userPasswordAuthenticationProcessingFilter =
new UserPasswordAuthenticationProcessingFilter();
userPasswordAuthenticationProcessingFilter.setAuthenticationManager(authenticationManager);
userPasswordAuthenticationProcessingFilter.setAuthenticationSuccessHandler(loginSuccessHandler);
userPasswordAuthenticationProcessingFilter.setAuthenticationFailureHandler(loginFailureHandler);
return userPasswordAuthenticationProcessingFilter;
}
GuestAuthenticationProcessingFilter guestAuthenticationProcessingFilter(
AuthenticationManager authenticationManager) {
GuestAuthenticationProcessingFilter guestAuthenticationProcessingFilter = new
GuestAuthenticationProcessingFilter();
guestAuthenticationProcessingFilter.setAuthenticationManager(authenticationManager);
guestAuthenticationProcessingFilter.setAuthenticationFailureHandler(loginFailureHandler);
guestAuthenticationProcessingFilter.setAuthenticationSuccessHandler(loginSuccessHandler);
return guestAuthenticationProcessingFilter;
}
AccessTokenAuthenticationProcessingFilter accessTokenAuthenticationProcessingFilter(
AuthenticationManager authenticationManager) {
AccessTokenAuthenticationProcessingFilter accessTokenAuthenticationProcessingFilter = new
AccessTokenAuthenticationProcessingFilter();
accessTokenAuthenticationProcessingFilter.setAuthenticationManager(authenticationManager);
accessTokenAuthenticationProcessingFilter.setAuthenticationFailureHandler(loginFailureHandler);
return accessTokenAuthenticationProcessingFilter;
}
@Bean
AuthenticationEntryPoint authenticationEntryPoint() {
AuthenticationEntryPoint authenticationEntryPoint = (httpServletRequest, httpServletResponse, e) ->
{
BaseResponse res = new BaseResponse(HttpStatus.UNAUTHORIZED.name().toLowerCase(),
HttpStatus.UNAUTHORIZED.getReasonPhrase());
httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
httpServletResponse.setCharacterEncoding(StandardCharsets.UTF_8.name());
httpServletResponse.getWriter().write(JsonMapper.toJSONString(res));
};
return authenticationEntryPoint;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.headers().frameOptions().disable();
http.csrf().disable();
http
.formLogin()
.loginProcessingUrl("/api/login")
.and()
.authorizeRequests()
.antMatchers("/internal/**", "/api/login", "/api/guestLogin", "/api/v3/api-docs.yaml",
"/api/application/**", "/api/public/**")
.permitAll()
// .antMatchers("/api/projects/**").hasAnyAuthority(OrganizationRoleEnum.OWNER.name(),
// OrganizationRoleEnum.WRITER.name())
.antMatchers("/api/**").authenticated()
.and()
.exceptionHandling()
.accessDeniedHandler(((httpServletRequest, httpServletResponse, e) ->
httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value())))
.authenticationEntryPoint(authenticationEntryPoint());
http.addFilterBefore(userPasswordAuthenticationProcessingFilter(authenticationManager()),
UsernamePasswordAuthenticationFilter.class);
if (!jwtConfig.isGuestDisabled()) {
http.addFilterBefore(guestAuthenticationProcessingFilter(authenticationManager()),
UserPasswordAuthenticationProcessingFilter.class);
}
http.addFilterBefore(accessTokenAuthenticationProcessingFilter(authenticationManager()),
UserPasswordAuthenticationProcessingFilter.class);
http.oauth2ResourceServer().jwt().jwtAuthenticationConverter(authenticationConverter());
}
@Override
protected AuthenticationManager authenticationManager() {
ProviderManager authenticationManager = new ProviderManager(Arrays.asList(userPasswordAuthenticationProvider,
guestAuthenticationProvider, accessTokenAuthenticationProvider));
return authenticationManager;
}
protected JwtAuthenticationConverter authenticationConverter() {
JwtGrantedAuthoritiesConverter authoritiesConverter = new JwtGrantedAuthoritiesConverter();
authoritiesConverter.setAuthorityPrefix("");
authoritiesConverter.setAuthoritiesClaimName(JwtHelper.AUTHORITIES_CLAIM_NAME);
JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
converter.setJwtGrantedAuthoritiesConverter(authoritiesConverter);
return converter;
}
}