415不支持的媒体类型与AngularJS和Spring 1.4.3引导
问题描述:
当我试图从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);
}
答
最后我得到了答案。确实如果我尝试发送json对象而不是请求参数,我必须使用Custom UserNamePasswordAuthenticationFilter。这也是事实,我必须使用POST。
感谢@dur指出。
最后,非常感谢this post。没有这篇文章,我不可能知道如何自定义过滤器。
取消注释并没有什么区别。 –
但是在哪里检查?我认为,对“/ login”的调用由SecurityConfig类处理,而不是由LoginController处理。 另外,你有没有想过:“我怀疑一件事,当我使用Spring Security时,是否真的需要带端点/登录的LoginController,否则安全配置会照顾到它? @dur –
难道这是一个解决方案:[link] http://*.com/questions/11492325/post-json-fails-with-415-unsupported-media-type-spring-3-mvc[/link] ?我会尝试一下。 –