1. 소개

이 글은 Login with Spring Security 에 초점을 맞출 것 입니다. 로그인 메커니즘과 함께 웹 애플리케이션을 설정하는 데 필요한 부분이므로 간단한 이전 Spring MVC 예제 를 기반으로 빌드 할 것 입니다.

2. Maven 의존성

Spring Boot로 작업 할 때 spring-boot-starter-security 스타터는 spring-security-core , spring-security-webspring-security-config 와 같은 모든 의존성을 자동으로 포함합니다 .

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>2.3.3.RELEASE</version>
</dependency>

Spring Boot를 사용하지 않는 경우 필요한 모든 의존성을 추가하는 방법을 설명하는 Spring Security with Maven 기사 를 참조하십시오 . 표준 spring-security-webspring-security-config 가 모두 필요합니다.

3. 스프링 Security 자바 구성

WebSecurityConfigurerAdapter 를 확장하는 Spring Security 구성 클래스를 작성하여 시작하겠습니다  .

@EnableWebSecurity 를 추가 하면 Spring Security 및 MVC 통합 지원이 제공됩니다.

@Configuration
@EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
        // authentication manager (see below)
    }

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        // http builder configurations for authorize requests and form login (see below)
    }
}

이 예에서는 메모리 내 인증을 사용하고 3 명의 사용자를 정의했습니다.

다음으로 양식 로그인 구성을 만드는 데 사용한 요소를 살펴 봅니다.

먼저 인증 관리자를 구축해 보겠습니다.

3.1. 인증 관리자

인증 공급자는 특히 InMemoryUserDetailsManager 라는 간단한 메모리 내 구현으로 지원됩니다 . 이는 완전한 지속성 메커니즘이 아직 필요하지 않은 경우 신속한 프로토 타이핑에 유용합니다.

protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
        .withUser("user1").password(passwordEncoder().encode("user1Pass")).roles("USER")
        .and()
        .withUser("user2").password(passwordEncoder().encode("user2Pass")).roles("USER")
        .and()
        .withUser("admin").password(passwordEncoder().encode("adminPass")).roles("ADMIN");
}

여기서는 하드 코딩 된 사용자 이름, 암호 및 역할을 사용하여 세 명의 사용자를 구성합니다.

Spring 5부터는 암호 인코더도 정의해야합니다 . 이 예에서는 BCryptPasswordEncoder를 사용했습니다 .

@Bean 
public PasswordEncoder passwordEncoder() { 
    return new BCryptPasswordEncoder(); 
}

다음으로 HttpSecurity를 구성 해 보겠습니다.

3.2. 요청 승인을위한 구성

요청 승인에 필요한 구성을 수행하는 것으로 시작합니다.

여기서는 사용자가 인증 할 수 있도록 / login에 대한 익명 액세스를 허용 합니다. / adminADMIN 역할로 제한 하고 다른 모든 것을 보호합니다.

@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
      .csrf().disable()
      .authorizeRequests()
      .antMatchers("/admin/**").hasRole("ADMIN")
      .antMatchers("/anonymous*").anonymous()
      .antMatchers("/login*").permitAll()
      .anyRequest().authenticated()
      .and()
      // ...
}

antMatchers ()  요소 의 순서 는 중요 합니다. 더 구체적인 규칙이 먼저 나오고 그 다음이 더 일반적인 규칙 이옵니다 .

3.3. 양식 로그인 구성

다음으로, 양식 로그인 및 로그 아웃을 위해 위의 구성을 확장합니다.

@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
      // ...
      .and()
      .formLogin()
      .loginPage("/login.html")
      .loginProcessingUrl("/perform_login")
      .defaultSuccessUrl("/homepage.html", true)
      .failureUrl("/login.html?error=true")
      .failureHandler(authenticationFailureHandler())
      .and()
      .logout()
      .logoutUrl("/perform_logout")
      .deleteCookies("JSESSIONID")
      .logoutSuccessHandler(logoutSuccessHandler());
}
  • loginPage ()  – 사용자 정의 로그인 페이지
  • loginProcessingUrl () – 사용자 이름과 암호를 제출할 URL
  • defaultSuccessUrl () – 성공적인 로그인 후 랜딩 페이지
  • failureUrl () – 로그인 실패 후 방문 페이지
  • logoutUrl () – 사용자 정의 로그 아웃

4. 웹 애플리케이션에 Spring Security 추가

위에서 정의한 Spring Security 구성을 사용하려면 웹 애플리케이션에 첨부해야합니다.

WebApplicationInitializer를 사용 하므로 web.xml 을 제공 할 필요가 없습니다 .

public class AppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext sc) {

        AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
        root.register(SecSecurityConfig.class);

        sc.addListener(new ContextLoaderListener(root));

        sc.addFilter("securityFilter", new DelegatingFilterProxy("springSecurityFilterChain"))
          .addMappingForUrlPatterns(null, false, "/*");
    }
}

Spring Boot 애플리케이션을 사용하는 경우이 초기화 프로그램이 필요하지 않습니다. Spring Boot 에서 Security 구성이로드되는 방법에 대한 자세한 내용은 Spring Boot Security 자동 구성에 대한 기사 를 참조하십시오.

5. 스프링 Security XML 설정

해당 XML 구성도 살펴 보겠습니다.

전체 프로젝트는 Java 구성을 사용하므로 Java @Configuration 클래스 를 통해 XML 구성 파일을 가져와야합니다 .

@Configuration
@ImportResource({ "classpath:webSecurityConfig.xml" })
public class SecSecurityConfig {
   public SecSecurityConfig() {
      super();
   }
}

