2017-06-14 156 views
1

我有我试图从ionic4 Web应用程序发送POST请求过一个Java Springboot REST API。不幸的是,我无法让登录帖子工作。我要么收到一个HTTP状态401403200当它仅发送预检请求选项。的Java Spring Security的ionic4 HTTP请求

我检查了在计算器上类似的帖子,其存在的诸如this但他们只是改变了,我发现了错误。以下是我在结束其他SO帖子的各种教程&后得到的结果。

不知道我的错误是在Spring SecurityConfiguration或打字稿POST请求。

我的春天安全配置

@EnableWebSecurity 
@Configuration 
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) 
@EnableGlobalMethodSecurity(securedEnabled = true) 
class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

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

     http 
      .authorizeRequests() 

      .requestMatchers(CorsUtils::isPreFlightRequest).permitAll() 
      .antMatchers("/login").permitAll() 
      .antMatchers(HttpMethod.OPTIONS).permitAll() 
      .anyRequest().authenticated() 
      .and() 
      .addFilterBefore(new RestConfig().corsFilter(), CsrfFilter.class) 
      .csrf().csrfTokenRepository(csrfTokenRepository()).and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class) 
      .formLogin().loginProcessingUrl("/login") 
      .successHandler(successHandler()) 
      .failureHandler(failureHandler()) 
      .and() 
      .exceptionHandling() 
      .and() 
      .csrf().disable(); 
    } 

    private AuthenticationSuccessHandler successHandler() { 
     return new AuthenticationSuccessHandler() { 

      @Override 
      public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { 
       httpServletResponse.getWriter().append("OK"); 
       httpServletResponse.setStatus(200); 
      } 
     }; 
    } 

    private AuthenticationFailureHandler failureHandler() { 
     return new AuthenticationFailureHandler() { 

      @Override 
      public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException { 
       httpServletResponse.getWriter().append("Authentication failure"); 
       httpServletResponse.setStatus(401); 
      } 
     }; 
    } 

    private AccessDeniedHandler accessDeniedHandler() { 
     return new AccessDeniedHandler() { 

      @Override 
      public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException { 
       httpServletResponse.getWriter().append("Access denied"); 
       httpServletResponse.setStatus(403); 
      } 
     }; 
    } 

    private AuthenticationEntryPoint authenticationEntryPoint() { 
     return new AuthenticationEntryPoint() { 

      @Override 
      public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException { 
       httpServletResponse.getWriter().append("Not authenticated"); 
       httpServletResponse.setStatus(401); 
      } 
     }; 
    } 

    private Filter csrfHeaderFilter() { 
     return new OncePerRequestFilter() { 

      @Override 
      protected void doFilterInternal(HttpServletRequest request, 
             HttpServletResponse response, FilterChain filterChain) 
       throws ServletException, IOException { 
        CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName()); 
        if (csrf != null) { 
         Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN"); 
         String token = csrf.getToken(); 
         if (cookie == null || token != null 
         && !token.equals(cookie.getValue())) { 
          cookie = new Cookie("XSRF-TOKEN", token); 
          cookie.setPath("/"); 
          response.addCookie(cookie); 
         } 
        } 
       response.setHeader("Access-Control-Allow-Origin", "*"); 
       response.setHeader("Access-Control-Allow-Headers", "*"); 
       response.setHeader("Access-Control-Allow-Credentials", "*"); 
       response.setHeader("Access-Control-Allow-Methods", "*"); 
       response.setHeader("Access-Control-Max-Age", "3600"); 
       filterChain.doFilter(request, response); 
      } 
     }; 
    } 

    private CsrfTokenRepository csrfTokenRepository() { 
     HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository(); 
     repository.setHeaderName("X-XSRF-TOKEN"); 
     repository.setSessionAttributeName("_csrf"); 
     return repository; 
    } 

我的打字稿POST

onLogin(loginData: {username: string, password: string}) { 
    let headers = new Headers(); 
    headers.append('Access-Control-Allow-Credentials', 'true'); 
    headers.append('Content-Type','application/x-www-form-urlencoded'); 
    headers.append("Authorization", "Basic " + btoa(loginData.username + ":" + loginData.password)); 


    let body = { 
     username: loginData.username, 
     password: loginData.password 
    } 
    this.http.post('http://localhost:5000/login', body, {headers: headers, withCredentials: true}) 
     .map(res => res.json()) 
     .subscribe(data => { 
      console.log(data); 
      console.log(data.status) 
     }); 
    } 
} 

错误我与上面的代码的东西,我知道这是不是因为相同的用户名&密码登录详细信息通过招摇即使在POST中完美工作。

ionic error

回答

2

这是我如何解决这个问题。

onLogin(loginData: {username: string, password: string}) { 
    let headers = new Headers(); 
    headers.append('Access-Control-Allow-Credentials', 'true'); 
    headers.append('Content-Type','application/x-www-form-urlencoded'); 

    let body = `username=${loginData.username}&password=${loginData.password}`; 

    this.http.post('http://localhost:5000/login', body, {headers: headers}) 

    .map(res => res) 
    .subscribe(data => { 
     console.log(data.status); 
     if (data.status == 200) { 
     this.navCtrl.push(TabsPage); 
     } 
     else { 
     this.showError("Invalid username or password"); 
     } 

    }); 
} 

更新: 主要问题是URL-encoding这一行:

let body = `username=${loginData.username}&password=${loginData.password}`; 

由于dur

+0

你能解释一下你做了什么,在这里解决问题。 –

+1

由于内容类型是'应用程序/ x-WWW的形式urlencoded'我需要URL编码所述主体(基本上转换特殊字符为十六进制例如。一个空间变得%20)看http://www.albionresearch.com /misc/urlencode.php更多信息 – Kai

+1

啊所以'$ {......}'确实编码魔术,得到了它。 –