스프링 라이브러리 추가
//시큐리티 버전은 스프링버전에 따라 사용방법이 완전히 다릅니다.
//시큐리티 5버전 => 스프링 부트 2버전 (수업)
//시큐리티 6버전 => 스프링 부트 3버전 (문법이 완전 변경되니 주의)
implementation 'org.springframework.boot:spring-boot-starter-security'
//시큐리티 타임리프에서 사용
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
//시큐리티 테스트
testImplementation 'org.springframework.security:spring-security-test'
- 시큐리티가 처음 설정 되면 모든 요청에 대해서 시큐리가 기본 제공하는 로그인 화면이 보이게 됩니다.
- 기본아이디는 user / 비밀번호는 console창에 비밀번호를 발급합니다.
- 로그아웃의 경로는 /logout이 기본이 됩니다.
- 로그아웃 이후에는 다시 /hello 요청으로 진입이 불가능해 집니다.
🕹️Spring Security Load 시 Console에 비밀번호 발급
이후 모든 요청에 대해서 아래와 같이 기본 제공페이지가 보인다.
스프링 시큐리티 공식 문서
https://docs.spring.io/spring-security/reference/5.7/servlet/configuration/java.html
Spring Security의 패턴 : Builder
Method | 의미 |
anyRequest() | 모든 요청 |
authorizeRequests() | Request에 권한 부여 |
antMatchers() | 경로 설정 |
authenticated() | 인증 필요 |
hasRole() | 권한 필요 |
hasAnyRole() | 여러 권한 중 1개 필요 |
permitAll() | 모두 허용 |
denyAll() | 모두 거부 |
SecurityConfig.JAVA 파일
@Configuration : 해당 파일이 설정 파일임을 명시한다.
@EnableWebSecurity : 시큐리티 설정 파일을 시큐리티 필터에 등록한다.
package com.coding404.demo.security.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import static org.springframework.security.config.Customizer.withDefaults;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public BCryptPasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
//csrf토큰 사용x
http.csrf().disable();
// /logout으로 로그아웃을 시도하고 URL주소를 확인하세요
//모든 요청에 대해 사용자 인증이 필요합니다.
// http.authorizeRequests( (authorize) -> authorize.anyRequest().authenticated() );
//user페이지에 대해서만 사용자 인증이 필요합니다.
// http.authorizeRequests( (authorize) -> authorize.antMatchers("/user/**").authenticated() );
//user페이지에 대해서 user권한이 필요합니다.
// http.authorizeRequests( (authorize) -> authorize.antMatchers("/user/**").hasRole("USER") );
//user페이지에 대해서 user권한이 필요합니다. admin페이지에 대해서 admin권한이 필요합니다.
// http.authorizeRequests( (authorize) -> authorize.antMatchers("/user/**").hasRole("USER")
// .antMatchers("/admin/**").hasRole("ADMIN") );
//all페지이는 인증만되면 들어갑니다. user페이지에 대해서 user권한이 필요합니다. admin페이지에 대해서 admin권한이 필요합니다.
//나머지 모든 요청은 요청을 허용합니다.
// http.authorizeRequests( (authorize) -> authorize.antMatchers("/all").authenticated()
// .antMatchers("/user/**").hasRole("USER")
// .antMatchers("/admin/**").hasRole("ADMIN")
// .anyRequest().permitAll() );
//all페지이는 인증만되면 들어갑니다.
//user페이지에 대해서 user권한 or ADMIN 이필요합니다.
//admin페이지에 대해서 admin권한이 필요합니다.
//나머지 모든 요청은 요청을 허용합니다.
http.authorizeRequests( (authorize) -> authorize
.antMatchers("/all").authenticated()
.antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().permitAll() );
//시큐리티가 제공하는 폼기반 로그인 기능을 사용할 수 있습니다.
//이후 권한이 없으면 시큐리티는 낚아채서 기본 로그인을 보여줍니다.
// http.formLogin( Customizer.withDefaults() );
//사용자가 제공하는 폼기반 로그인 기능을 사용할 수 있습니다.
http.formLogin().loginPage("/login");
return http.build();
}
}
비밀번호 암호화 BCryptPasswordEncoder 객체
공식 문서
https://docs.spring.io/spring-security/reference/5.7/features/authentication/password-storage.html#authentication-password-storage-bcrypt
스프링 시큐리티에서 비밀번호 단방향 암호화는 필수요소이다.
시큐리티는 비밀번호 암호화 객체 BCryptPasswordEncoder를 제공한다.
쉽게 설명하자면, 우리가 웹 서비스를 이용할 때, 비밀번호를 잊어버려 다시 발급받은 적이 있을 것이다.
그 이유가 바로 스프링 시큐리티의 암호화 객체에 의해 발생한다.
BCryptPasswordEncoder의 암호화로 인하여, 비밀번호를 잊어버렸을 때 해당 비밀번호에 대한 복호화를 수행하지 않는다. 그렇기 때문에 비밀번호를 잊었을 때 다시금 비밀번호를 재설정하는 이유가 이런 것에 있다.
@Bean public BCryptPasswordEncoder encoder() { return new BCryptPasswordEncoder(); }
위 처럼 BcryptPasswordEncoder 객체를 불러와 Bean으로 등록한다.
@PostMapping("/joinForm") public String joinForm(UserVO vo) { System.out.println(vo.toString()); String pw = bCryptPasswordEncoder.encode(vo.getPassword()); vo.setPassword(pw); //비밀번호 암호화 userMapper.join(vo); //회원가입 return "redirect:/login"; }
이후 불러온 암호화 객체를 이용해 기존에 사용자가 회원가입시 입력한 비밀번호를 암호화를 진행하고
다시 vo의 비밀번호로 교체해준다.
이 방법을 통해 사용자는 로그인 처리시, 동일하게 암호화된 비밀번호를 찾아 로그인을 할 수 있지만,
잃어버렸을 경우 찾을 수는 없다.
간단하게 구현을 해보기 위해서 Service 영역은 생략하도록 한다.
일단 Controller에는 위와 같이 선언을 해주고, 화면에서 권한을 설정할 수 있도록 처리한다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>join</h3>
<form action="joinForm" method="post">
<input type="text" name="username" placeholder="아이디">
<input type="password" name="password" placeholder="비밀번호">
<select name="role">
<option value="ROLE_USER">user</option>
<option value="ROLE_ADMIN">admin</option>
<option value="ROLE_TESTER">tester</option>
</select>
<input type="submit" value="가입">
</form>
</body>
</html>
Mapper에서는 DB로 해당 값이 들어갈 수 있도록 처리를 한다.
<insert id="join">
insert into members values (#{username}, #{password}, #{role})
</insert>
결과
위 사진과 같이 나는 아이디와 비밀번호를 동일하게 입력을 하였음에도 Spring Security 암호화 객체에 의해
비밀번호가 암호화되어 저장된 것을 확인 할 수가 있다.
728x90
'Programming > Spring Boot' 카테고리의 다른 글
[Spring Boot] JWT HMAC 암호화 (0) | 2024.05.30 |
---|---|
[Spring Boot] JWT (1) | 2024.05.30 |
[Spring Boot] 어노테이션을 활용해 권한 설정하기 (0) | 2024.05.29 |
[Spring Boot] Spring Security 로그인 처리 (1) | 2024.05.29 |
[Spring Boot] Spring Security (0) | 2024.05.27 |