스프링 시큐리티 데이터 JDBC
전체 예제 코드는 kdevkr/spring-boot-security에서 확인할 수 있다.
Spring Data Integration를 참고하면 스프링 시큐리티와 스프링 데이터 모듈을 통합할 수 있다.
우선 아래와 같이 클래스패스에 org.springframework.security:spring-security-data
의존성을 추가하도록 하자.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.security:spring-security-data'
}
@Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
return new SecurityEvaluationContextExtension();
}
구성 클래스에서 SecurityEvaluationContextExtension를 빈으로 등록하면 @PreAuthorize와 같은 메소드 기반 표현식과 비슷하게 @Query 내에서 스프링 시큐리티에 대한 SpEL을 사용할 수 있다. 하지만, 스프링 시큐리티 공식 문서와 Spring Data에 대한 예제 코드와 같이 시도해보면 아래와 같은 오류
가 발생한다.
org.springframework.dao.InvalidDataAccessApiUsageException: SQL [SELECT u.username FROM users u where u.username = ?__$synthetic$__1]: given 1 parameters but expected 0
위와 같은 오류가 발생하는 이유는 Spring Data JDBC는 내부적으로 NamedParameterJdbcTemplate**를 사용하기 때문에 ?
와 같은 JPQL 또는 Native 쿼리 방식과는 차이가 있으므로 ?
이 아닌 :
로 표현해야한다.
@Repository
public interface UserRepository extends CrudRepository<User, String> {
@Query("SELECT u.username FROM users u where u.username = :#{ principal?.username }")
String getUsername();
}