본문 바로가기

Spring/Security

Spring Security 7: 데이터베이스를 이용해 인증하기(JDBC) #1

복습

https://joyfulviper.tistory.com/77

앞서 인증 처리는 AuthenticationManager 인터페이스가 하고 구현체로는 ProviderManager가 있다고 설명했다. 또한 ProviderManager에는 여러개의 AuthenticationProvider(인터페이스)가 List로 존재하며 인증 타입에 따라 List를 순회하며 인증 처리를 수행한다. 이 중 http 인증 처리를 수행할 때 가장 기본적으로 사용되는 구현체는 DaoAuthenticationProvider 이다.

 

데이터베이스를 이용해 인증하기 위해서는 위의 배경지식이 필요하다.

이제 구현해보자

JdbcDaoImpl

DaoAuthenticationProvider 내부를 들여다 보면 사용자를 UserDetailsService 객체의 loadUserByUsername 함수를 호출해서 사용자가 인증된 사용자인지 아닌지를 검증하는데, UserDetailsService(인터페이스)를 구현체로 JdbcDaoImpl 클래스로 설정해주면 데이터베이스에서 인증된 사용자를 로드한다.

 

 

필요한 테이블과 필드는 위 필드 중 ddl에 해당하는 경로의 파일을 확인하거나 테이블과 쿼리를 커스텀할 수 있다.

 

여기서 boolean 값 들에 대해 간단히 설명하자면 다음과 같다.

 

enableAuthorities: 이 옵션을 활성화하면, authoritiesByUsernameQuery를 사용하여 특정 사용자의 권한(authorities)을 데이터베이스에서 직접 로드한다. 결과적으로 각 사용자는 하나 이상의 권한을 가질 수 있으며, 이 권한은 사용자가 접근할 수 있는 리소스나 역할을 결정한다.

enableGroups: 이 옵션을 활성화하면, 사용자는 특정 그룹에 속하게 된다. 각 그룹은 자체적인 권한 집합을 가질 수 있으며, 사용자는 소속된 그룹의 권한을 상속받게 된다. 그룹은 여러 사용자를 묶어 동일한 권한 세트를 부여하려는 경우에 유용하다.

 

커스텀한 테이블

 

 

코드는 아래와 같이 작성하면 된다. 나의 경우 테이블을 커스텀해서 만들었기 때문에 아래와 같이 쿼리를 초기화 해줬다.

 

@Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http, DataSource dataSource) throws Exception {

        var authenticationManager = http.getSharedObject(AuthenticationManagerBuilder.class);
        authenticationManager.jdbcAuthentication()
                .dataSource(dataSource)
                .usersByUsernameQuery(
                        "SELECT " +
                                "login_id, passwd, true " +
                                "FROM " +
                                "USERS " +
                                "WHERE " +
                                "login_id = ?"
                )
                .groupAuthoritiesByUsername(
                        "SELECT " +
                                "u.login_id, g.name, p.name " +
                                "FROM " +
                                "users u JOIN groups g ON u.group_id = g.id " +
                                "LEFT JOIN group_permission gp ON g.id = gp.group_id " +
                                "JOIN permissions p ON p.id = gp.permission_id " +
                                "WHERE " +
                                "u.login_id = ?"
                )
                .getUserDetailsService().setEnableAuthorities(false);
    }