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 |