์ด๋ ๋ก๊ทธ์ธ์ด ๋๊ธฐ ์ํด์๋ password๊ฐ ํด์ฌ๋ก ์ํธํ๋ ์ฑ๋ก ๋ค์ด์์ผ ํ๋ค.
// < SecurityConfig >
@Bean // IoC๊ฐ ๋๋ค.
public BCryptPasswordEncoder encodePWD() {
return new BCryptPasswordEncoder(); // ์ด ๊ฐ์ฒด๋ฅผ ์คํ๋ง์ด ๊ด๋ฆฌํ๊ฒ ๋จ. ํ์ํ ๋๋ง๋ค ๊ฐ์ ธ๊ฐ์ ์ฐ๋ฉด ๋๋ค.
}
.
.
.
// < test>
public class EncTest {
@Test
public void ํด์ฌ_์ํธํํ() {
String encPassword = new BCryptPasswordEncoder().encode("1234");
System.out.println("1234 ํด์ฌ : " + encPassword);
}
}
< UserService >
@Service // ์คํ๋ง์ด ์ปดํฌ๋ํธ ์ค์บ์ ํตํด์ Bean์ ๋ฑ๋ก์ ํด์ค. (IoC)
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private BCryptPasswordEncoder encoder;
@Transactional // ์ ์ฒด๊ฐ ์ฑ๊ณตํด์ผ commit, ์คํจํ๋ฉด rollback
public void ํ์๊ฐ์
(User user) {
String rawPassword = user.getPassword(); // ์๋ณธ (์ : 1234)
String encPassword = encoder.encode(rawPassword); // ํด์ฌ
user.setPassword(encPassword);
user.setRole(RoleType.USER);
userRepository.save(user);
}
}
// ์ํ๋ฆฌํฐ๊ฐ ๋ก๊ทธ์ธํ ๋ ์ด๋ค ์ํธํ๋ก ์ธ์ฝ๋ฉํด์ ๋น๋ฒ์ ๋น๊ตํ ์ง ์๋ ค์ค์ผ ํจ.
// ์ํ๋ฆฌํฐ๊ฐ ๋์ ๋ก๊ทธ์ธ ํจ -> password ๊ฐ๋ก์ฑ
// ๊ฐ๋ก์ฑ password๊ฐ ํ์๊ฐ์
๋ ๋ ๋ฌด์์ผ๋ก ํด์ฌ๊ฐ ๋์๋์ง ์์์ผํจ -> ๊ทธ๋์ผ ๊ฐ์ ํด์ฌ๋ก ์ํธํ ํ๊ณ DB์ ์๋ ํด์ฌ์ ๋น๊ตํ์ฌ ๋ก๊ทธ์ธ
// ์ฆ, ํจ์ค์๋ ๋น๊ตํ๋ ๋ฉ์๋
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(principalDetailService).passwordEncoder(encodePWD()); // passwordEncoder ํ๋ ์ ๊ฐ encodePWD ์.
}
@Configuration // ๋น ๋ฑ๋ก (IoC๊ด๋ฆฌ)
@EnableWebSecurity // Security ํํฐ๊ฐ ๋ฑ๋ก๋จ = ์คํ๋ง ์ํ๋ฆฌํฐ๊ฐ ์ด๋ฏธ ํ์ฑํ๋ ๋์ด์์ง๋ง, ์ค์ ์ ํด๋น ํ์ผ์์ ํ ๊ฒ์
@EnableGlobalMethodSecurity(prePostEnabled = true) // ํน์ ์ฃผ์๋ก ์ ๊ทผ์ ํ๋ฉด ๊ถํ ๋ฐ ์ธ์ฆ์ ๋ฏธ๋ฆฌ ์ฒดํฌ (์ํํ ํ์ ์ฒดํฌํ๋ ๊ฒ์ด ์๋)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private PrincipalDetailService principalDetailService;
// 1. Bean ์ด๋
ธํ
์ด์
์ ๋ฉ์๋์ ๋ถ์ฌ์ ๊ฐ์ฒด ์์ฑ์ ์ฌ์ฉ
@Bean // IoC๊ฐ ๋๋ค.
public BCryptPasswordEncoder encodePWD() {
return new BCryptPasswordEncoder(); // ์ด ๊ฐ์ฒด๋ฅผ ์คํ๋ง์ด ๊ด๋ฆฌํ๊ฒ ๋จ. ํ์ํ ๋๋ง๋ค ๊ฐ์ ธ๊ฐ์ ์ฐ๋ฉด ๋๋ค.
}
// 2. ์ํ๋ฆฌํฐ๊ฐ ๋ก๊ทธ์ธํ ๋ ์ด๋ค ์ํธํ๋ก ์ธ์ฝ๋ฉํด์ ๋น๋ฒ์ ๋น๊ตํ ์ง ์๋ ค์ค์ผ ํจ.
// ์ํ๋ฆฌํฐ๊ฐ ๋์ ๋ก๊ทธ์ธ ํจ -> password ๊ฐ๋ก์ฑ
// ๊ฐ๋ก์ฑ password๊ฐ ํ์๊ฐ์
๋ ๋ ๋ฌด์์ผ๋ก ํด์ฌ๊ฐ ๋์๋์ง ์์์ผํจ -> ๊ทธ๋์ผ ๊ฐ์ ํด์ฌ๋ก ์ํธํ ํ๊ณ DB์ ์๋ ํด์ฌ์ ๋น๊ตํ์ฌ ๋ก๊ทธ์ธ
// ์ฆ, ํจ์ค์๋ ๋น๊ตํ๋ ๋ฉ์๋
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(principalDetailService).passwordEncoder(encodePWD()); // passwordEncoder ํ๋ ์ ๊ฐ encodePWD ์.
}
// 3. ํํฐ๋ง
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable() // csrf ํ ํฐ ๋นํ์ฑํ (ํ
์คํธ์ ๊ฑธ์ด๋๋๊ฒ ์ข์)
.authorizeRequests() // request๊ฐ ๋ค์ด์ค๋ฉด
.antMatchers("/", "/auth/**", "/js/**", "/css/**", "/image/**") // ์ฌ๊ธฐ๋ก ๋ค์ด์ค๋ฉด
.permitAll() // ๋ชจ๋ ๊ฐ๋ฅ (๋๊ตฌ๋ ๊ฐ๋ฅ)
.anyRequest() // ๊ทธ๊ฒ ์๋ ๋ค๋ฅธ ๋ชจ๋ ์์ฒญ์
.authenticated() // ์ธ์ฆ์ด ๋์ด์ผ ํ๋ค
.and()
.formLogin()
.loginPage("/auth/loginForm") // ์ธ์ฆ์ด ํ์ํ ์์ฒญ์ ์ด ๋ก๊ทธ์ธ ํผ์ผ๋ก ์จ๋ค
.loginProcessingUrl("/auth/loginProc") // ์คํ๋ง ์ํ๋ฆฌํฐ๊ฐ ํด๋น ์ฃผ์๋ก ์์ฒญ์ด ์ค๋ ๋ก๊ทธ์ธ์ ๊ฐ๋ก์ฑ์ ๋์ ๋ก๊ทธ์ธ์ ํ๋ค.
.defaultSuccessUrl("/");
}
// ์ฐธ๊ณ : .headers().frameOptions().disable() // ์์ดํ๋ ์ ์ ๊ทผ ๋ง๊ธฐ
// ์ฐธ๊ณ : .csrf().disable() // csrf ํ ํฐ ๋นํ์ฑํ (ํ
์คํธ์ ๊ฑธ์ด์ฃผ๋ ๊ฒ์ด ์ข์)
}
// ๋ก๊ทธ์ธ์, ๋๋ ์์
ํ๋ฉด ์์ฒญ์ CSRF ํ ํฐ์ ์์ฑํ์ฌ ์ธ์
์ ์ ์ฅ
session.setAttribute("CSRF_TOKEN",UUID.randomUUID().toString());
// ์์ฒญ ํ์ด์ง์ CSRF ํ ํฐ์ ์
ํ
ํ์ฌ ์ ์ก
<input type="hidden" name="_csrf" value="${CSRF_TOKEN}" />
์คํ๋ง ์ํ๋ฆฌํฐ๋ฅผ ์ฌ์ฉํ๋ฉด, CSRF์ฒ๋ผ ๊ฐ๋ฐ์๊ฐ ์๋ํ์ง ์์ ์์ฒญ๋ค์ด API๋ก ๋ค์ด์ค๋ฉด ์์ฒ์ฐจ๋จํ ์ ์๋ค.
์ฆ, ์์ฒญ์์ CSRF ํ ํฐ์ ์ ๊ฐ์ง๊ณ ์์ฒญ์ ํ๋ฉด (=CSRF ํ ํฐ์ด ์์ผ๋ฉด) ์คํ๋ง ์ํ๋ฆฌํฐ๊ฐ ๋ง์์ค๋ค.
๊ทธ๋์ ํ
์คํธ์์๋ SecurityConfig.java ์ .csrf().disable() // csrf ํ ํฐ ๋นํ์ฑํ (ํ
์คํธ์ ๊ฑธ์ด๋๋๊ฒ ์ข์)
์ด๋ ๊ฒ ๋นํ์ฑํ ํด๋๊ณ ํ
์คํธ ํ๋ฉด ๋๋ค.