1. Spring Security Dependency 추가

 

gradle

dependencies { implementation "org.springframework.boot:spring-boot-starter-security" }

maven

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>2.6.1</version>
</dependency>

 

 

2. Security패키지를 생성하고, 안에 SecurityConfig클래스를 추가한다.

: SecurityConfig클래스는 WebSecurityConfigureAdapter를 상속받는다.

 

기본 설정이 된 SecurityConfig클래스의 코드는 아래와 같다.

@Configuration // 설정을 위한 어노테이션
@EnableWebSecurity // 스프링 시큐리티 사용을 위한 어노테이션
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private AuthenticationProvider authenticationProvider;

    @Override
    public void configure(HttpSecurity http) throws Exception { // Security 기본 설정
        http.authorizeRequests()
                .antMatchers("/css/**", "/js/**", "/img/**", "/favicon.ico").permitAll() // resource들은 권한 없이 접근 가능하다.
                .antMatchers("/").hasRole("USER")
                .anyRequest().authenticated();

        http.formLogin()
                .loginPage("/login")
                .loginProcessingUrl("/authenticate") // login페이지 form의 action과 값이 같아야한다.
                .usernameParameter("userId")
                .passwordParameter("password")
                .defaultSuccessUrl("/")
                .failureUrl("/login?error")
                .permitAll();

        http.logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login");

        http.sessionManagement()
                .maximumSessions(1)
                .maxSessionsPreventsLogin(false); // 먼저 접속한 사용자를 로그아웃 시킨다.
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(authenticationProvider);
    }
}

스프링 시큐리티에서는 자동적으로 CSRF 보호가 실행되기 때문에,
당장 관련 설정을 하지 않는다면 csrf.disable()을 설정해 CSRF보호를 꺼 놓아야 개발하기 편하다. (위 코드엔 없다)

만약 보호를 꺼 놓지 않는다면 스프링 시큐리티가 CSRF로부터 보호를 시작하기 때문에 정상적으로 작동시키려면
서버에서 토큰을 발행하고 클라이언트 측에서도 서버에 요청할 때에 CSRF토큰을 포함해서 보내야 하기 때문이다.

 

 

3. SecurityConfig클래스에서 호출한 authenticationProvider인터페이스를 상속받아 클래스를 작성한다.

@Component
public class UserAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private AuthService authService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String userId = authentication.getName();
        String password = authentication.getCredentials().toString();
        return authService.authenticate(userId, password);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return true;
    }
}

Authentication은 세션 정보를 저장해놓는 컨텍스트이다.

클래스 안에는 Principal(아이디), Authority(권한), Credential(패스워드)이 있고,

 

사용자가 화면을 열면 > 스프링 시큐리티가 UserAuthenticcationProvider을 열어서 아이디 패스워드값을 Authentication컨텍스트에 저장 > 서비스 클래스로 가서 DB검증하고, 패스워드 값 맞춰서 보낼 정보 중 민감한 정보는 지우고, 권한 부여하고(DB에 기록되어 있는) > 접근을 허용하는 방식으로 진행된다.

 

Spring Security는 Filter 기반으로 운용되고, SpringMVC와는 독립적으로 동작한다는걸 알면 이해하기 수월하다.

 

 

4. 인증을 위한 서비스 클래스를 만들어준다.

@Service
public class AuthService {

    @Autowired
    private UserMapper userMapper;

    public Authentication authenticate(String userId, String password) {
        UserVo userVo = userMapper.getUser(userId);
        if (userVo != null) {
            if (userVo.getPassword().equals(password)) { 
                userVo.setPassword(null); // 보안을 위해 확인이 끝나면 삭제한다.
                List<SimpleGrantedAuthority> authorities = new ArrayList<>();
                authorities.add(new SimpleGrantedAuthority(userVo.getRole()));  
                return new UsernamePasswordAuthenticationToken(userVo, null, authorities);
            }
        }

        throw new BadCredentialsException("No such user.");
    }

 

 

 

 

'Java > SpringBoot' 카테고리의 다른 글

Spring boot : Mustache 사용시 한글 인코딩 설정  (0) 2024.03.11
Spring Security CSRF 설정  (0) 2021.12.09
Logback 기본 설정  (0) 2021.12.07

+ Recent posts