Spring security 사용자 정의 인증 절차 상세 설명

1.사용자 정의 로그 인 페이지
(1)먼저 static 디 렉 터 리 아래 login.html 를 만 듭 니 다.
메모:springboot 프로젝트 는 기본적으로 resources/resources,resources/staic,resources/Public 디 렉 터 리 아래 의 정적 파일 에 접근 할 수 있 습 니 다.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>    </title>
</head>
<body>
<form action="/auth/login" method="post">
     :<input type="text" name="username">
  <br/>
   &emsp; :<input type="password" name="password">
  <br/>
  <input type="submit" value="  ">
</form>
</body>
</html>
(2)spring security 설정 클래스 에서 다음 과 같이 설정 합 니 다.

@Override
  protected void configure(HttpSecurity http) throws Exception {
    http.formLogin()
        //          
        .loginPage("/login.html")
        //   url
        .loginProcessingUrl("/auth/login")
        .and()
        .authorizeRequests()
        //     url   ,     login.html,   
        .antMatchers("/login.html").permitAll()
        .anyRequest()
        .authenticated()
        .and()
        //   spring security    csrf  
        .csrf().disable();
  }
(3)테스트
대략.
(4)존재 하 는 문제점
<1>재 활용 가능 한 로그 인 모듈 로 서 저 희 는 맞 춤 형 로그 인 페이지 를 제공 해 야 합 니 다.즉,login.html 로 만 넘 어 갈 수 없습니다.
이 문 제 는 비교적 잘 해결 되 었 습 니 다.설정 가능 한 로그 인 페이지 를 사용 하고 기본적으로 login.html 를 사용 하면 됩 니 다.
<2>login.html 로그 인 페이지 로 이동 을 요청 합 니 다.문제 가 없 는 것 같 지만 restful 스타일 의 인터페이스 로 서 일반적으로 json 데이터 형식,특히 app 요청 에 응답 합 니 다.
해결 사상:사용자 가 데이터 요청 을 시작 합 니 다.->security 는 인증 이 필요 한 지 판단 합 니 다.->사용자 정의 contrller 방법 으로 이동 합 니 다.->이 방법 에서 html 가 요청 한 것 인지 판단 합 니 다.그렇다면 login.html 로 이동 합 니 다.그렇지 않 으 면 json 형식의 데이터 에 응답 하여 오류 정 보 를 설명 합 니 다.
사용자 정의 컨트롤 러

@Slf4j
@RestController
public class LoginController {

  /**
   *     
   */
  private RequestCache requestCache = new HttpSessionRequestCache();

  /**
   *       
   */
  private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

  /**
   *                  ,           
   */
//  @Value("${xxxx:defaultLoginPage}")
//  private String standardLoginPage;
  private String standardLoginPage = "/login.html"; //    

  /**
   *         
   */
  @GetMapping("/user/auth")
  @ResponseStatus(code = HttpStatus.UNAUTHORIZED) //     
  public ResponseData login(HttpServletRequest request, HttpServletResponse response) throws IOException {
    SavedRequest savedRequest = requestCache.getRequest(request, response);
    if (savedRequest != null) {
      String targetUrl = savedRequest.getRedirectUrl();
      log.info("   :" + targetUrl);
      //       html  
      if (StringUtils.endsWithIgnoreCase(targetUrl, ".html")) {
        redirectStrategy.sendRedirect(request, response, standardLoginPage);
      }
    }
    return new ResponseData("       ,js         ,                  ?");
  }
}
spring security 가 이 controller 의 login 방법 에 권한 을 부여 합 니 다.

@Override
  protected void configure(HttpSecurity http) throws Exception {
    http.formLogin()
        //   controller  
        .loginPage("/user/auth")
        //          
        .loginPage("/login.html")
        //   url
        .loginProcessingUrl("/auth/login")
        .and()
        .authorizeRequests()
        //  controller    
        .antMatchers("/user/auth").permitAll()
        //     url   ,     login.html,   
        .antMatchers("/login.html").permitAll()
        .anyRequest()
        .authenticated()
        .and()
        //   spring security    csrf  
        .csrf().disable();
  }
