Issue
I have created a client angular on webstorm and I have a Spring Boot server on Eclipse. The problem is when I try to open the session i get this error message:
OPTIONS http://localhost:8080/allquestions 401 ()
(anonymous) @ angular.js:12410
p @ angular.js:12155
(anonymous) @ angular.js:11908
(anonymous) @ angular.js:16648
$eval @ angular.js:17972
$digest @ angular.js:17786
$apply @ angular.js:18080
(anonymous) @ angular.js:19924
f @ angular.js:6111
(anonymous) @ angular.js:6390
XMLHttpRequest cannot load http://localhost:8080/allquestions. Response for preflight has invalid HTTP status code 401
The WebConfig
@EnableWebMvc
@Configuration
@ComponentScan
public class WebConfig extends WebMvcConfigurerAdapter {
public WebConfig() {
super();
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.addViewController("/").setViewName("welcome");
registry.addViewController("/welcome").setViewName("welcome");
registry.addViewController("/exam").setViewName("exam");
registry.addViewController("/report").setViewName("report");
registry.addViewController("/error").setViewName("error");
registry.addViewController("/editing").setViewName("editing");
}
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
registry.addResourceHandler("/images/**").addResourceLocations("/images/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
}
A part of the Controller :
@RestController
public class HomeController {
@Autowired
private BusinessModel businessModel;
private List<String> messages;
private User currentUser;
@PostConstruct
public void init() {
messages = businessModel.getMessages();
}
// Communicate informations to client
private void sendOptions(HttpServletResponse response) {
if (businessModel.getCorsNeeded().booleanValue()) {
// Fix the header CORS
response.addHeader("Access-Control-Allow-Origin", "*");
// Header Authorization
response.addHeader("Access-Control-Allow-Headers", "Authorization");
}
}
// questions list via OPTIONS
@RequestMapping(value = "/allquestions", method = RequestMethod.OPTIONS)
public void getAllQuestions(HttpServletResponse response) {
sendOptions(response);
}
The SecurityConfig :
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UsersService usersService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic();
http.authorizeRequests().antMatchers("/login").permitAll().antMatchers("/**").hasRole("USER").and().formLogin()
.loginPage("/login").and().logout();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(usersService).passwordEncoder(new BCryptPasswordEncoder());
}
}
I can't add xml file (restriction of my work context)...
I am totally blocked and I need your help!
Solution
The solution for everyone !
You create a filter who can make the sort :
public class CorsFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filter)
throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Access-Control-Allow-Origin", "*");
httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
httpResponse.setHeader("Access-Control-Max-Age", "3600");
httpResponse.setHeader("Access-Control-Allow-Headers", "Authorization");
filter.doFilter(request, response);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
You can see, the filter create for you all the headers. And the most wanted : httpResponse.setHeader("Access-Control-Allow-Origin", ""*).
Then, you can call the filter in the SecurityConfig :
@EnableAutoConfiguration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UsersService usersService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(new CorsFilter(), ChannelProcessingFilter.class);
http.csrf().disable();
http.httpBasic();
http.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/", "/**").permitAll();
http.authorizeRequests().antMatchers(HttpMethod.GET, "/", "/**").permitAll();
//http.authorizeRequests().antMatchers("/login").permitAll().antMatchers("/**").hasRole("USER").and().formLogin().loginPage("/login").and().logout();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(usersService).passwordEncoder(new BCryptPasswordEncoder());
}
}
There, you can see the filter is call before the request properly : http.addFilterBefore(new CorsFilter(), ChannelProcessingFilter.class).
This is the best solution I found and the only works for me ! I hope, it can help you !
Answered By - ReNaR
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.