2017-09-27 1 views
0

Ich arbeite an Spring Boot, mit Frühling Sicherheit für Auth Login. Ich habe diesen Teil beendet. Jetzt möchte ich Captcha auf der Anmeldeseite implementieren. Ich habe es getan, aber manchmal ging der Wert schief. Hier mein Quellcode.Frühling Sicherheit validate captcha über Filter hat falschen Wert

Login-Seite

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

In Sicherheitskonfigurations

@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); 
    } 
} 

In captcha Validierfilter

@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); 
    } 

Und in userDetailsImplement

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); 
    } 

So in Login-Controller:

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; 
    } 

Also, ich debuggen in captcha Filter der Wert captchaOk oft ändern. Nicht sicher, ob ich richtig mache.

Bitte werfen Sie einen Blick darauf und geben Sie Kommentare.

Danke.

Antwort

0

Ich habe einen Filter angepasst, um die Captcha in Spring Boot-Anwendung vor zu verify. Vielleicht stimmt etwas mit Ihrem benutzerdefinierten Filter nicht. Sie können sich auf meine Implementierungen beziehen:

1.CaptchaAuthenticationFilter: Setzen Sie den Verifizierungscode in die Sitzung, wenn Sie ihn erstellen, dann nehmen Sie ihn aus der Sitzung, um hier zu verifizieren.

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 es Sicherheit zum Frühling:

@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 die failureURL /login?error2 oben. Wenn das Captcha fehlschlägt, wird die Anfrage dorthin umgeleitet. Sie können den Fehler auf der Seite wie folgt erfassen:

<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> 
Verwandte Themen