이렇게 하면 돼!! 
2.사용자 정의 로그 인 성공 처리(json 으로 돌아 가기)
(1)AuthenticationSuccessHandler.java 구현

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Slf4j
@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
  @Autowired
  private ObjectMapper objectMapper;
  /**
   * Called when a user has been successfully authenticated.
   * @param request
   * @param response
   * @param authentication
   * @throws IOException
   * @throws ServletException
   */
  @Override
  public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
    log.info("    !!!");
    //             
    response.setContentType(MediaType.APPLICATION_JSON_VALUE);
    response.getWriter().write(objectMapper.writeValueAsString(authentication));

  }
}
(2)보안 설정 클래스 수정

@Autowired
  private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.formLogin()
        //   controller  
        .loginPage("/user/auth")
        //          
        .loginPage("/login.html")
        //   url
        .loginProcessingUrl("/auth/login")
        .successHandler(myAuthenticationSuccessHandler)
        .and()
        .authorizeRequests()
        //  controller    
        .antMatchers("/user/auth").permitAll()
        //     url   ,     login.html,   
        .antMatchers("/login.html").permitAll()
        .anyRequest()
        .authenticated()
        .and()
        //   spring security    csrf  
        .csrf().disable();
  }
(3)테스트

설명:authentication 대상 에 포 함 된 정 보 는 로그 인 방식 에 따라 달라 집 니 다.
3.사용자 정의 로그 인 실패 처리(json 으로 돌아 가기)
AuthenticationFailure Handler.java 인 터 페 이 스 를 실현 하면 로그 인 성패 처리 설정 과 같 습 니 다.
4.사용자 정의 로그 인 성공 처리 논리
이상 의 로그 인 이 성공 하거나 실패 한 것 은 모두 제 이 슨 입 니 다.그러나 어떤 경우 에는 로그 인 이 성공 하거나 실패 하여 페이지 전환(spring security 기본 처리 방식)이 존재 합 니 다.그러면 제 이 슨 으로 돌아 가 는 방식 은 적절 하지 않 습 니 다.그래서 우 리 는 더욱 유연 하 게 배치 할 수 있 는 것 을 만들어 야 한다.
로그 인 성공 논리 에 있어 서 는 MyAuthentication SuccessHandler.java 를 조금 만 수정 하면 됩 니 다.코드 는 다음 과 같 습 니 다.

/**
 * SavedRequestAwareAuthenticationSuccessHandler spring security         
 */
@Slf4j
@Component
public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
  @Autowired
  private ObjectMapper objectMapper;

  /**
   *        
   */
//  @Value("${xxx:    }")
  private String loginType = "JSON";
  /**
   * Called when a user has been successfully authenticated.
   */
  @Override
  public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
    log.info("    !!!");

    //           JSON,   json  
    if ("JSON".equals(loginType)) {
      //             
      response.setContentType(MediaType.APPLICATION_JSON_VALUE);
      response.getWriter().write(objectMapper.writeValueAsString(authentication));
    } else { //             
      super.onAuthenticationSuccess(request,response,authentication);
    }
  }
}
5.사용자 정의 로그 인 실패 처리 논리
로그 인 성공 과 유사 합 니 다.구체 적 인 코드 는 다음 과 같 습 니 다.

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Slf4j
@Component
public class MySimpleUrlAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
  @Autowired
  private ObjectMapper objectMapper;

  /**
   *        
   */
//  @Value("${xxx:    }")
  private String loginType = "JSON";
  @Override
  public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
    log.info("    !!!");

    //           JSON,   json  
    if ("JSON".equals(loginType)) {
      //             
      response.setStatus(HttpStatus.UNAUTHORIZED.value());
      response.setContentType(MediaType.APPLICATION_JSON_VALUE);
      response.getWriter().write(objectMapper.writeValueAsString(exception));
    } else { //             ,         
      super.onAuthenticationFailure(request,response,exception);
    }
  }
}

@Autowired
  private MySimpleUrlAuthenticationFailureHandler mySimpleUrlAuthenticationFailureHandler;
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.formLogin()
        //   controller  
        .loginPage("/user/auth")
        //          
        .loginPage("/login.html")
        //   url
        .loginProcessingUrl("/auth/login")
        .successHandler(myAuthenticationSuccessHandler)
        .failureHandler(mySimpleUrlAuthenticationFailureHandler)
        .and()
        .authorizeRequests()
        //  controller    
        .antMatchers("/user/auth").permitAll()
        //     url   ,     login.html,   
        .antMatchers("/login.html").permitAll()
        .anyRequest()
        .authenticated()
        .and()
        //   spring security    csrf  
        .csrf().disable();
  }
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기