📚 공부한 책 : 코드로배우는 스프링 부트 웹프로젝트
❤️ github 주소 : https://github.com/qkralswl689/LearnFromCode/tree/main/club
SecurityConfig 클래스는 시큐리티 관련 기능을 쉽게 설정하기 위해 WebSecurityConfigurerAdapter 라는 클래스를 상속처리한다
-> WebSecurityConfigurerAdapter 클래스는 주로 override를 통해 여러 설정을 조정하게 된다
★ 앞으로 모든 시큐리티 관련 설정이 추가되는 부분이다
package com.example.club.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}
시큐리티 관련 설정이 정상적으로 동작하는지 확인하기 위한 컨트롤러를 구성한다
- 컨트롤러에 사용자의 권한에 따라 접근할 수 있는 경로를 지정한다
package com.example.club.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/sample")
public class SampleController {
// 로그인을 하지 않은 사용자도 접근 가능
@GetMapping("/all")
public void exAll(){
System.out.println("exALl");
}
// 로그인한 사용자만 접근 가능
@GetMapping("/member")
public void exMember(){
System.out.println("exMember");
}
// 관리자 권한이 있는 사용자만 접근가능
@GetMapping("/admin")
public void exAdmin(){
System.out.println("exAdmin");
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>For All </h1>
</body>
</html>
<!DOCTYPE html>
<html xmlns:sec="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>For Member ....................</h1>
<div sec:authorize="hasRole('USER')">Has USER ROLE</div>
<div sec:authorize="hasRole('MANAGER')">Has MANAGER ROLE</div>
<div sec:authorize="hasRole('ADMIN')">Has ADMIN ROLE</div>
<div sec:authorize="isAuthenticated()">
Only Authenticated user can see this Text
</div>
Authenticated username:
<div sec:authentication="name"></div>
Authenticated user roles:
<div sec:authentication="principal.authorities">
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>For Admin </h1>
</body>
</html>
스프링 시큐리티의 동작에는 여러 개의 객체가 서로 데이터를 주고받으며 이루어진다
-> 스프링 시큐리티의 간단한 흐름
- 핵심역할 : Authentication Manager(인증 매니저)를 통해 이루어진다, AuthenticationProvider는 인증매니저가 어떻게 동작해야 하는지 결정하고 최종적으로 실제 인증은 UserDetailsService에 의해 이루어진다
- 핵심개념 : 인증(Authentication) / 인가(Authorization)
- 필터(Filter)는 서블릿이나 JSP에서 사용하는 필터와 같은 개념이다 But 스프링 시큐리티에서는 스프링의 빈과 연동할 수 있는 구조로 설계되어있다.
-> 일반적인 필터는 스프링의 빈을 사용할 수 없기 때문에 별도의 클래스를 상속받는 형태가 많다- 스프링 시큐리티의 내부에는 여러개의 필터가 Filter Chain이라는 구조로 Request를 처리하게 된다
- 개발 시에 필터를 확장하고 설정하면 스프링 시큐리티를 이용해 다양한 형태의 로그인 처리가 가능하게 된다
- 스프링 시큐리티의 주요 필터
- 필터의 핵심적인 동작은 AuthenticationManager를 통해 인증(Authentication)이라는 타입의 객체로 작업하게 된다
- AuthenticationManager가 가진 인증 처리 메서드는 파라미터도 Authentication 타입으로 받고 리턴 타입 역시 Authentication이다
- 전달된 ID/PW 로 실제 사용자에 대해 검증하는 행위는 AuthenticationManager(인증 매니저)를 통해 이루어진다
- 실제 동작에서 전달되는 파라미터는 UsernamePasswordAuthenticationToken과 같이 토큰이라는 이름으로 전달된다
=> 스프링 시큐리티 필터의 주요 역할이 인증 관련된 정보를 토큰이라는 객체로 만들어 전달한다는 의미- 예제 코드
String username obtainUsername(request); username (username! = null) ? username : ""; username username.trim(); String password obtainPassword.(request); password (password。rd != null) password : ""; UsernamePasswordAuthenthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username , password) ; // Allow subclasses to set the "details" property setDetails(request, authRequest); return this.getAuthenticationManager().authenticate(authRequest);
-> request를 이용해 사용자의 ID/PW를 받아 UsernamePasswordAuthenthenticationToken 이라는 객체를 만들고 이를 AuthenticationManager의 authenticate()에 파라미터로 전달한다. AuthenticationManager는 다양한 방식으로 인증처리 방법을 제공해야 한다.
AuthenticationManager는 이런한 처리를 AuthenticationProvider로 처리한다.
AuthenticationProvider는 전달되는 토큰의 타입을 처리할 수 있는 존재인지 확인하고 이를 통해 authenticate()를 수행하게 된다
- AuthenticationProvider와 하위 구현 클래스
- AuthenticationProvider는 내부적으로 UserDetailsService를 이용한다.
UserDetailsService는 실제로 인증을 위한 데이터를 가져오는 역할을 한다
- 인가(Authorization)는 '승인'의 의미이다.
-> 필터에서 호출하는 AuthenticationManager에는 authenticate()라는 메서드가 있는데 이 메서드의 리턴값은 Authentication이라는 '인증' 정보이다. 이 인증 정보내에는 Roles라는 '권한'에 대한 정보가 있다. 이 정보로 사용자가 원하는 작업을 할수 있는 지 '허가' 하게 되는데 이러한 행위를 'Access-Control(접근 제한)' 이라고 한다.- AuthenticationProvider에서 만일 올바른 사용자라고 인증되면 사용자의 정보를 Authentication 타입으로 전달한다. 전달된 객체로 사용자가 적절한 권한이 있는지 확인하는 '인가(Autherization)' 과정을 거치게 된다