1. 개요

이 빠른 사용방법(예제)에서는 Spring Security로 Jakarta EE 웹 애플리케이션을 보호하는 방법을 살펴보겠습니다 .

2. 메이븐 의존성

이 예제에 필요한 Spring Security 의존성 부터 시작하겠습니다 .

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>5.7.5</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
    <version>5.7.5</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-taglibs</artifactId>
    <version>5.7.5</version>
</dependency>

최신 Spring Security 버전(이 예제 작성 시점)은 5.7.5입니다. 항상 그렇듯이 Maven Central 에서 최신 버전을 확인할 수 있습니다 .

3. Security 구성

다음으로 기존 Jakarta EE 애플리케이션에 대한 Security 구성을 설정해야 합니다.

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig {

    @Bean
    public InMemoryUserDetailsManager userDetailsService() {
        UserDetails user = User.withUsername("user1")
            .password("{noop}user1Pass")
            .roles("USER")
            .build();
        UserDetails admin = User.withUsername("admin")
            .password("{noop}adminPass")
            .roles("ADMIN")
            .build();
        return new InMemoryUserDetailsManager(user, admin);
    }
}

단순화를 위해 간단한 메모리 내 인증을 구현합니다. 사용자 세부 정보는 하드 코딩되어 있습니다.

이는 전체 지속성 메커니즘이 필요하지 않을 때 신속한 프로토타이핑에 사용하기 위한 것입니다.

다음으로 SecurityWebApplicationInitializer 클래스를 추가하여 기존 시스템에 Security을 통합해 보겠습니다 .

public class SecurityWebApplicationInitializer
  extends AbstractSecurityWebApplicationInitializer {

    public SecurityWebApplicationInitializer() {
        super(SpringSecurityConfig.class);
    }
}

이 클래스는 애플리케이션 시작 중에 SpringSecurityConfig 가 로드 되도록 합니다 . 이 단계에서 우리는 Spring Security의 기본 구현을 달성했습니다 . 이 구현으로 Spring Security는 기본적으로 모든 요청 및 경로에 대한 인증을 요구합니다.

4. Security 규칙 설정

SecurityFilterChain 빈을 생성하여 Spring Security를 ​​추가로 사용자 정의할 수 있습니다 .

 @Bean
 public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
     http.csrf()
         .disable()
         .authorizeRequests()
         .antMatchers("/auth/login*")
         .anonymous()
         .antMatchers("/home/admin*")
         .hasRole("ADMIN")
         .anyRequest()
         .authenticated()
         .and()
         .formLogin()
         .loginPage("/auth/login")
         .defaultSuccessUrl("/home", true)
         .failureUrl("/auth/login?error=true")
         .and()
         .logout()
         .logoutSuccessUrl("/auth/login");
     return http.build();
 }

antMatchers() 메서드를 사용하여 /auth/login 에 대한 익명 액세스를 허용 하고 다른 모든 요청을 인증하도록 Spring Security를 ​​구성합니다.

4.1. 사용자 정의 로그인 페이지

사용자 지정 로그인 페이지는 formLogin() 메서드를 사용하여 구성됩니다 .

http.formLogin()
  .loginPage("/auth/login")

이것이 지정되지 않으면 Spring Security는 /login 에 기본 로그인 페이지를 생성합니다 .

<html>
<head></head>
<body>
<h1>Login</h1>
<form name='f' action="/auth/login" method='POST'>
    <table>
        <tr>
            <td>User:</td>
            <td><input type='text' name='username' value=''></td>
        </tr>
        <tr>
            <td>Password:</td>
            <td><input type='password' name='password'/></td>
        </tr>
        <tr>
            <td><input name="submit" type="submit" 
              value="submit"/></td>
        </tr>
    </table>
</form>
</body>
</html>

4.2. Custom 랜딩 페이지

로그인에 성공하면 Spring Security는 사용자를 애플리케이션의 루트로 리디렉션합니다. 기본 성공 URL을 지정하여 이를 재정의할 수 있습니다.

http.formLogin()
  .defaultSuccessUrl("/home", true)

defaultSuccessUrl() 메서드의 alwaysUse 매개변수를 true로 설정하면 사용자는 항상 지정된 페이지로 리디렉션됩니다.

alwaysUse 매개변수가 설정되지 않았거나 false로 설정된 경우 사용자는 인증을 요청하기 전에 액세스를 시도한 이전 페이지로 리디렉션됩니다.

마찬가지로 Custom 실패 랜딩 페이지를 지정할 수도 있습니다.

http.formLogin()
  .failureUrl("/auth/login?error=true")

4.3. 권한 부여

역할별로 리소스에 대한 액세스를 제한할 수 있습니다.

http.formLogin()
  .antMatchers("/home/admin*").hasRole("ADMIN")

관리자가 아닌 사용자가 /home/admin 엔드포인트에 액세스하려고 하면 액세스 거부 오류가 발생합니다.

