SpringBoot+SpringSecurity 문자 인증 코드 로그 인 기능 구현

실현 원리
이전 글 에서 우 리 는 일반적인 계 정 비밀번호 로그 인 방식 을 소개 했다.SpringBoot+Spring Security 기본 사용 및 맞 춤 형 로그 인 설정그러나 지금 은 핸드폰 문자 인증 코드 를 통 해 직접 로그 인 하 는 흔 한 방법 도 있다.여 기 는 스스로 추가 적 인 일 을 해 야 한다.
SpringSecurity 인증 절차 상세 설명에 대해 어느 정도 알 고 있 습 니 다.계 정 암호 인증 과정 에서 다음 과 같은 몇 가지 유형 과 관련 되 었 습 니 다.UsernamePassword AuthenticationFilter(요청 매개 변수 획득 에 사용),UsernamePassword AuthenticationToken(사용자 로그 인 정보 표시),Provider Manager(인증 검증),
문자 인증 코드 를 통 해 로그 인 되 었 기 때문에 저 희 는 요청 한 매개 변수,인증 과정,사용자 로그 인 Token 정 보 를 재 작성 해 야 합 니 다.
물론 인증 코드 의 과정 은 우리 가 맨 앞 에 두 어야 한다.만약그래 픽 인증번호의 실현 이 같다 면.이러한 방법의 장점 은 인증 코드 를 이 과정 을 결합 시 켜 다른 인터페이스 도 사용 할 수 있 도록 하 는 것 이다.
기본 실현
인증번호 검사
문자 인증 코드 의 기능 이 실현 되 는 것 은 사실 도형 인증 코드 의 원리 와 같다.하 나 는 전단 에 있 는 그림 을 되 돌려 주 는 것 이 고 하 나 는 사용자 에 게 짧 은 메 시 지 를 보 내 는 것 입 니 다.여 기 는 문자 서비스 업 체 의 인 터 페 이 스 를 호출 하면 됩 니 다.더 많은 원 리 는 참고 할 수 있다SpringBoot+SpringSecurity 그래 픽 인증 코드 기능 구현
AuthenticationToken
계 정 비밀 번 호 를 사용 하여 로그 인 할 때 UsernamePassword AuthenticationToken 에는 사용자 의 계 정,비밀번호,기타 사용 가능 여부 등 상태 정보 가 포함 되 어 있 습 니 다.우 리 는 핸드폰 문자 메 시 지 를 통 해 로그 인 을 하기 때문에 비밀번호 가 없습니다.여기 서 우 리 는 UsernamePassword Authentication Token 의 코드 를 복사 해서 비밀번호 와 관련 된 정 보 를 없 애 면 됩 니 다.

public class SmsCodeAuthenticationToken extends AbstractAuthenticationToken {

  private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;

  private final Object principal;

  public SmsCodeAuthenticationToken(String mobile) {
    super(null);
    this.principal = mobile;
    setAuthenticated(false);
  }

  public SmsCodeAuthenticationToken(Object principal,
                   Collection<? extends GrantedAuthority> authorities) {
    super(authorities);
    this.principal = principal;
    super.setAuthenticated(true); // must use super, as we override
  }

  public Object getCredentials() {
    return null;
  }

  public Object getPrincipal() {
    return this.principal;
  }

  public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
    if (isAuthenticated) {
      throw new IllegalArgumentException(
          "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
    }
    super.setAuthenticated(false);
  }

  @Override
  public void eraseCredentials() {
    super.eraseCredentials();
  }
}

AuthenticationFilter
계 정 암호 로그 인 프로 세 스에 서 기본적으로 UsernamePassword AuthenticationFilter 를 사용 합 니 다.요청 에서 계 정,비밀 번 호 를 가 져 오고 요청 방식 을 검증 하여 AuthenticationToken 을 생 성 하 는 역할 을 합 니 다.여기 서 우리 의 매개 변 수 는 어느 정도 변화 가 있 기 때문에 여전히 옛날 방법 입 니 다.copy 는 간단 한 수정 을 진행 합 니 다.