그리고 Spring Security XML 구성 – webSecurityConfig.xml :

<http use-expressions="true">
    <intercept-url pattern="/login*" access="isAnonymous()" />
    <intercept-url pattern="/**" access="isAuthenticated()"/>

    <form-login login-page='/login.html' 
      default-target-url="/homepage.html" 
      authentication-failure-url="/login.html?error=true" />
    <logout logout-success-url="/login.html" />
</http>

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="user1" password="user1Pass" authorities="ROLE_USER" />
        </user-service>
        <password-encoder ref="encoder" />
    </authentication-provider>
</authentication-manager>

<beans:bean id="encoder" 
  class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
</beans:bean>

6. web.xml

Spring 4가 도입되기 전에 우리는 web.xml 에서 Spring Security 구성을 구성하는 데 사용  했습니다. 표준 Spring MVC web.xml에 추가 된 필터 만 추가되었습니다 .

<display-name>Spring Secured Application</display-name>

<!-- Spring MVC -->
<!-- ... -->

<!-- Spring 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>

필터 – DelegatingFilterProxy – 단순히 Spring 관리 빈 – FilterChainProxy – 전체 Spring 빈 라이프 사이클 관리 등의 혜택을받을 수 있습니다.

7. 로그인 양식

로그인 양식 페이지는 간단한 메커니즘을 사용하여 Spring MVC에 등록 되어 중간에 명시적인 컨트롤러가 필요하지 않은 URL에 뷰 이름을 매핑합니다 .

registry.addViewController("/login.html");

물론 이것은 login.jsp에 해당합니다 .

<html>
<head></head>
<body>
   <h1>Login</h1>
   <form name='f' action="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>

Spring 로그인 양식은 다음과 같은 관련 유물이있다 :

  • login – 인증 프로세스를 트리거하기 위해 양식이 게시되는 URL
  • username – 사용자 이름
  • password – 암호

8. Spring 로그인 추가 구성

위에서 스프링 Security 구성을 소개했을 때 로그인 메커니즘의 몇 가지 구성에 대해 간략히 논의했습니다. 이제 좀 더 자세히 살펴 보겠습니다.

Spring Security에서 대부분의 기본값을 재정의하는 한 가지 이유 는 애플리케이션이 Spring Security로 Security 사실숨기고 잠재적 인 공격자가 애플리케이션에 대해 알고있는 정보를 최소화하는 것입니다.

완전히 구성된 로그인 요소는 다음과 같습니다.

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.formLogin()
      .loginPage("/login.html")
      .loginProcessingUrl("/perform_login")
      .defaultSuccessUrl("/homepage.html",true)
      .failureUrl("/login.html?error=true")
}

또는 해당 XML 구성 :

<form-login 
  login-page='/login.html' 
  login-processing-url="/perform_login" 
  default-target-url="/homepage.html"
  authentication-failure-url="/login.html?error=true" 
  always-use-default-target="true"/>

8.1. 로그인 페이지

다음으로 loginPage () 메서드를 사용하여 사용자 지정 로그인 페이지를 구성하는 방법을 살펴 보겠습니다 .

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

또는 XML 구성을 통해 :

login-page='/login.html'

이것을 지정하지 않으면 Spring Security는 / login URL에 매우 기본적인 로그인 양식을 생성합니다 .

8.2. 로그인을위한 POST URL

인증 프로세스를 트리거하기 위해 Spring 로그인이 POST하는 기본 URL은 Spring Security 4 이전에 / j_spring_security_check 이었던 / login 입니다 .

loginProcessingUrl  메서드를 사용 하여이 URL을 재정 의 할 수 있습니다 .

http.formLogin()
  .loginProcessingUrl("/perform_login")

또는 XML 구성을 통해 :

login-processing-url="/perform_login"

이 기본 URL을 재정의하는 좋은 이유는 애플리케이션이 실제로 Spring Security로 Security된다는 사실을 숨기는 것입니다. 그 정보는 외부에서 사용할 수 없어야합니다.

8.3. 성공의 랜딩 페이지

로그인 프로세스가 성공하면 사용자는 기본적으로 웹 응용 프로그램의 루트 인 페이지로 리디렉션됩니다.

defaultSuccessUrl () 메서드 를 통해이를 재정의 할 수 있습니다 .

http.formLogin()
  .defaultSuccessUrl("/homepage.html")

또는 XML 구성 :

default-target-url="/homepage.html"

경우에 항상 사용 기본 대상이 true로 설정 한 후 사용자는 항상이 페이지로 리디렉션됩니다. 해당 속성이 false로 설정되면 사용자는 인증하라는 메시지가 표시되기 전에 방문하려는 이전 페이지로 리디렉션됩니다.

8.4. 실패에 대한 랜딩 페이지

로그인 페이지와 마찬가지로 로그인 실패 페이지는 / login? 기본적으로 오류입니다.

이를 재정의하려면 failureUrl () 메서드를 사용할 수 있습니다  .

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

또는 XML :

authentication-failure-url="/login.html?error=true"

9. 결론

Spring Login Example 에서는 간단한 인증 프로세스를 구성했습니다. Spring Security 로그인 양식, Security 구성 및 사용 가능한 일부 고급 사용자 정의에 대해 논의했습니다.

이 Spring 로그인 튜토리얼의 구현은 GitHub 프로젝트 에서 찾을 수 있습니다. 이것은 Eclipse 기반 프로젝트이므로 그대로 가져 와서 실행하기 쉽습니다.

프로젝트가 로컬에서 실행되면 다음 위치에서 샘플 HTML에 액세스 할 수 있습니다.

http://localhost:8080/spring-security-mvc-login/login.html