How to disable CORS in Spring Security within Spring Boot? - java

I want to completely remove CORS from Spring Boot (2.3.3.RELEASE) with Spring Security.
There is WebSecurityConfigurerAdapter#configure method for HttpSecurity object where I can call cors().disable() but it seems not to work.
class MySecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().disable();
}
}
With just above snippet I still get CORS errors while accessing endpoints from my frontend application.
Instead of that I have to override addCorsMappings from WebMvcConfigurer interface like below 👇.
Why is that? Why it is not enough to call http.cors().disable()?
class MySecurityConfiguration extends WebSecurityConfigurerAdapter implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("*")
.allowedOrigins("*");
}

Hi you need to create a global cors configuration in your spring boot project.Create a class and annotate it with #Configuration. You can follow this example below.
#Configuration
public class MyConfiguration {
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://domain2.com")
.allowedMethods("PUT", "DELETE")
.allowedHeaders("header1", "header2", "header3")
.exposedHeaders("header1", "header2")
.allowCredentials(false).maxAge(3600);
}
};
}
}
Here is the full guide that spring framework provides https://spring.io/blog/2015/06/08/cors-support-in-spring-framework

Related

Spring isn't loading CSS and gives a 404 when the page is loaded

I'm running a Spring (not Boot) web app and it's finding my JSP views properly, but my CSS isn't being found for some reason. To be clear, the page is loading with the necessary elements, but any CSS styling from classes in my .css files is not being applied. The structure for the CSS file I'm trying to use is src/main/resources/css/style.css.
Below is the relevant code for my AppConfig class:
public class AppConfig implements WebMvcConfigurer {
...
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**")
.addResourceLocations("/css/");
}
...
}
And the JSP header:
<link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"/>
I've already checked some other questions asking after this issue and have had no luck. Several of them advised checking the config file for Spring Security to ensure that permission is granted for all requests using the resource file but based on what I can see, it shouldn't be prohibiting the CSS from being loaded:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserService userService;
#Bean
public BCryptPasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setPasswordEncoder(encoder());
authenticationProvider.setUserDetailsService(userService);
return authenticationProvider;
}
}
For a non-Spring Boot project your css folder should be not in src/main/resources but in src/main/webapp.
You need to tell spring security to ignore css files by overriding this method in WebSecurityConfigurerAdapter:
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**","/vendor/**","/fonts/**").anyRequest();
}
The configuration that you posted in your question:
public class AppConfig implements WebMvcConfigurer {
...
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**")
.addResourceLocations("/css/");
}
...
}
tells Spring MVC to serve /css/style.css from the css directory in your context directory. If it doesn't exist, you get a 404.
If you want to serve the file from the classpath (which is what your question seems to imply), then you should do this instead:
public class AppConfig implements WebMvcConfigurer {
...
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**")
.addResourceLocations("classpath:/resources/css/");
}
...
}
See the documentation of ResourceHandlerRegistry for more details.

How to make viewController ignore server.servlet.context-path

I have the following configuration for serving static content from Spring Boot.
#Configuration
public class WebConfig implements WebMvcConfigurer {
#Value("${frontend.location}")
private String frontendLocation;
#Override
public void addViewControllers(ViewControllerRegistry reg) {
reg.addViewController("/").setViewName("forward:/index.html");
reg.addViewController("/{x:[\\w\\-]+}").setViewName("forward:/index.html");
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations(frontendLocation);
}
}
This works fine as long as there is no server.servlet.context-path. When server.servlet.context-path is configured, it is being passed down to the frontend router as part of the URL.
The solution would be not to forward context path to index.html. How can I achieve that?

Injected Spring Bean is NULL in Spring Boot Application

I am using Spring Boot(1.5.3) to develop a REST Web Service. In order to take some action on incoming request I have added an interceptor shown below.
#Component
public class RequestInterceptor extends HandlerInterceptorAdapter {
#Autowired
RequestParser requestParser;
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//HandlerMethod handlerMethod = (HandlerMethod) handler;
requestParser.parse(request);
return true;
}
}
RequestInterceptor has an autowired Spring Bean RequestParser responsible for parsing the request.
#Component
public class RequestParserDefault implements RequestParser {
#Override
public void parse(HttpServletRequest request) {
System.out.println("Parsing incomeing request");
}
}
Interceptor registration
#Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new RequestInterceptor()).addPathPatterns("/usermanagement/v1/**");
}
}
And my Spring Boot Application
#SpringBootApplication
public class SpringBootApp {
public static void main(String[] args) {
SpringApplication.run(SpringBootApp.class, args);
}
}
Now when a request comes in, it lands in preHandle method of RequestInterceptor but RequestParser is NULL. If I remove the #Component annotation from RequestParser I get an error during Spring context initialization No bean found of type RequestParser. That means RequestParser is registered as Spring bean in Spring context but why it is NULL at the time of injection? Any suggestions?
Your problem lies in this new RequestInterceptor().
Rewrite your WebMvcConfig to inject it, e.g. like this:
#Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
#Autowired
private RequestInterceptor requestInterceptor;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(requestInterceptor)
.addPathPatterns("/usermanagement/v1/**");
}
}

Spring Boot OAuth2 with custom security filter

I have a spring boot setup with an OAuth2 authorization and resource server. The user is able to acquire tokens by making a POST request to /oauth/token. So far, so good.
However, I don't want to protect /oauth/token via BASIC auth but by means of a custom security filter.
I tried the following but DemoAuthenticationFilter is never called:
#Configuration
#EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
// ...
#Override
public void configure(HttpSecurity http) throws Exception {
// ...
http.addFilterBefore(new DemoAuthenticationFilter(), BasicAuthenticationFilter.class);
http.authorizeRequests().antMatchers("/oauth/token").authenticated();
}
}
Also, if I try to add it to WebSecurityConfigurerAdapter the filter is only called after the request is authenticated via OAuth2:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
// ...
#Override
protected void configure(HttpSecurity http) throws Exception {
// ...
http.addFilterBefore(new DemoAuthenticationFilter(), BasicAuthenticationFilter.class);
http.authorizeRequests().antMatchers("/oauth/token").authenticated();
}
}
Some simple example how to achieve this would be really helpful. Thank you!
#Configuration
#EnableAuthorizationServer
public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdapter {
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.allowFormAuthenticationForClients().addTokenEndpointAuthenticationFilter(new AligenieFilter());
}
//....
}
It works for me.

Java config for spring interceptor where interceptor is using autowired spring beans

I want to add spring mvc interceptor as part of Java config. I already have a xml based config for this but I am trying to move to a Java config. For interceptors, I know that it can be done like this from the spring documentation-
#EnableWebMvc
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LocaleInterceptor());
}
}
But my interceptor is using a spring bean autowired into it like follows-
public class LocaleInterceptor extends HandlerInterceptorAdaptor {
#Autowired
ISomeService someService;
...
}
The SomeService class looks like follows-
#Service
public class SomeService implements ISomeService {
...
}
I am using annotations like #Service for scanning the beans and have not specified them in the configuration class as #Bean
As my understanding, since java config uses new for creating the object, spring will not automatically inject the dependencies into it.
How can I add the interceptors like this as part of the java config?
Just do the following:
#EnableWebMvc
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
LocaleInterceptor localInterceptor() {
return new LocalInterceptor();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeInterceptor());
}
}
Of course LocaleInterceptor needs to be configured as a Spring bean somewhere (XML, Java Config or using annotations) in order for the relevant field of WebConfig to get injected.
The documentation for general customization of Spring's MVC configuration can be found here, and specifically for Interceptors see this section
When you handle the object creation for yourself like in:
registry.addInterceptor(new LocaleInterceptor());
there is no way the Spring container can manage that object for you and therefore make the necessary injection into your LocaleInterceptor.
Another way that could be more convenient for your situation, is to declare the managed #Bean in the #Configuration and use the method directly, like so:
#EnableWebMvc
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public LocaleInterceptor localeInterceptor() {
return new LocaleInterceptor();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor( localeInterceptor() );
}
}
Try to inject your service as a constructor parameter. It is simple.
#EnableWebMvc
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Autowired
ISomeService someService;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LocaleInterceptor(someService));
}
}
Then reconfigure your interceptor,
public class LocaleInterceptor extends HandlerInterceptorAdaptor {
private final ISomeService someService;
public LocaleInterceptor(ISomeService someService) {
this.someService = someService;
}
}
Cheers !

Categories