spring boot is ignoring web.xml - spring

I try to make spring boot to load stuff from web.xml and so far it is ignoring definitions from there...
I have bellow starter:
#Configuration
#EnableAutoConfiguration
#ComponentScan
#SpringBootApplication
#ImportResource(value = {"classpath:/*-beans.xml"})
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
I see in logs that spring beans are initialized but no definitions are loaded from web.xml...

Related

How to add scanBasePackages in SpringBootServletInitializer & SpringApplicationBuilder?

Following is used for my spring project
#SpringBootApplication(scanBasePackages = "com.tv")
public class WWWAbacusApplication {
public static void main(String[] args) {
SpringApplication.run(WWWAbacusApplication.class, args);
}
}
I need to deploy it in widlfly so i do it like below
public class ServletInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(WWWAbacusApplication.class);
}
}
but i never required scanbasepackages but in this application i required it.
Can anyone suggest how to do it in SpringBootServletInitializer

Spring Security OAuth2: multiple ResourceServerConfiguration not working

Spring boot version: 1.5.8.RELEASE
Spring cloud version: Edgware.RELEASE (using zuul)
Trying to configure multiple resources and, following this example in github, can't make it work.
My code is:
class ResourceServerConfigurationFactory
{
static ResourceServerConfiguration criarResourceServerConfiguration(String resourceId, int order,
HttpSecurityConfigurer configurer)
{
ResourceServerConfiguration resource = new ResourceServerConfiguration()
{
// Switch off the Spring Boot #Autowired configurers
public void setConfigurers(List<ResourceServerConfigurer> configurers)
{
super.setConfigurers(configurers);
}
};
resource.setConfigurers(Arrays.<ResourceServerConfigurer>asList(new ResourceServerConfigurerAdapter()
{
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception
{
resources.resourceId(resourceId);
}
#Override
public void configure(HttpSecurity http) throws Exception
{
configurer.configure(http);
}
}));
resource.setOrder(order);
return resource;
}
}
interface HttpSecurityConfigurer
{
public void configure(HttpSecurity http) throws Exception;
}
And my configuration:
#Configuration
public class OAuthResourceConfiguration
{
#Bean
protected ResourceServerConfiguration usuarioResources()
{
return ResourceServerConfigurationFactory.criarResourceServerConfiguration("usuario", -10,
http -> http.antMatcher("/user").authorizeRequests().anyRequest().permitAll());
}
#Bean
protected ResourceServerConfiguration funcaoResources()
{
return ResourceServerConfigurationFactory.criarResourceServerConfiguration("funcao", -20,
http -> http.antMatcher("/ws").authorizeRequests().anyRequest().permitAll());
}
}
Finally, the Spring boot application:
#SpringBootApplication
#EnableResourceServer
#EnableZuulProxy
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}
Facts:
Spring instantiates both ResourceServerConfiguration beans;
Only the bean with higher order works (/user endpoint is ok, /ws endpoint keeps asking authentication)
In spring log, I can see that only /user ant matcher is used. /ws gets completely ignored.
What's wrong?
The problem was related to the Factory class I created.
The combination of lambda + anonymous class created some kind of problem (that I was not able to understand) that screwed up things.
Declaring both Configurers as Beans in the #Configuration class resolved the problem.

How to exclude a URL when usinf PCF SSO service with EnableOAuth2Sso annotation?

I am using Angular and Spring Boot to build a Single Page app with Rest API. Here is my configuration:
#SpringBootApplication
#EnableOAuth2Sso
public class AppConfig extends SpringBootServletInitializer implements ApplicationContextAware {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AppConfig.class);
}
public static void main(String[] args) {
ApplicationContext appContext = SpringApplication.run(AppConfig.class);
context = appContext;
}
#Configuration
protected static class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/healthcheck", "/").permitAll()
.antMatchers("/api/**").authenticated()
.anyRequest().authenticated();
}
}
}
The SSO service I am using is provided by Pivotal Cloud Foundry[PCF]. Everything was fine before I included
SecurityConfig
class. As soon as the app is loaded, user is redirected to the SSO login page and then redirected back to the app. But I need to exclude the "healthcheck" URL from authentication. That is why I included the SecurityConfig class. But now the SSO Authentication is not working at all. I could only reach /healthcheck.
I followed this example https://spring.io/guides/tutorials/spring-boot-oauth2/
Can someone please let me know what is wrong with my code?
Thanks.
I figured it out. I had to move my EnableOAuth2Sso to the WebSecurityConfigurerAdapter. Like this:
#SpringBootApplication
public class AppConfig extends SpringBootServletInitializer implements ApplicationContextAware {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AppConfig.class);
}
public static void main(String[] args) {
ApplicationContext appContext = SpringApplication.run(AppConfig.class);
context = appContext;
}
#Configuration
#EnableOAuth2Sso
protected static class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/healthcheck", "/").permitAll()
.antMatchers("/api/**").authenticated()
.anyRequest().authenticated();
}
}
}

Where is SpringBootServletInitializer's DispatcherServlet?

How SpringBootServletInitializer determines RootConfig.class, WebConfig.class, and maps DispatcherSevlet?
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
return application.sources(Application.class); - loads the Application.class. That's your main configuration, where you can declare #Beans. You can add more #Configuration classes by putting them in the same folder, for example, and they will be "component-scanned".
If you declare a #Configuration class that extends WebMvcConfigurerAdapter, you have an access to the web configuration like resource handlers, argument resolvers, etc.
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/public-resources/")
.setCacheControl(CacheControl.maxAge(1, TimeUnit.HOURS).cachePublic());
}
#Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new FooBarHandlerMethodArgumentResolver());
}
}
By default the dispatcher servlet is configured to the root path "/"
If you need more details, see the auto configuration.

Global method security in Spring Boot

I'm having some issues when trying to enable the global method security in a Spring Boot application.
More or less I've this configuration:
#ComponentScan
#Configuration
#EnableAutoConfiguration
#EnableConfigurationProperties
public class Main extends SpringBootServletInitializer {
public static void main(String[] args) throws Exception {
SpringApplication app = new SpringApplication(Main.class);
app.setShowBanner(false);
ApplicationContext context = app.run(args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Main.class);
}
}
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(securedEnabled = true, proxyTargetClass = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
...
}
#Override
protected void configure(HttpSecurity http) throws Exception {
...
}
}
#Controller
public class SampleController {
#RequestMapping("/api/hello")
#ResponseBody
String hello() {
return "Hello!";
}
#Secured(SecurityGrant.WRITE_PROJECT)
#RequestMapping("/api/bye")
#ResponseBody
String bye() {
return "Bye!";
}
}
The #Secure annotations are working OK at services, but not in controllers, so as I read here (http://docs.spring.io/spring-security/site/faq/faq.html#faq-method-security-in-web-context) I think is because method security is only configured in the root application context and not in the one for the servlet.
However, I can't find the way to set this via Java Configuration, instead of using a web.xml file.
Any ideas?
Update:
As pointed in the comments, methods should be public to be proxied.
The controller methods need to be public in order to be proxied for #Secured. Just doing that should fix it.
In XML you would have to define a second global-method-security in the servlet-context.xml file. This is because there are two contexts, the root context and the web context and security needs to be configured in each separately.
In Java config, try to create a separate web configuration class, and mark it with #EnableWebMvc:
#Configuration
#EnableWebMvc
#EnableGlobalMethodSecurity(securedEnabled = true, proxyTargetClass = true)
public class WebConfig {
...
}

Resources