2017-09-27 5 views
0

저는 스프링 로그인시 인증을 위해 스프링 보안을 사용하고 있습니다. 나는이 부분을 마쳤다. 이제 로그인 페이지에 captcha를 구현하고 싶습니다. 나는 그것을했지만 때로는 가치가 잘못되었다. 여기 내 소스 코드.필터를 통해 스프링 보안 유효성 검사 captcha에 잘못된 값이 있습니다.

로그인 페이지 보안 설정에서

<form th:action="@{/j_spring_security_check}" method="post"> 
<tr> 
       <th align="left" width="30%"> 
        <label for="userId">User Id</label> 
       </th> 
       <td width="70%"> 

        <input type="text" style="width: 150px" name="userId" autocomplete="off"/> 
       </td> 
      </tr> 
      <tr> 
       <th align="left" width="30%"> 
        Password 
       </th> 
       <td width="70%"> 

        <input type="PASSWORD" style="width: 150px" name="password" autocomplete="off"/> 
       </td> 
      </tr> 
      <tr> 
       <th align="left" width="30%"> 
        Answer 
       </th> 
       <td width="70%"> 
        <input type="text" name="logonAnswer" style="width: 150px"/> 
       </td> 
      </tr> 
      <tr> 
       <td align="right">&nbsp; 
       </td> 
       <td align="left"> 
        <div id="captcha" 
         style="cursor: pointer; height: 30px; width: 150px; display: inline-block; float: left"><img 
          th:src="@{/captcha}"/></div> 
        <div id="captchaRefresh" class="refresh-btn" title="Click to get other Captcha"></div> 
       </td> 
      </tr> 
</form> 

보안 문자 확인 필터에서

@Configuration 
@EnableWebSecurity 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private UserDetailsService userDetailsService; 
    @Autowired 
    private AccessDeniedHandler accessDeniedHandler; 
    @Autowired 
    private RoleRepository roleRepository; 
    @Autowired 
    private CaptchaFilter captchaFilter; 

    @Autowired 
    private PasswordEncoder passwordEncoder() { 
     return new CustomerPasswordEncoder(); 
    } 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
     auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
       .authorizeRequests() 
       .antMatchers("/register").permitAll() 
       .antMatchers("/configuration/**").hasRole(roleRepository.getRolesByGroup("USER")) 
       .antMatchers("/configuration/**", "/merchant/**", "/import/**", "/manualSettle/**", "/report/**", "/user/**").hasAnyRole(roleRepository.getRolesByGroup("ADMIN")) 
       .antMatchers("/superadmin").hasRole(roleRepository.getRolesByGroup("SUPERADMIN")) 
       .and() 
       .formLogin() 
       .loginPage("/login") 
       .loginProcessingUrl("/j_spring_security_check") 
       .usernameParameter("userId") 
       .passwordParameter("password") 
       .defaultSuccessUrl("/") 
       .failureUrl("/login?error") 
       .and() 
       .addFilterBefore(captchaFilter, UsernamePasswordAuthenticationFilter.class) 
       .exceptionHandling().accessDeniedHandler(accessDeniedHandler); 
    } 
} 

@Autowired 
    UserDetailsServiceImpl userDetailsService; 

    @Override 
    public void init(FilterConfig filterConfig) throws ServletException { 

    } 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
     HttpServletRequest request = (HttpServletRequest) req; 
     HttpSession session = request.getSession(false); 
     if (userDetailsService != null 
       && request.getParameter("logonAnswer") != null 
       && !request.getParameter("logonAnswer").equals("") 
       && session != null && request.getParameter("logonAnswer").equalsIgnoreCase(session.getAttribute("wirecardmposcaptcha").toString())) { 
      userDetailsService.setCaptchaOK(true); 
     } 

     chain.doFilter(request, response); 
    } 

그리고 로그인 컨트롤러에

private boolean captchaOK; 

    public void setCaptchaOK(boolean captchaOK) { 
     this.captchaOK = captchaOK; 
    } 

    @Override 
    @Transactional 
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 
     Users user = userRepository.findByUserId(username); 
     if (user == null) { 
      throw new UsernameNotFoundException("UserId or Password invalid"); 
     } 

     if (!captchaOK) 
      throw new InternalAuthenticationServiceException("Invalid Captcha"); 

     Set<GrantedAuthority> grantedAuthorities = new HashSet<>(); 
     Set<Roles> roles = user.getRoles(); 
     for (Roles role : roles) { 
      grantedAuthorities.add(new SimpleGrantedAuthority(role.getRoleName())); 
     } 

     return new org.springframework.security.core.userdetails.User(user.getUserId(), user.getPassword(), user.getEnabled().equals("true"), true, true, true, grantedAuthorities); 
    } 

