2016-08-18 3 views
0

Ich entwickle einen RESTful Web-Service und hatte Login-Funktion. Ich wollte Token Sicherheit und den Zugang fügen, damit ich ein UserDetailsService hinzugefügt, wie unten zu sehen:Spring Sicherheit loadByUsername Benutzername Feld ist leer

@Component 
public class CustomLoginAuthenticationProvider implements UserDetailsService { 

    @Autowired 
    private BusinessUserService businessUserService; 

    @Override 
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { 
     if(email == null || email.isEmpty() || !email.contains("@")) { 
      System.out.println("ERROR - THIS IS THE USERNAME:" + email); 
      throw new UsernameNotFoundException(email); 
     } 
    //... More below, but it doesn't matter. Exception thrown every time 
} 

jedoch der E-Mail-String ist leer. Ich kann nicht verstehen, warum, weil es mir schwer fällt zu verstehen, wann genau diese Methode aufgerufen wird und welcher Wert als Parameter für diese Methode gesendet wird, da dies ein REST-Backend ist, das JSON sendet. Hier sind meine WebSecurityConfigurerAdapter Setup:

@Configuration 
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) 
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { 

    @Bean 
    public CustomLoginAuthenticationProvider customLoginAuthenticationProvider() { 
     return new CustomLoginAuthenticationProvider(); 
    } 

    @Bean 
    public BCryptPasswordEncoder passwordEncoder() { 
     return new BCryptPasswordEncoder(); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
      .authorizeRequests() 
      .antMatchers("/css/**", "/js/**", "/images/**", "/fonts/**", 
         "/videos/**", "/", "/register", "/login", "/about", 
         "/contact", "/test") 
      .permitAll() 
     .and() 
      .authorizeRequests() 
      .anyRequest() 
      .authenticated()        
     .and() 
      .exceptionHandling() 
      .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/")) 
     .and() 
      .formLogin() 
      .loginPage("/login") 
      .loginProcessingUrl("/login") 
      .usernameParameter("email") 
      .passwordParameter("password") 
     .and() 
      .logout() 
      .logoutSuccessUrl("/") 
      .permitAll() 
     .and() 
      .csrf() 
      .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) 
     .and() 
      .addFilterAfter(new CsrfTokenFilter(), CsrfFilter.class); 
    } 
} 

ich angeben, dass eine E-Mail an die Methode gesendet werden soll, wenn ich .usernameParameter("email") verwenden, so bin ich nicht wirklich sicher, warum es nicht die E-Mail-Parameter bevölkert. Ich verwende AngularJS im Frontend und sende die Zugangsdaten mit JSON zum Backend.

+0

können Sie Ihr Anmeldeformular hier eingeben? –

Antwort

1

Wenn Sie die Anmeldeinformationen in JSON senden, liegt der Fehler hier daran, dass die E-Mail kein HTTP-Parameter ist, der in RequestBody enthalten ist.

Der Standard UsernamePasswordAuthenticationFilter nimmt die Anmeldeinformationen von http param:

public class UsernamePasswordAuthenticationFilter extends 
     AbstractAuthenticationProcessingFilter { 


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

      String username = obtainUsername(request); 
      String password = obtainPassword(request); 
      ... 
    } 

    /** 
     * Enables subclasses to override the composition of the password, such as by 
     * including additional values and a separator. 
     * <p> 
     * This might be used for example if a postcode/zipcode was required in addition to 
     * the password. A delimiter such as a pipe (|) should be used to separate the 
     * password and extended value(s). The <code>AuthenticationDao</code> will need to 
     * generate the expected password in a corresponding manner. 
     * </p> 
     * 
     * @param request so that request attributes can be retrieved 
     * 
     * @return the password that will be presented in the <code>Authentication</code> 
     * request token to the <code>AuthenticationManager</code> 
     */ 
     protected String obtainPassword(HttpServletRequest request) { 
      return request.getParameter(passwordParameter); 
     } 

     /** 
     * Enables subclasses to override the composition of the username, such as by 
     * including additional values and a separator. 
     * 
     * @param request so that request attributes can be retrieved 
     * 
     * @return the username that will be presented in the <code>Authentication</code> 
     * request token to the <code>AuthenticationManager</code> 
     */ 
     protected String obtainUsername(HttpServletRequest request) { 
      return request.getParameter(usernameParameter); 
     } 

Sie müssen Ihre eigenen Filter schreiben, wo Sie die eingehenden Anmeldeinformationen aus dem RequestBody lesen muss und es in Ihrer Konfiguration in der Position des UsernamePasswordAuthenticationFilter eingestellt.

Sie einen Blick auf https://stackoverflow.com/a/35724932/4190848 und https://stackoverflow.com/a/35699200/4190848

0

Eine andere Lösung haben könnte, das ist viel einfacher, dann ist dies in der Client-Anwendung zu tun - arbeitet mit Spring Security fein:

public login(username: string, password: string) { 
    const headers = new Headers(); 
    headers.append('Content-Type', 'application/x-www-form-urlencoded'); 

    return this.http.post(
     `http://www.myserver.com:8080/myApp/login`, 
     encodeURI(`username=${username}&password=${password}`), 
     { headers } 
    ); 
    } 
} 

Das blendet die Parameter aus der URL und codiert sie als Formulardaten, und die Standardimplementierung von Spring Security mag dies sehr.

+0

Stellen Sie sicher, dass Sie sie als Parameter anstelle von JSON-Daten übergeben. Ein Winkel Weise JSON Daten als Parameter $ HTTP ({ \t \t 'url': 'Anmelden' \t \t 'Methode': 'Post', \t \t 'params': user \t} der Weitergabe) – Ram

Verwandte Themen