사용자 역할에 따라 JSP 페이지의 데이터를 제한할 수도 있습니다. 이것은 <security:authorize> 태그를 사용하여 수행됩니다 .

<security:authorize access="hasRole('ADMIN')">
    This text is only visible to an admin
    <br/>
    <a href="<c:url value="/home/admin" />">Admin Page</a>
    <br/>
</security:authorize>

이 태그를 사용하려면 페이지 상단에 Spring Security 태그 taglib를 포함해야 합니다.

<%@ taglib prefix="security" 
  uri="http://www.springframework.org/security/tags" %>

5. 스프링 시큐리티 XML 구성

지금까지 Java에서 Spring Security를 ​​구성하는 방법을 살펴보았습니다. 동등한 XML 구성을 살펴보겠습니다.

먼저 XML 구성이 포함된 web/WEB-INF/spring 폴더 에 security.xml 파일을 생성해야 합니다 . 이러한 security.xml 구성 파일 의 예는 문서 끝에서 사용할 수 있습니다.

인증 관리자와 인증 Provider를 구성하여 시작하겠습니다. 단순화를 위해 간단한 하드 코딩된 사용자 자격 증명을 사용합니다.

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="user" 
              password="user123" 
              authorities="ROLE_USER" />
        </user-service>
    </authentication-provider>
</authentication-manager>

방금 수행한 작업은 사용자 이름, 암호 및 역할을 가진 사용자를 생성하는 것입니다.

또는 암호 인코더를 사용하여 인증 Provider를 구성할 수 있습니다.

<authentication-manager>
    <authentication-provider>
        <password-encoder hash="sha"/>
        <user-service>
            <user name="user"
              password="d7e6351eaa13189a5a3641bab846c8e8c69ba39f" 
              authorities="ROLE_USER" />
        </user-service>
    </authentication-provider>
</authentication-manager>

Spring의 UserDetailsService 또는 Datasource 의 사용자 정의 구현을 인증 Provider로 지정할 수도 있습니다 . 자세한 내용은 여기에서 확인할 수 있습니다 .

이제 인증 관리자를 구성했으므로 Security 규칙을 설정하고 액세스 제어를 적용해 보겠습니다.

<http auto-config='true' use-expressions="true">
    <form-login default-target-url="/secure.jsp" />
    <intercept-url pattern="/" access="isAnonymous()" />
    <intercept-url pattern="/index.jsp" access="isAnonymous()" />
    <intercept-url pattern="/secure.jsp" access="hasRole('ROLE_USER')" />
</http>

위 스니펫에서는 양식 로그인을 사용하도록 HttpSecurity를 ​​구성하고 /secure.jsp를 로그인 성공 URL로 설정했습니다 . /index.jsp"/" 경로 에 대한 익명 액세스를 허용했습니다 . 또한 /secure.jsp 에 대한 액세스 에는 인증이 필요하고 인증된 사용자는 최소한 ROLE_USER 수준의 권한이 있어야 한다고 지정했습니다 .

http 태그 auto-config 속성을 true 로 설정하면 구성에서 재정의할 필요가 없는 기본 동작을 구현하도록 Spring Security에 지시합니다. 따라서 /login/logout은 각각 사용자 로그인 및 로그아웃에 사용됩니다. 기본 로그인 페이Map 제공됩니다.

사용자 지정 로그인 및 로그아웃 페이지, 인증 실패 및 성공을 모두 처리하는 URL을 사용하여 form-login 태그를 추가로 사용자 지정할 수 있습니다 . Security Namespace 부록에는 form-login (및 기타) 태그 에 대해 가능한 모든 특성이 나열되어 있습니다 . 일부 IDE는 Ctrl 키 를 누른 상태에서 태그를 클릭하여 검사를 가능하게 합니다 .

마지막으로 애플리케이션 시작 중에 로드할 security.xml 구성의 경우 web.xml 에 다음 정의를 추가해야 합니다 .

<context-param>                                                                           
    <param-name>contextConfigLocation</param-name>                                        
    <param-value>                                                                         
      /WEB-INF/spring/*.xml                                                             
    </param-value>                                                                        
</context-param>                                                                          
                                                                                          
<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>                                                                         
                                                                                          
<listener>                                                                                
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

동일한 JEE 애플리케이션에서 XML 및 Java 기반 구성을 모두 사용하려고 하면 오류가 발생할 수 있습니다.

6. 결론

이 기사에서는 Spring Security로 Jakarta EE 애플리케이션을 보호하는 방법을 살펴보고 Java 기반 및 XML 기반 구성을 모두 시연했습니다.

또한 사용자의 역할에 따라 특정 리소스에 대한 액세스 권한을 부여하거나 취소하는 방법에 대해서도 논의했습니다.

전체 소스 코드 및 XML 정의는 GitHub에서 사용할 수 있습니다 .

res – Security (video) (cat=Security/Spring Security)