Spring Security (5): 인증 (Authentication) - 문자 인증번호 로그 인

29778 단어 SpringSecurity
일부 로그 인 은 휴대 전화 번 호 를 입력 하고 문자 인증 번 호 를 받 아 로그 인 한다.문자 인증 코드 는 이미지 인증 코드 원리 와 마찬가지 로 인증 코드 가 정확 한 지 확인 하 는 데 사용 할 필 터 를 사용자 정의 합 니 다.
  • login.html
  • <p>
        <label for="imageCode">     label>
        <input type="input" id="smsCode" name="smsCode" required>
        <button onclick="getSmsCode()">     button>
    p>
    
    <script>
    function getSmsCode() {
        var ajax = new XMLHttpRequest();
        ajax.open('get','/code/sms');
        ajax.send();
    }
    script>
    
  • controller
  • @Data
    @ToString
    @AllArgsConstructor
    @RequiredArgsConstructor
    public class SmsCode {
        private String code;
        private LocalDateTime expireTime;
    
    
        public SmsCode(String code, int expireIn) {
            this.code = code;
            this.expireTime = LocalDateTime.now().plusSeconds(expireIn);
        }
    
        public boolean isExpried() {
            return LocalDateTime.now().isAfter(expireTime);
        }
    }
    
    @RestController
    public class SmsValidateCodeController {
    
        private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();
        public static final String SESSION_KEY = "SESSION_KEY_SMS_CODE";
    
        @GetMapping("/code/sms")
        public void createCode(HttpServletRequest request) {
            SmsCode smsCode = createSmsCode();
            System.out.println("       :" + smsCode);
            sessionStrategy.setAttribute(new ServletWebRequest(request), SESSION_KEY, smsCode);
        }
    
        private SmsCode createSmsCode() {
            String code = (int) ((Math.random() * 9 + 1) * 100000) + "";
            return new SmsCode(code, 600);
        }
    }
    
  • filter
  • public class SmsValidateCodeFilter extends OncePerRequestFilter {
    
        @Autowired
        private AuthenticationFailureHandler authenticationFailureHandler;
    
        // spring-social-web
        private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
            if ("/login".equals(request.getRequestURI()) && "POST".equals(request.getMethod())) {
                try {
                    validate(new ServletWebRequest(request));
                } catch (ValidateCodeException e) {
                    authenticationFailureHandler.onAuthenticationFailure(request, response, e);
                    return;
                }
            }
    
            filterChain.doFilter(request, response);
        }
    
        private void validate(ServletWebRequest request) throws ServletRequestBindingException {
            SmsCode codeInSession = (SmsCode) sessionStrategy.getAttribute(request, SmsValidateCodeController.SESSION_KEY);
            String codeInRequest = ServletRequestUtils.getStringParameter(request.getRequest(), "smsCode");
    
            if (StringUtils.isEmpty(codeInRequest)) {
                throw new ValidateCodeException("       ");
            }
    
            if (codeInSession == null) {
                throw new ValidateCodeException("      ");
            }
    
            if (codeInSession.isExpried()) {
                sessionStrategy.removeAttribute(request, SmsValidateCodeController.SESSION_KEY);
                throw new ValidateCodeException("      ");
            }
    
            if (!codeInRequest.equals(codeInSession.getCode())) {
                throw new ValidateCodeException("      ");
            }
    
            sessionStrategy.removeAttribute(request, SmsValidateCodeController.SESSION_KEY);
        }
    
        public AuthenticationFailureHandler getAuthenticationFailureHandler() {
            return authenticationFailureHandler;
        }
    
        public void setAuthenticationFailureHandler(AuthenticationFailureHandler authenticationFailureHandler) {
            this.authenticationFailureHandler = authenticationFailureHandler;
        }
    }
    
  • configuration
  • @Configuration
    @EnableWebSecurity
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    
        @Autowired
        private MyUserDetailsService myUserDetailsService;
    
        @Autowired
        private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;
    
        @Autowired
        private MyAuthenticationFailureHandler myAuthenticationFailureHandler;
    
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
    
            SmsValidateCodeFilter smsValidateCodeFilter = new SmsValidateCodeFilter();
            smsValidateCodeFilter.setAuthenticationFailureHandler(myAuthenticationFailureHandler);
    
            http.csrf().disable()
                    //          
                    .authorizeRequests()
                    .antMatchers("/login", "/code/image", "/code/sms").permitAll()
                    .anyRequest()
                        .authenticated()
                        .and()
                    //         
                    .addFilterBefore(smsValidateCodeFilter, UsernamePasswordAuthenticationFilter.class)
                    .formLogin()
                        .loginPage("/login")
                        .usernameParameter("username")
                        .passwordParameter("password")
                        .successHandler(myAuthenticationSuccessHandler)
                        .failureUrl("/login?error")
                        .permitAll()
                        .and()
                    //       
                    .logout()
                        .permitAll();
    
        }
    
        @Override
        public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(myUserDetailsService).passwordEncoder(passwordEncoder());
        }
    
        @Override
        public void configure(WebSecurity web) {
            web.ignoring().antMatchers("/static/**");
        }
    
        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    }
    
    

    좋은 웹페이지 즐겨찾기