Spring Security는 Java 애플리케이션, 특히 Spring Framework를 기반으로 구축된 애플리케이션을 위해 만들어진 사용자가 정의 가능한 인증 및 액세스 제어 프레임워크입니다.
말 그대로 Spring 설정에서 보안을 담당합니다.
사용자 인증 및 권한 부여: Spring Security는 사용자 인증 및 권한 부여 기능을 제공합니다. 이를 통해 애플리케이션에 액세스할 수 있는 사용자를 제어하고, 각 사용자에게 허용된 작업을 제어할 수 있습니다.
데이터 암호화: Spring Security는 데이터 암호화 기능을 제공합니다. 이를 통해 애플리케이션의 데이터를 외부 공격으로부터 보호할 수 있습니다.
접근 제어: Spring Security는 접근 제어 기능을 제공합니다. 이를 통해 애플리케이션의 특정 리소스에 대한 액세스를 제어할 수 있습니다.
<properties>
<org.springframework-version>5.3.29</org.springframework-version>
<org.aspectj-version>1.9.19</org.aspectj-version>
<org.slf4j-version>2.0.7</org.slf4j-version>
<spring.security-version>5.8.1</spring.security-version>
</properties>
<!-- security -->
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-web -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${spring.security-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-config -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-taglibs -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${spring.security-version}</version>
</dependency>
- properties에 security-version 설정되어 있는지 확인해주세요!
- security-taglibs는 JSP에서 Security 기능을 태그 형태로 간단하게 제공하기 때문에 추가해주었습니다.
<!-- 모든 서블릿 필터에 적용되는 Root Spring Container -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml
/WEB-INF/spring/appServlet/security-context.xml
</param-value>
</context-param>
<!-- 파일 업로드처리 -->
<filter>
<filter-name>multipartFilter</filter-name>
<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>multipartFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 인코딩 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Security 기능 제공 -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
📌 주의 사항!!
- multipartFilter는 파일 업로드 요청을 처리하기 때문에 springSecurityFilterChain 보다 먼저 실행되어야 해서 위에 작성해줍니다.
- 그 다음 인코딩을 진행해야 하고,
- springSecurityFilterChain을 작성해줍니다.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/user/join" access="permitAll" />
<intercept-url pattern="/**" access="permitAll" />
<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
<form-login
login-processing-url="/user/login"
username-parameter="id"
password-parameter="pw"
default-target-url="/post"
authentication-success-handler-ref="customLoginSuccessHandler"
authentication-failure-handler-ref="customLoginFailureHandler"
/>
<access-denied-handler ref="customAccessDeniedHandler"/>
<logout logout-url="/logout" logout-success-url="/post" invalidate-session="true" delete-cookies="JSESSIONID"/>
<remember-me data-source-ref="dataSource" token-validity-seconds="604800"/>
</http>
<authentication-manager>
<authentication-provider user-service-ref="customUserDetailsService">
<password-encoder ref="bcryptPasswordEncoder"/>
</authentication-provider>
</authentication-manager>
</beans:beans>
권한에따라 특정 URL에 대한 접근 제한을하는 역할입니다!!
접근 제한을 설정할 URL 패턴을 지정합니다.
접근 권한을 지정합니다.
- hasRole : access 속성에 지정된 권한을 가진 사용자만 접근할 수 있도록 합니다.
- hasAnyRole : access 속성에 지정된 권한 중 하나를 가진 사용자만 접근할 수 있도록 합니다.
- permitAll : 모든 사용자의 접근을 허용합니다.
- denyAll : 모든 사용자의 접근을 거부합니다.
Spring Security의 로그인 인증을 하는 역할입니다!!
login-processing-url
로그인 요청을 처리할 URL을 지정합니다.
기본값은 /login 입니다.
username-parameter
로그인 폼에서 사용자 ID를 입력받을 input 태그의 name 속성 값을 지정합니다.
기본값은 username 입니다.
password-parameter
로그인 폼에서 비밀번호를 받을 input 태그의 name 속성 값을 지정합니다.
기본값은 password입니다.
default-target-url
로그인이 성공하면 이동할 URL을 지정합니다.
authentication-success-handler-ref
로그인이 성공하면 호출될 핸들러를 지정합니다.
기본값은 org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler
authentication-failure-handler-ref
로그인이 실패하면 호출될 핸들러를 지정합니다.
기본값은 org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler
로그아웃은 따로 컨트롤러를 만들지 않아도 시큐리티 설정에서 간단하게 구현가능합니다.
이건 매우 장점....
<logout logout-url="/logout" logout-success-url="/post" invalidate-session="true" delete-cookies="JSESSIONID"/>
영구 토큰 접근 방식을 사용
security-context.xml 파일을 만들어서 한번에 관리하고 있는 설정이라 요소만 추가하면 사용할 수 있기 때문에 이 방식을 사용
<remember-me data-source-ref="dataSource" token-validity-seconds="604800"/>
이 방식을 사용한다면 사용중인 데이터베이스에 persistent_logins 이름의 테이블이 생성되어 있어야합니다.
MySQL ver.
create table persistent_logins(
username varchar(64) not null,
series varchar(64) primary key,
token varchar(64) not null,
last_used timestamp not null
);
설정은 대부분 끝났고, 기존 @Controller, form 태그로 로그인하는 방식을
@RestController, ajax로 변경해보려고한다..
REST API 조건을 최대한 고려해보자! 하는 목적이고, 요청에대한 응답을 적절한 응답코드로 응답을 받을 수 있도록 Ajax를 사용해보자!!
참고
https://docs.spring.io/spring-security/site/docs/3.1.x/reference/remember-me.html