스프링 시큐리티(Spring Security) 환경설정, 초기세팅(백엔드/개발/Java/인증 및 인가)
by 시간기억자2024. 11. 10.
반응형
스프링 Security
Spring Security : 인증과 인가 기능을 제공하는 보안 프레임워크
인증(Authentication) : 프로그램을 사용할 수 있는 사용자가 맞는지를 확인하는 절차 → 인증을 정상적으로 수행하기 위해서는 사용자를 구분할 수 있는 정보 필요 - Credential
인가(Authorization) : 인증된 사용자가 요청한 자원에 접근 가능한가를 결정하는 절차(권한이라고 생각하면 됨) → 인증 처리 후 권한을 부여 받을 수 있으며 권한은 일반적으로 역할(Role) 형태로 부여 → 전처럼 인가를 위해 Interceptor를 만들 필요 없이 환경설정만 해주면 된다. 아니면 어노테이션을 이용해도 된다.
Spring Security는 인증과 인가를 위해 Principal 객체를 아이디로 사용하고 Credential 객체를 비밀번호로 사용하는 Credential 기반의 인증 방식을 사용 → Principal 객체에는 사용자의 모든 정보가 들어가 있다.
환경설정
프로젝트 생성(Spring Legacy Project)
프로젝트 properties에서 project facets 수정
pom.xml은 spring 프로젝트꺼 복붙하기
log4jdbc.log4j2.properties 파일도 spring 프로젝트꺼 복사해서 src/main/resources/ 경로에 붙여넣기
Spring Security를 SpringMVC 프로그램에 적용하는 방법
spring-security-web, spring-security-core, spring-security-config, spring-security-taglibs 라이브러리를 프로젝트에 빌드 처리 - 메이븐 : pom.xml → 4개의 라이브러리 모두 5.X.X 대 버전 사용(6.X.X대 버전은 JDK17 버전에서 사용)
1. spring-security-web
역할: 웹 애플리케이션의 보안을 위한 기능을 제공합니다.
기능:
2. spring-security-core
역할: Spring Security의 핵심 기능을 제공합니다.
기능:
3. spring-security-config
역할: Spring Security의 설정을 간편하게 관리할 수 있도록 도와줍니다.
기능:
4. spring-security-taglibs
역할: JSP와 같은 뷰에서 보안 관련 태그를 사용할 수 있게 해줍니다.
기능:
이렇게 각 라이브러리는 Spring Security의 다양한 기능을 제공하여 웹 애플리케이션의 보안을 강화하는 데 기여합니다.
[web.xml] 파일에 Spring Security 기능을 제공하는 필터 클래스를 필터로 등록하고 필터가 실행되기 위한 URL 패턴을 매핑 처리
<!-- DelegatingFilterProxy 클래스를 필터로 등록되도록 설정 --> <!-- => 반드시 필터의 이름을 [springSecurityFilterChain]으로 등록되도록 작성해야 한다. --> <!-- DelegatingFilterProxy : 메인 Filter Chain에 위치되도록 설정하는 클래스 --> <!-- => Spring Security 필터를 사용하는 시작점으로 설정되며 서블릿 컨테이너(WAS)의 필터와 ApplicationContext(Spring Container)에서 Spring Bean으로 등록된 필터를 연결하는 다리 역할 수행 --> <!-- => 사용자가 웹프로그램을 요청하면 DelegatingFilterProxy 필터가 요청을 받아 FilterChainProxy 필터에게 요청을 위임하여 필요한 필터들이 순서대로 실행되도록 동작 →
DelegatingFilterProxy 얘 하나만 필터로 등록하면 다른 필터와 연결이 된다. (DelegatingFilterProxy 얘 하나만 필터로 등록하면 다른 여러가지 필터를 사용해서 인증과 인가를 해주는 것이라고 생각하면 된다.)
[web.xml] 파일에 Spring Security 기능의 필터를 사용하기 위한 정보를 제공하는 Spring Bean Configuration File 설정 - ContextLoaderListener 클래스가 읽을 수 있도록 파일 경로 지정 → context-param 엘리먼트로 작성 → security-context.xml : spring security 관련 spring bean을 등록하는데 사용하거나, 필터에 필요한 정보를 제공할 수 있다. → security-context.xml <beans>엘리먼트 속성 값 순서 변경
기본적으로 beans namespace를 기본 namespace로 사용하는데, Spring Security에서는 security를 namespace로 설정해야 사용하기 편해서 그렇게 변경 설정을 해줘야 한다. (꼭 이렇게 쓸필요는 없지만 권장사항이다)
기본 네임스페이스를 [security]로 설정하여 사용하는 것을 권장
[security] 네임스페이스의 spring-security.xsd 파일에서 제공하는 다수의 엘리먼트 사용하기 때문에.
Spring Security 기능을 구현하기 위한 Spring Bean Configuration File 작성
http : Spring Security 기능을 SpringMVC 프로그램에 적용하기 위한 정보를 제공하는 엘리먼트 (이거는 무조건 있어야 한다. 이거 없으면 Spring Security가 제공하는 필터를 사용할 수 없다) → Spring Security 관련 환경 설정이 시작되는 위치를 제공
auto-config : false 또는 true(기본값) 중 하나를 속성값으로 설정 → auto-config 속성값을 [true]로 설정한 경우 기본값으로 환경 설정
use-expressions : false 또는 true(기본값) 중 하나를 속성값으로 설정 → use-expressions 속성을 [true]로 설정하면 SpEL 표현식을 사용하여 페이지 접근 여부 설정 가능 → use-expressions 속성을 [false]로 설정하면 SpEL 표현식을 사용불가능
SpEL 표현식(Spring Expression Language) : 권한을 표현하는 표현식 → hasRole('role') : 권한을 가지고 있는 경우를 나타내는 표현식 → hasAnyRole('role1','role2',...) : 나열된 권한 중 하나를 가지고 있는 경우를 나타내는 표현식 → permitAll : 모든 사용자의 접근 가능을 나타내는 표현식 → denyAll : 모든 사용자의 접근 불가능을 나타내는 표현식 → isAnonymous() : Anonymous 사용자(인증 받지 않은 사용자)인 경우에만 접근 가능을 나타내는 표현식 → isRememnberMe() : Remember-me 기능으로 인증받은 사용자인 경우에만 접근 가능을 나타내는 표현식 → → isAuthentucated() : 인증 처리된 사용자(Remember-me 기능으로 인증받은 사용자 포함)인 경우에만 접근 가능을 나타내는 표현식 → isFullyAuthenticated() : 인증 처리된 사용자(Remember-me 기능으로 인증받은 사용자 제외)인 경우에만 접근 가능을 나타내는 표현식
이런 SpEㅣ 표현식은 interceptor-url에서 써야 한다.
use-expressions 속성을 [false]로 설정한 경우 access 속성값으로 SpEL 사용 불가능
intercept-url 엘리먼트를 사용해 페이지에 접근 가능한 권한을 하나만 설정 가능
intercept-url : 요청 페이지에 접근 가능을 권한을 설정하는 엘리먼트 → 특정 페이지에 대한 권한 설정을 먼저하고 나머지는 마지막에 설정하는 것을 권장
pattern 속성 : 요청 페이지의 경로를 속성값으로 설정 → * 또는 ** 등의 패턴문자를 사용하여 속성값 설정 가능 → * : 폴더에 있는 페이지까지 → ** : 하위폴더까지에 있는 페이지까지
access 속성 : 페이지에 접근 가능한 권한(Role)을 속성값으로 설정 → use-expressions 속성을 [true]로 설정한 경우 SpEL를 사용해 권한 설정 가능 → 권한이 없는 사용자가 페이지를 요청할 경우 AccessDeniedException 발생
form-login : form 태그를 사용한 로그인 페이지를 설정하기 위한 엘리먼트
login-page 속성 : 아이디와 비밀번호를 입력받기 위한 페이지의 경로를 속성값으로 설정 → 속성을 설정하지 않은 경우 Spring Security에서 제공하는 로그인 페이지 사용
login-processing-url 속성 : 아이디와 비밀번호를 전달받아 인증 처리하는 페이지의 경로를 속성값으로 설정
authentication-manager : 인증 관리자를 등록하기 위한 엘리먼트 → 다양한 형태의 인증 방식 제공
authentication-provider : 인증 제공자를 등록하기 위한 엘리먼트 → 실질적인 인증 작업을 진행하는 기능 제공
user-service : 인증 정보를 등록하기 위한 엘리먼트 → 인증 처리를 이용해 사용자의 권한 관련 정보를 반환하는 기능
user : 인증을 위한 정보 및 사용자의 권한 정보를 설정하는 엘리먼트
name 속성 : 사용자를 구분하기 위한 식별자(아이디)를 속성값으로 설정
password 속성 : 사용자의 비밀번호를 속성값으로 설정 → Spring Security 5.0 이상에서는 비밀번호를 반드시 암호화 처리하여 비교되도록 구현 → password 속성값으로 설정된 비밀번호 앞부분에 {noop}를 붙여 작성하면 암호화 처리 하지 않아도 비교
authorities 속성 : 권한(Role)을 속성값으로 설정 → 권한은 ROLE 기반으로 설정 - 속성값을 ROLE_XXX 형식으로 설정 → 사용자에게 다수의 권한을 제공할 경우 , 기호로 구분하여 권한을 나열해 설정 가능
인증이 성공한 경우 Authentication Manager는 Spring Security 관련 세션(Security ContextHolder)에 인증 및 인가 관련 정보(Authentication 객체) 저장
jdbc-user-service : Spring Security가 JDBC를 이용해 인증 처리하기 위한 엘리먼트 → JdbcUserDetailsManager 클래스를 사용해 인증과 인가 처리 → USERS 테이블을 생성해 사용자 정보를 저장하고 AUTHORITIES 테이블을 생성하여 사용자의 권한 정보를 저장할 경우 SQL 명령을 작성하지 않아도 기본적으로 제공되는 SQL 명령으로 인증 처리 후 사용자 정보(UserDetails 객체)를 반환 UserDetails 객체에는 아이디, 비밀번호, enabled 정도의 인증정보와 인가정보만 가지고 있다. 그런데 이것뿐만 아니라 사용자 전체 정보를 저장하고 싶으면 별도의 클래스(CustomUserDetails)를 만들어줘야 한다. → 인증하려면 SQL 명령이 필요한데 그걸 우리가 만들어주는게 아니라 알아서 만들어서 인증 진행을 해주는거다. → 사용자 정보(UserDetails 객체)는 세션에 저장되고 우리는 그걸 가져다가 요청 처리 메소드나 뷰에서 사용할 수 있다.
data-source-ref : Connection 객체를 제공하기 위한 DataSource 관련 클래스의 Spring Bean 식별자(beanName)을 속성값으로 설정
password-encoder : 암호화 처리된 비밀번호를 비교하기 위한 기능을 제공하는 엘리먼트
ref 속성 : PasswordEncoder 인터페이스를 상속받은 클래스의 Spring Bean 식별자(beanName)을 속성값으로 설정
Spring Security를 SpringMVC 프로그램에 적용하여 제공 받을 수 있는 기능 (필터를 사용해서 이 기능들을 제공한다고 생각하면 됨)
다양한 형태(폼로그인 인증, 토큰 기반 인증, OAuth2 기반 인증, LDAP 인증)의 사용자 인증 방법 제공 → OAuth2 기반 인증 : 다른 사이트에 인증을 요청하고 받는 것(예 : 카카오, 네이버 등) → LDAP 인증 : 인증을 할 수 있는 서버를 따로 만드는 것
UsernamePasswordAuthenticationFilter : 아이디와 비밀번호를 사용하는 Form 기반 유저 인증을 처리하는 필터 → Authentication 객체를 만들고 AuthenticationManager에게 인증 처리 위임 → AuthenticationManager는 실질적인 인증에 대한 검증 단계를 총괄하는 AuthenticationProvider에게 인증 처리를 위임 - UserDetailService와 같은 서비스를 사용해서 인증 처리
ConcurrentSessionFilter : 동시 세션과 관련된 필터 - 이중 로그인 방지
RememberMeAuthenticationFilter : 세션이 사라지거나 만료 되더라도 쿠키 또는 DB를 사용하여 저장된 토큰을 기반으로 인증 처리하는 필터
AnonymousAuthenticationFilter : 사용자 정보가 인증되지 않았다면 익명 사용자 토큰을 반환하는 필터
SessionManagementFilter : 로그인 후 Session과 관련된 작업을 처리하는 필터 → 여기에 권한관련 정보를 저장한다.
ExceptionTranslationFilter : 필터 체인 내에서 발생되는 인증 및 인가 관련 예외를 처리하는 필터
FilterSecurityInterceptor : 권한 부여와 관련한 결정을 AccessDecisionManager에게 위임해 권한 부여 결정 및 접근 제어를 처리하는 필터
CsrfFilter : CSRF Tocken을 사용하여 CSRF 공격을 막아주는 기능을 제공하는 필터
CommonsMultipartResolver 를 Spring 프로젝트에서는 servlet-context.xml에 등록했는데, Spring Security 프로젝트에서는 root-context.xml 에 등록을 해줘야한다. Spring Security를 쓰면 multipart/form-data를 전달할때는 Spring Security의 영향을 받기 때문에 root-context.xml에 써야 하는 것이다. servlet-context.xml에 등록하면 Spring Bean 인식을 못한다.
댓글