public class SmsCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
  //     key
  private String mobileParameter = SecurityConstants.DEFAULT_PARAMETER_NAME_MOBILE;
  //      POST
  private boolean postOnly = true;

  public SmsCodeAuthenticationFilter() {
    //      url
    super(new AntPathRequestMatcher(SecurityConstants.DEFAULT_LOGIN_PROCESSING_URL_MOBILE, "POST"));
  }

  public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
      throws AuthenticationException {
    if (postOnly && !request.getMethod().equals("POST")) {
      throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
    }
    //        ,    value
    String mobile = obtainMobile(request);
    if (mobile == null) {
      mobile = "";
    }
    mobile = mobile.trim();

    //      AuthenticationToken
    SmsCodeAuthenticationToken authRequest = new SmsCodeAuthenticationToken(mobile);

    setDetails(request, authRequest);

    return this.getAuthenticationManager().authenticate(authRequest);
  }

  /**
   *      
   */
  protected String obtainMobile(HttpServletRequest request) {
    return request.getParameter(mobileParameter);
  }
  //        
}

Provider
계 정 비밀번호 로그 인 과정 에서 비밀번호 의 정확성 과 계 정 이 Dao AuthenticationProvider 를 통 해 검 사 될 수 있 는 지 여 부 를 확인 합 니 다.우리 도 스스로 Provier 를 실현 해 야 한다.

public class SmsCodeAuthenticationProvider implements AuthenticationProvider {

  private UserDetailsService userDetailsService;

  /**
   *       
   * @param authentication
   * @return
   * @throws AuthenticationException
   */
  @Override
  public Authentication authenticate(Authentication authentication) throws AuthenticationException {

    SmsCodeAuthenticationToken authenticationToken = (SmsCodeAuthenticationToken) authentication;

    UserDetails user = userDetailsService.loadUserByUsername((String) authenticationToken.getPrincipal());

    if (user == null) {
      throw new InternalAuthenticationServiceException("        ");
    }

    SmsCodeAuthenticationToken authenticationResult = new SmsCodeAuthenticationToken(user, user.getAuthorities());

    authenticationResult.setDetails(authenticationToken.getDetails());

    return authenticationResult;
  }

  @Override
  public boolean supports(Class<?> authentication) {
    return SmsCodeAuthenticationToken.class.isAssignableFrom(authentication);
  }

  public UserDetailsService getUserDetailsService() {
    return userDetailsService;
  }

  public void setUserDetailsService(UserDetailsService userDetailsService) {
    this.userDetailsService = userDetailsService;
  }
}
배치 하 다.
주요 한 인증 절 차 는 상기 네 가지 과정 을 통 해 이 루어 진 것 이다.여기 서 우 리 는 그것들 을 다시 내 려 배치 하면 된다.

@Component
public class SmsCodeAuthenticationSecurityConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {

  @Autowired
  private AuthenticationSuccessHandler myAuthenticationSuccessHandler;

  @Autowired
  private AuthenticationFailureHandler myAuthenticationFailureHandler;

  @Autowired
  private UserDetailsService userDetailsService;

  @Override
  public void configure(HttpSecurity http) throws Exception {

    SmsCodeAuthenticationFilter smsCodeAuthenticationFilter = new SmsCodeAuthenticationFilter();
    smsCodeAuthenticationFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
    smsCodeAuthenticationFilter.setAuthenticationSuccessHandler(myAuthenticationSuccessHandler);
    smsCodeAuthenticationFilter.setAuthenticationFailureHandler(myAuthenticationFailureHandler);

    SmsCodeAuthenticationProvider smsCodeAuthenticationProvider = new SmsCodeAuthenticationProvider();
    smsCodeAuthenticationProvider.setUserDetailsService(userDetailsService);

    http.authenticationProvider(smsCodeAuthenticationProvider)
        .addFilterAfter(smsCodeAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

  }
}
 
// BrowerSecurityConfig.java
@Override
protected void configure(HttpSecurity http) throws Exception {
  http.apply(smsCodeAuthenticationSecurityConfig);
}
코드 다운로드
Spring-Security
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기