import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.domain.ReactiveAuditorAware;
import org.springframework.data.r2dbc.config.EnableR2dbcAuditing;
import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.security.core.context.SecurityContext;
@Configuration
@EnableR2dbcAuditing
@EnableR2dbcRepositories("repository.reactive")
@Import(DataSourceAutoConfiguration.class)
public class ReactiveConfig {
@Bean
public ReactiveAuditorAware<String> auditorAware() {
ReactiveAuditorAware<String> result = () -> ReactiveSecurityContextHolder.getContext()
.map(SecurityContext::getAuthentication)
.log()
.filter(Authentication::isAuthenticated)
.map(Authentication::getPrincipal)
.map(String.class::cast);
return result;
}
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.ReactiveAuditorAware;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import java.util.List;
@Configuration
@EnableWebFluxSecurity
@RequiredArgsConstructor
public class WebSecurityConfig {
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http, AuthWebFilter authWebFilter) {
return http
.addFilterBefore(authWebFilter, SecurityWebFiltersOrder.AUTHENTICATION)
.authorizeExchange(authorize -> authorize
.pathMatchers("", "/error", "/liveness", "/readiness").permitAll()
.anyExchange().authenticated()
)
.cors(cors -> cors.configurationSource(request -> {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(List.of("*"));
config.setAllowedMethods(List.of("*"));
config.setAllowedHeaders(List.of("*"));
return config;
}))
.csrf(ServerHttpSecurity.CsrfSpec::disable)
.formLogin(ServerHttpSecurity.FormLoginSpec::disable)
.httpBasic(ServerHttpSecurity.HttpBasicSpec::disable)
.build();
}
}
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.security.authentication.RememberMeAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
@Component
@Slf4j
public class AuthWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String userId = request.getHeaders().getFirst("X-User-Id");
if (StringUtils.hasText(userId)) {
log.info("[Authentication] User ID: {}", userId);
Authentication authentication = new RememberMeAuthenticationToken(userId + "_key", userId + "_principal", null);
return chain.filter(exchange)
.contextWrite(ReactiveSecurityContextHolder.withAuthentication(authentication));
}
return chain.filter(exchange);
}
}
import io.ustd.common.exception.BtsException;
import io.ustd.common.exception.ExceptionCode;
import io.ustd.common.exception.ExceptionResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.reactive.function.server.EntityResponse;
import org.springframework.web.reactive.function.server.ServerRequest;
import reactor.core.publisher.Mono;
@RestControllerAdvice
@Slf4j
public class CommonExceptionHandler {
@ExceptionHandler(BtsException.class)
public Mono<EntityResponse<ExceptionResponse>> handleException(BtsException e, ServerRequest request) {
log.error("BtsException: ", e);
ExceptionCode statusCode = e.getStatusCode();
return EntityResponse
.fromObject(ExceptionResponse.builder()
.code(statusCode.getCode())
.message(e.getMessage())
.path(request.path())
.build())
.status(statusCode.getHttpStatus())
.build();
}
}
'Framework & Platform > Spring' 카테고리의 다른 글
ThreadPoolTaskScheduler initialize method (0) | 2020.03.29 |
---|---|
spring - 4.2.0.RELEASE AsyncAnnotationBeanPostProcessor NoUniqueBeanDefinitionException (0) | 2015.08.04 |
spring - ServletContext (0) | 2015.07.16 |
spring - headers="Accept=*/*" (0) | 2014.12.26 |
spring - Get current ApplicationContext (0) | 2014.10.06 |