userDetailsImplement에 :

private String getErrorMessage(HttpServletRequest request, String key) { 

     Exception exception = (Exception) request.getSession().getAttribute(key); 

     String error = ""; 
     if (exception instanceof BadCredentialsException) { 
      error = "Invalid user ID and password!"; 
     } else if (exception instanceof DisabledException) { 
      error = "User is locked"; 
     } else if (exception instanceof InternalAuthenticationServiceException) { 
      error = "Invalid answer."; 
     } else { 
      error = "Invalid user ID and password!"; 
     } 

     return error; 
    } 

그래서, 나는 captchaOk의 값이 여러 번 변경 보안 문자 필터 디버깅합니다. 내가 올바른 길을하고 있는지 확실하지 않습니다.

한번보세요. 의견을 보내주세요.

감사합니다.

답변

0

이전에 봄 부팅 응용 프로그램에서 captcha를 화나게하는 필터를 사용자 정의했습니다. 사용자 정의 된 필터에 문제가있을 수 있습니다. 내 구현을 참조 할 수 있습니다.

1.CaptchaAuthenticationFilter : 인증 코드를 생성 할 때 세션에 넣은 다음 세션에서 가져 와서 확인하십시오.

@Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.csrf().disable(); 
     // add filter here 
     http.addFilterBefore(new CaptchaAuthenticationFilter("/login", "/login?error2"), UsernamePasswordAuthenticationFilter.class); 
     http.authorizeRequests() 
       .antMatchers("/").hasRole("USER") 
       .antMatchers("/index").hasRole("USER") 
       .antMatchers("/message/*").hasRole("USER") 
       .anyRequest().permitAll() 
       .and().formLogin().loginPage("/login").defaultSuccessUrl("/index").failureUrl("/login?error1").permitAll() 
       .and().rememberMe().tokenValiditySeconds(60*60*7).key("message") 
       .and().logout().logoutUrl("/logout").logoutSuccessUrl("/login").permitAll(); 
    } 

3.Note failureUrl /login?error2 위 :

import org.springframework.security.authentication.InsufficientAuthenticationException; 
import org.springframework.security.core.Authentication; 
import org.springframework.security.core.AuthenticationException; 
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; 
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; 

import javax.servlet.FilterChain; 
import javax.servlet.ServletException; 
import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import java.io.IOException; 

/** 
* The filter to verify captcha. 
*/ 
public class CaptchaAuthenticationFilter extends AbstractAuthenticationProcessingFilter { 

    private String processUrl; 

    public CaptchaAuthenticationFilter(String defaultFilterProcessesUrl, String failureUrl) { 
     super(defaultFilterProcessesUrl); 
     this.processUrl = defaultFilterProcessesUrl; 
     setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler(failureUrl)); 
    } 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
     HttpServletRequest req = (HttpServletRequest) request; 
     HttpServletResponse res=(HttpServletResponse)response; 
     if(processUrl.equals(req.getServletPath()) && "POST".equalsIgnoreCase(req.getMethod())){ 
      String expect = req.getSession().getAttribute("YZM").toString(); 

      //remove from session 
      req.getSession().removeAttribute("YZM"); 

      if (expect != null && !expect.equals(req.getParameter("verifyCode"))){ 
       unsuccessfulAuthentication(req, res, new InsufficientAuthenticationException("Wrong verification code.")); 
       return; 
      } 
     } 
     chain.doFilter(request, response); 
    } 

    @Override 
    public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException { 
     return null; 
    } 
} 

2.Configure는 보안을 봄합니다. captcha가 실패를 확인하면 요청이 거기로 리디렉션됩니다. 다음 페이지에서 오류를 캡처 할 수 있습니다.

<div class="clearfix"> 
    <div th:if="${param.error1}"> 
     <div class="btn btn-xs btn-danger"> 
      <i class="icon-bolt bigger-110"></i> 
      Wrong username or password! 
     </div> 
    </div> 

    <div th:if="${param.error2}"> 
     <div class="btn btn-xs btn-danger"> 
      <i class="icon-bolt bigger-110"></i> 
      Wrong verification code! 
     </div> 
    </div> 
</div>