튜플입니다. 튜플을 보면 ROLE이라는 권한이 저장 되어 있습니다. 이 글에는 저장되어 있는 경우와
저장되어 있지 않은 경우(즉, 컬럼이 없는 경우)도 기록해 놓았습니다.
또 튜플을 보면 비밀번호가 암호화 되어 있습니다. 이 글에는 저장된 비밀번호가 평문일 경우도
해결하는 방법도 기록이 되어 있습니다.
먼저 Spring Security 에서 이해해야 할 인터페이스가 있습니다.
이전에 언급한 UserDetailsService입니다.
UserDetailsService - 아이디로 디비 조회 후 사용자 정보 리턴(체크, 아이디만 가지고 디비 조회) - 주요설정 - a. 서비스 로직을 통해 아이디 디비 조회 b. 사용자정보 리턴 - 리턴시 User객체를 builder, 또는 User객체를 커스트마이징 한 객체 타입으로 리턴
UserDetailService는 구현받은 클래스를 객체로 만드는 설정만 있다면 정상적으로 시큐리티가 알아서 동작시켜준다.
구현받은 클래스 작업외에는 설정하지 않을 것이다. @Service 어노테이션으로 객체로 생성되도록 처리한다.
@Service public class MyUserDetailsService implements UserDetailsService {
먼저 UserDetailService로 완성 된 소스를 살표 보겠습니다.
@Service
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private IF_MemberDao memberdao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// TODO Auto-generated method stub
try {
MemberVO member = memberdao.selectOne(username);
return User.builder().username(member.getId()).password(member.getPass()).roles(member.getRole()).build();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
디비를 조회할 객체가 필요합니다. < 이 부분은 미리 데이터베이스 작업이 필요합니다 >
@Autowired
private IF_MemberDao memberdao;
UserDetailsService 인터페이스가 실행되면 자동으로 loadUserByUsername(String username) 메서드가 실행되고
메서드는 UserDetails 타입을 리턴하게 됩니다.
소스를 보겠습니다.
MemberVOmember=memberdao.selectOne(username); 이 코드에서 username은 클라이언트가 보낸 username을 스프링 시큐리티가 저장한 변수입니다. 즉, 클라이언트가 보낸 username으로 데이터베이스를 조회합니다.
return User.builder().username(member.getId()).password(member.getPass()).roles(member.getRole()).build(); 이 코드는 리턴하는 코드입니다. loadUserByUsername 메서드는 UserDetails(인터페이스) 타입을 리턴하게 되어 있습니다. 코드는 User 객체 (import org.springframework.security.core.userdetails.User;)를 리턴합니다. User 디테일은 스프링시큐리티에서 제공하는 객체이고 Userdetails 인터페이스를 상속 받은 것입니다.
User 객체로 리턴한다는 것을 이해했으니 세부적으로 User 객체의 값을 셋팅하는 부분을 살펴 봅니다. usename(디비에서검색한 결과의 아이디), password(디비에서 검색한 결과의 암호), role(디비에서 저장된 회원의 Role)으로 user객체를 builder합니다.
이렇게 하면 자동으로 클라이언트가 입력한 비밀번호와 디비에서 조회한 비밀번호의 일치 여부를 판단하여 최종 인가가 완료 됩니다.
주의점 UserDetails에서 인식하는 비밀번호는 반드시 암호화가 되어 있어야 합니다. 그래서 데이터 베이스에 저장할 때 암호화 시켜야 하는 것이 좋습니다.
만약, 데이터베이스에 저장된 암호가 평문일 때는 User.builder().username(member.getId()).password(member.getPass()).roles(member.getRole()).build(); 이 코드에서 password(member.getPass()를 암호화 작업함)를 빌드 하기 전 암호화 작업을 합니다.
먼저, Spring security에서 사용하는 객체를 이해한다. 1. SecurityFilterChain - 주요설정 - a. csrf 설정 - csrf기능을 비활성화 또는 사용과 관련된 설정, (이번장에서는 비활성화) b. authorizeHttpRequests - url 요청에 따른 인가정책 c. formLogin - 클라이언트가 로그인 요청시 파라미터 값 받기등 부가작업 d. logout - 클라이언트가 로그아웃 요청시 처리 e. userDetailsService (생략가능) - 아이디로 디비 조회 후 사용자 정보 리턴(User 또는 User객체를 커스터마이징한 객체) 2. UserDetailsService - 아이디로 디비 조회 후 사용자 정보 리턴(체크, 아이디만 가지고 디비 조회) - 주요설정 - a. 서비스 로직을 통해 아이디 디비 조회 b. 사용자정보 리턴 - 리턴시 User객체를 builder, 또는 User객체를 커스트마이징 한 객체 타입으로 리턴
3. AuthenticationProvider - 사용자 정보가 리턴되면 자동으로 클라이언트가 입력한 암호와 디비 조회에서 가져온 암호를 비교 함. 이때 둘 다 암호화 되어있어야 함. 특징 : 커스트마이징 하지 않아도 자동 - 주요설정 - a. 클라이언트가 전송한 아이디와 비번을 저장하는 객체 b. 디비 조회로 가져온 객체의 정보 c. a와 b의 암호가 같은지 판단 (아이디는 이미 userDetailsService에서 조회 함) d. 권한부여... -여기서 부여하는 권한은 1번 SecurityFilterChain의 b. authorizeHttpRequests 의 정책에 적용된다.
그럼,
1. SecurityFilterChain 작업을 시작해 보자.
가. package만들기
나. SecurityFilterChain class만들기 (클래스명은 SecurityConfig로 한다.) * 어노테이션은 spring security 설정이라는 의미
다. csrf와 authorizeHttpRequests 의 설정을 먼저 한다. -------------------------------------------------------- - 주요설정 - a. csrf 설정 - 비활성화 b.authorizeHttpRequests - / 요청은 모두 허용, freeboard로 시작하는 요청은 USER권한만 가능, 그외 요청은 허가 받은 유저만 가능 --------------------------------------------------------
2. 위에서 설정한 작업이 정상인지 확인해 보자
서버를 재시작한다.
브라우저 창에 다음 순서로 입력한다.
url 주소
결과
설명
http://www.localhost:8080
home.html 문서가 보인다.
requestMatchers("/").permitAll()
http://www.localhost:8080/freeboard
액세스가 거부 됨. 그 밑에는 HTTP ERROR 403
requestMatchers("/freeboard*").hasRole("USER")
위 표와 같이 테스팅이 나오면 spring security의 인가 정책은 정상적으로 동작하는 것이다.
주소창에 localhost:8080 이라고 입력(포트번호는 다를 수 있음, 스프링 부트 콘솔을 참고)하면 자동으로 로그인 창으로 이동된다. 아래 화면에 보이는 로그인 창은 spring boot가 내장하고 있는 화면.
http://www.localhost:8080 이라고 브라우저 주소창에 입력한다.. 여기서 포트 번호를 다를 수 있으니
스프링 부트의 콘솔을 확인해 보자.
이렇게 되면 spring security 설치는 완료 된 것.
http://www.localhost:8080 또는 http://www.localhost:8080/freeboard로 입력하고 로그인 화면으로 전환된다.
즉, 어떤 url을 요청해도 spring security는 필터링하여 인증을 하도록 한다.
맛보기 - 인증과 인가를 이해해 보자.
서버를 재시작하고 콘솔을 보면 임시 비밀번호가 있다.
임시 비밀번호로 로그인을 할 것이다. username부분에는 user를 입력하고, password부분은 콘솔에 출력된 암호를 입력한다. Sing in을 입력하면 다음과 같이 인가가 된 것을 확인 할 수 있다. 인가 받은 user이기 때문에 다른 url요청도 모두 인가해 준다.
맛보기 -------------------------------------------- 끝