시큐리티 설정 파일
시큐리티와 관련된 모든 설정들을 관리하는 config 클래스 이다.
스프링 부트 버전 2.7.0 이전에는 ' WebSecurityConfigurerAdapter ' 를 상속( * 페이지 이동 )받아서 사용해야하며, 이후 부터는 사용되지 않으므로 주의 해야한다.
📑SecurityConfig.java
package com.example.springsecurity.config;
import lombok.extern.log4j.Log4j2;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@Log4j2
public class SecurityConfig {
}
01 ) 패스워드 암호화 - PasswordEncoder
인증을 위해 반드시 PasswordEncoder 를 지정해야한다. 스프링 시큐리티에서 여러 종류의 PasswordEncoder를 제공하는데 그중 BCryptPasswordEncoder 클래스를 가장 많이 사용한다.
BCryptPasswordEncoder
다시 원래대로 복구가 불가능하며, 매번 암호화된 값도 다르게 출력된다.
원본을 확인 불가능하므로 최근 가장 많이 사용된다. Bean을 이용하여 지정해줄수 있다.
📑SecurityConfig.java
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
🍫 암호화된 패스워드 확인하기
📑PsswordTests.java
package com.example.springsecurity;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.password.PasswordEncoder;
@SpringBootTest
public class PasswordTests {
@Autowired
private PasswordEncoder passwordEncoder;
@Test
public void testEncoder(){
String password = "1111";
String enPw = passwordEncoder.encode(password);
System.out.println("enPw : " + enPw);
// 일치 불일치 확인
boolean matchResult = passwordEncoder.matches(password,enPw);
System.out.println("matchResult : " + matchResult);
}
}
🍫 임의의 사용자 계정 생성하여 암호화된 패스워드로 로그인
📑SecurityConfig.java
//사용자 계정 생성
@Bean
public InMemoryUserDetailsManager userDetailsManager(){
UserDetails user = User.builder()
.username("user1")
.password(passwordEncoder().encode("1111"))
.roles("USER")
.build();
log.info("user details service ===============");
log.info(user);
return new InMemoryUserDetailsManager(user);
}
02 ) 특정 URL 접근 제한 방법 - 2가지
1번. " SecurityConfig " 설정을 통한 패턴
2번. 어노테이션 사용
SecurityFilterChain
.permitAll() : 모든 사용자 가능
.hasRole("권한명") : 해당 권한을 가지고 있는 사용자만 접속 가능
* USER = ROLE_USER : 상수 처럼 인증된 사용자를 의미.( 로그인에 성공하면 권한을 가지게 된다. )
1번. " SecurityConfig " 설정을 통한 패턴
- antMatchers : 어떤 리퀘스트에 대해서 필터체인이 동작할 것인지 설정
ex ) 모든 요청 : http.antMatchers("/**")
특정 경로 : http.antMatchers("/api/**")
📑SecurityConfig.java
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
http.authorizeHttpRequests()
.antMatchers("/sample/all").permitAll()
.antMatchers("/sample/member").hasRole("USER");
http.formLogin(); //로그인폼 사용
http.logout(); //로그아웃폼 사용
return http.build();
}
2번. 어노테이션 사용
- '📑SecurityConfig' 파일에 @EnableGlobalMethodSecurity 적용.
- prePostEnabled = true : @PreAuthorize (컨트롤러에서 속성 지정 * 아래 설명 참조) 를 사용하기 위해 속성 필요하다.
- securedEnabled = true : @Secure (좀더 유연한 설정이 가능) 를 사용하기 위해 속성 필요하다.
- 기존 접근 제안 걸어 주었던 내용은 주석처리 해주었다.
📑SecurityConfig.java
package com.example.springsecurity.config;
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
@Configuration
@Log4j2
public class SecurityConfig {
...
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
// http.authorizeHttpRequests((auth)->{
// auth.antMatchers("/sample/all").permitAll();
// auth.antMatchers("/sample/member").hasRole("USER");
// });
...
return http.build();
}
}
- '📑SampleController ' 파일에서 각 매핑부분에 접근 권한을 설정해줄 수 있다.
- @PreAuthorize("permitAll()") : 전체 접근가능
- @PreAuthorize("hasRole('권한명')") : 해당 권한을 가지고 있는 사용자만 접근가능
📑SampleController.java
package com.example.springsecurity.controller;
...
@Controller
@Log4j2
@RequestMapping("/sample/")
public class SampleController {
@PreAuthorize("permitAll()")
@GetMapping("/all")
public void exAll(){
log.info("all page");
}
@PreAuthorize("hasRole('USER')")
@GetMapping("/member")
public void exMember(){
log.info("member page");
}
@PreAuthorize("hasRole('ADMIN')")
@GetMapping("/admin")
public void exAdmin(){
log.info("admin page");
}
}
@PreAuthorize
value 표현식은 '#'과 같은 특별한 기호나 authentication 같은 내장 변수를 이용할 수 있다.
ex) 로그인한 사용자 중에서 특정 사용자만 접근이 가능하도록 설정
@PreAuthorize("#clubAuthMember != null && #clubAuthMember.username eq \"user95@gmail.com"")
@GetMapping("/admin")
public void exAdmin(){
log.info("admin page");
}
03 ) CSRF 설정 - 외부 공격방어
CSRF 토큰
사이트간 요청위조를 방지하는 것으로
GET 방식의 요청을 제외한 모든 요청에 임의의 'CSRF 토큰' 을 포함시켜야만 정삭 동작이 가능하다.
하지만 매번 CSRF 토큰 발행을 하지 않아도 되는 경우가 있다.
이때 토큰을 발행하지 않도록 하는 방법은 " http.csrf().disable(); "를 설정에 추가해주면된다.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
http.authorizeHttpRequests()
...
http.csrf().disable();
return http.build();
}
'BackEnd > Security · JPA' 카테고리의 다른 글
[ Security ] 02. 로그인 - 시큐리티 권한에 따른 페이지 접속 (0) | 2023.05.23 |
---|---|
[ Security ] 01. 시큐리티 사용하기 - WebSecurityConfigurerAdapter 권한 설정 (스프링 부트 버전 2.7.0이전) (0) | 2023.05.23 |
[ JPA ] 동적 쿼리 처리를 해주는 Querydsl 사용해보기 (1) | 2023.04.16 |
[ Security ] 시큐리티 - 로그인 (0) | 2023.04.04 |
[ JPA ] Embedded - 재활용 가능한 Entity (0) | 2023.04.02 |