0

当我试图从AngularJS的用户进行身份验证,我看到这个警告在春季启动日志:415不支持的媒体类型与AngularJS和Spring 1.4.3引导

[WARN ] 2017-02-04 17:09:20.085 [http-nio-8080-exec-1] DefaultHandlerExceptionResolver - Resolved exception caused by Handler execution: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'null' not supported 

和浏览器响应:

415不支持的媒体类型

LoginController

@RestController 
// @RequestMapping("/") 
public class LoginController { 

    public Logger logger = LoggerFactory.getLogger(this.getClass()); 

    @RequestMapping(value = "/login", method = RequestMethod.GET, 
     consumes = MediaType.APPLICATION_JSON_VALUE 
     /*produces = MediaType.APPLICATION_JSON_VALUE*/) 
    public ResponseEntity<Admin> login(@RequestBody UserDTO user, BindingResult result, WebRequest request) { 
     logger.info("********** Inside login of LoginController **************"); 

     Admin authenticatedUser = (Admin) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 
     HttpStatus httpStatus = null; 
     if (authenticatedUser == null) { 
      httpStatus = HttpStatus.NOT_FOUND; 
     } else { 
      httpStatus = HttpStatus.OK; 
     } 
     return new ResponseEntity<Admin>(authenticatedUser, httpStatus); 
    } 
} 

我AngularJS代码:

service.login = function(user, successHandler, errorHandler) { 

// Obtain a CSRF token 
loginResources.options().$promise.then(function (response) { 
    console.log('Obtained a CSRF token in a cookie', response); 

    // Extract the CSRF token 
    var csrfToken = Cookies.getFromDocument($http.defaults.xsrfCookieName); 
    console.log('Extracted the CSRF token from the cookie', csrfToken); 

    // Prepare the headers 
    var headers = { 
    'Content-Type': 'application/json' 
    }; 
    headers[$http.defaults.xsrfHeaderName] = csrfToken; 
    console.log("Before calling /login, user : ", user); 
    // Post the credentials for logging in 
    $http.get(ApiBasePath + '/login', user, {headers: headers}) 
    .success(successHandler) 
    .error(function (data, status, headers, config) { 

     if (isCSRFTokenInvalidOrMissing(data, status)) { 
     console.error('The obtained CSRF token was either missing or invalid. Have you turned on your cookies?'); 

     } else { 
     // Nope, the error is due to something else. Run the error handler... 
     errorHandler(data, status, headers, config); 
     } 
    }); 

}).catch(function(response) { 
    console.error('Could not contact the server... is it online? Are we?', response); 
}); 

}; //登录功能结束

我有一个完全相同的AngularJS完全相同注册控制器注册功能(具有不同的端点当然) ,但是完美的作品。

虽然我怀疑一件事,但当我使用Spring Security时,是否真的需要LoginController与端点/login或者安全配置会照顾到这一点?我的安全配置:

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
     .authorizeRequests() 
      .antMatchers(HttpMethod.OPTIONS, "/*/**").permitAll() 
      .antMatchers("/login").permitAll() 
      .antMatchers("/register").permitAll() 
      .antMatchers("/", "/**/*.css", "/**/**/*,css", 
       "/**/*.js", "/**/**/*.js").permitAll() 
      .antMatchers("/dashboard", "/dasboard/**", "/logout").authenticated(); 

    // Handlers and entry points 
    http 
     .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint); 
    http 
     .formLogin() 
      .successHandler(authenticationSuccessHandler); 
    http 
     .formLogin() 
      .failureHandler(authenticationFailureHandler); 

    // Logout 
    http 
     .logout() 
      .logoutUrl("/logout") 
      .logoutSuccessHandler(logoutSuccessHandler); 

    // CORS 
    http 
     .addFilterBefore(corsFilter, ChannelProcessingFilter.class); 

    // CSRF 
    http 
     .csrf().requireCsrfProtectionMatcher(
       new AndRequestMatcher(
        // Apply CSRF protection to all paths that do NOT match the ones below 
        new NegatedRequestMatcher(new AntPathRequestMatcher("/", HttpMethod.OPTIONS.toString())), 
        new NegatedRequestMatcher(new AntPathRequestMatcher("/", HttpMethod.GET.toString())), 
        new NegatedRequestMatcher(new AntPathRequestMatcher("/", HttpMethod.POST.toString())), 
        new NegatedRequestMatcher(new AntPathRequestMatcher("/", HttpMethod.HEAD.toString())), 
        new NegatedRequestMatcher(new AntPathRequestMatcher("/", HttpMethod.TRACE.toString())), 

        new NegatedRequestMatcher(new AntPathRequestMatcher("/css/**", HttpMethod.GET.toString())), 
        new NegatedRequestMatcher(new AntPathRequestMatcher("/js/**", HttpMethod.GET.toString())), 
        new NegatedRequestMatcher(new AntPathRequestMatcher("/js/**/**", HttpMethod.GET.toString())), 
        // We disable CSRF at login/logout, but only for OPTIONS methods 
        new NegatedRequestMatcher(new AntPathRequestMatcher("/login*/**", HttpMethod.OPTIONS.toString())), 
        new NegatedRequestMatcher(new AntPathRequestMatcher("/logout*/**", HttpMethod.OPTIONS.toString())), 

        //Disable CSRF at register for all methods 
        new NegatedRequestMatcher(new AntPathRequestMatcher("/register*/**", HttpMethod.OPTIONS.toString())) 
       ) 
      ); 
    http 
     .addFilterAfter(new CsrfTokenResponseCookieBindingFilter(), CsrfFilter.class); // CSRF tokens handling 
} 

@Autowired 
public void configure(AuthenticationManagerBuilder auth) throws Exception { 
    auth.userDetailsService(userDetailsService); 
    auth.authenticationProvider(authProvider()); 
} 

@Bean 
public DaoAuthenticationProvider authProvider() { 
    final DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); 
    authProvider.setUserDetailsService(userDetailsService); 
    authProvider.setPasswordEncoder(encoder()); 
    return authProvider; 
} 

@Bean 
public PasswordEncoder encoder() { 
    return new BCryptPasswordEncoder(11); 
} 
+0

取消注释并没有什么区别。 –

+0

但是在哪里检查?我认为,对“/ login”的调用由SecurityConfig类处理,而不是由LoginController处理。 另外,你有没有想过:“我怀疑一件事,当我使用Spring Security时,是否真的需要带端点/登录的LoginController,否则安全配置会照顾到它? @dur –

+0

难道这是一个解决方案:[link] http://stackoverflow.com/questions/11492325/post-json-fails-with-415-unsupported-media-type-spring-3-mvc[/link] ?我会尝试一下。 –

回答

0

最后我得到了答案。确实如果我尝试发送json对象而不是请求参数,我必须使用Custom UserNamePasswordAuthenticationFilter。这也是事实,我必须使用POST。

感谢@dur指出。

最后,非常感谢this post。没有这篇文章,我不可能知道如何自定义过滤器。

相关问题