I have configured the allowed origins for CORS in the Spring yml configuration as follows.
endpoints:
cors:
allowed-origins: http://client.local
allow-credentials: true
But it wasn't applied until I added a Java configuration as follows
#Configuration
#EnableWebMvc
public class WebConfiguration extends WebMvcConfigurerAdapter {
#Value("${endpoints.cors.allowed-origins}")
private String allowedOrigins;
#Value("${endpoints.cors.allow-credentials}")
private boolean allowCredentials;
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins(allowedOrigins)
.allowCredentials(allowCredentials);
}
}
I want to keep the yml configuration and discard the Java configuration, why is the yml config not applied?
I know, it might be too late, but I'll try...
Have you added spring-boot-starter-actuator to your dependencies?
Instead of using custom properties use endpoints provided by Spring Boot.
Ex:
management.endpoints.web.cors.allowed-origins=http://domain:port
Spring Boot Application.properties configuration
Related
How to do the same that I pointed using Spring Boot (+Security)? Implementation of WebMvcConfigurer interface resets a lots settings, which were performed by Spring BOOT did automatically. For example, setting in application.properties "spring.mvc.hiddenmethod.filter.enabled=true" stopped to work. Question in that how to setting a binding of multiple ResourceHandler:ResourceLocation pairs without configuring the extra.
I don't know how to make things right.
#Configuration
#EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**")
.addResourceLocations("classpath:/static/assets/css/");
registry.addResourceHandler("/images/**")
.addResourceLocations("classpath:/static/assets/images/");
registry.addResourceHandler("/js/**")
.addResourceLocations("classpath:/static/assets/js/");
registry.addResourceHandler("/person-storage/**")
.addResourceLocations("classpath:/storage/person-images/");
}
}
I tried to use settings in application.properties for spring boot. I tried to create #Bean of "addResourceHandler" to I won't implement interface WebMvcConfigurer fully.
My spring application start's via WebApplicationInitializer.
public class WebAppInitializer implements WebApplicationInitializer
{
#Override
public void onStartup(ServletContext servletContext) throws ServletException
{
....
}
}
I have Config class
#Configuration
#PropertySources({
#PropertySource(value = "classpath:application.properties"))
})
public class MainConfig
{
....
}
And in application.properties file I try to override the spring and logging properties
logging.level.com.app=DEBUG
logging.level.org.springframework.web=DEBUG
The file application.properties is in the directory src/main/resources
But it has no effect - means that no property is applied to the spring or logging system
Try using SpringBoot. In spring boot application.properties is read by default and you don't even need to use #PropertySource to read it. You can download a spring boot application skeleton from https://start.spring.io/
I am trying to load the required parameters like accessURI,client_id, client_secret from properties file like below. It never loads the properties, I see many sites mention this as example. It is working if I tries to set it explicitly.
In this example
https://dzone.com/articles/build-a-spring-boot-app-with-secure-server-to-serv
#Bean()
#ConfigurationProperties(prefix ="my.oauth2.client")
protected ClientCredentialsResourceDetails oAuthDetails() {
return ClientCredentialsResourceDetails();
But it never loaded the properties so I need to change to use set methods.I am not able to figure out why it did not load, I believe I cannot mention this in #EnableConfigurationProperties as it does not have the configuration configured.
I tried searching but could not find a matching reason.
Basically, the binding of properties to class members works as described in the example.
The properties have to be present either as YAML or properties file:
spring:
security:
oauth2:
client:
registration:
oauth:
client-id: XXXXXX
client-secret: YYYYYYY
scope: openid
redirect-uri: http://redirect
access-token-uri: https://token
client-authentication-method: basic
authorization-grant-type: client_credentials
Then the #ConfigurationProperties annotation has to be declared with the correct prefix. In this example it is "spring.security.oauth2.client.registration.oauth".
#Bean
#ConfigurationProperties(prefix ="spring.security.oauth2.client.registration.oauth")
protected ClientCredentialsResourceDetails oAuthDetails() {
return new ClientCredentialsResourceDetails();
}
As stated in the Spring Boot documentation you normally do not have to set the #EnableConfigurationProperties annotation unless you are developing your own auto-configuration.
But if you are working on a non Spring Boot project the #EnableConfigurationProperties annotation has to be declared, describing the class where we want to use the #ConfigurationProperties annotation:
#Configuration()
#EnableConfigurationProperties(MyProperties.class)
public class MyConfig {
}
with
#ConfigurationProperties(prefix="myproperties")
public class MyProperties {
}
Alternatively you can also use configuration property scanning which works similarly to the component scanning by declaring the #ConfigurationPropertiesScan annotation:
#SpringBootApplication
#ConfigurationPropertiesScan({ "my.app" })
public class MyApplication {
}
Hope, this helps. Pero
In spring boot 1.x it was possible to resolve all actuator endpoints programatically. I have a bean that exposes all actuator endpoints paths
#Component
public class MyProjectActuatorEndpoints {
#Autowired
private MvcEndpoints endpoints;
public String[] getActuatorEndpointPaths() {
return endpoints.getEndpoints().stream()
.map(MvcEndpoint::getPath)
.map(path -> path + "/**")
.toArray(String[]::new);
}
}
Unfortunately in spring boot actuator 2.0.5.RELEASE there is no such class MvcEndpoints. Is there any replacement for this class in the new spring version?
Everything you need is in the org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints bean. This should set you on the right path, if you'll pardon the pun:
#Slf4j
#Component
public class ActuatorLogger {
public ActuatorLogger(#Autowired PathMappedEndpoints pme) {
log.info("Actuator base path: {}", pme.getBasePath());
pme.getAllPaths().forEach(p -> log.info("Path: {}", p));
}
}
org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest is available to help you set spring security rules for actuator endpoints when you need to do it from code. For example, in your WebSecurityConfigurerAdapter implementation, this fragment could be merged in to your existing rules:
http.authorizeRequests()
.requestMatchers(EndpointRequest.to(ShutdownEndpoint.class))
.hasAnyAuthority("ROLE_ADMIN", "ROLE_SUPPORT")
#Autowired
private HealthEndpoint healthEndpoint;
public Health getAlive() {
return healthEndpoint.health();
}
Spring Boot Actuator 2.x exposes /actuator endpoints as configurable environment variables.
Enabling Acutator Endpoints
You can enable these actuator endpoints in your application.properties
management.endpoints.web.exposure.include=info, health
or (with extreme caution) enable them all. Keep in mind that many of these are sensitive in nature.
management.endpoints.web.exposure.include=*
Securing Actuator Endpoints (reference)
The documentation specifies this as a strategy to secure all endpoints. The EndpointRequest itself would be the closest alternative to what you were looking for (MvcEndpoints)
#Configuration
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests()
.anyRequest().hasRole("ENDPOINT_ADMIN")
.and()
.httpBasic();
}
}
You may also set up a particular antmatcher in case you have a different strategy or role that you would like to assign just to these endpoints
httpRequest.authorizeRequests().antMatcher("/actuator/*").hasRole("ENDPOINT_ADMIN")
The application uses JDK 8, Spring Boot & Spring Boot Jersey starter and is packaged as a WAR (although it is locally run via Spring Boot Maven plugin).
What I would like to do is to get the documentation I generate on the fly (at build time) as a welcome page.
I tried several approaches:
letting Jersey serving the static contents by configuring in application.properties the proper init parameter as described here
introduce a metadata-complete=false web.xml in order to list the generated HTML document as a welcome-file.
None of that worked out.
I would like to avoid having to enable Spring MVC or creating a Jersey resource just for serving a static file.
Any idea?
Here is the Jersey configuration class (I unsuccessfully tried to add a ServletProperties.FILTER_STATIC_CONTENT_REGEX there):
#ApplicationPath("/")
#ExposedApplication
#Component
public class ResourceConfiguration extends ResourceConfig {
public ResourceConfiguration() {
packages("xxx.api");
packages("xxx.config");
property(ServerProperties.BV_DISABLE_VALIDATE_ON_EXECUTABLE_OVERRIDE_CHECK, true);
property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true);
}
}
And here is Spring Boot application class (I tried adding an application.properties with spring.jersey.init.jersey.config.servlet.filter.staticContentRegex=/.*html but it didn't work, I'm not exactly sure what the property key should be here):
#SpringBootApplication
#ComponentScan
#Import(DataConfiguration.class)
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Let me just first state, that the reason the static content won't be served is because of the default servlet mapping of the Jersey servlet, which is /*, and hogs up all the requests. So the default servlet that serves the static content can't be reached. Beside the below solution, the other solution is to simply change the servlet mapping. You can do that by either annotating your ResourceConfig subclass with #ApplicationPath("/another-mapping") or set the application.properties property spring.jersey.applicationPath.
In regards to your first approach, take a look at the Jersey ServletProperties. The property you are trying to configure is FILTER_STATIC_CONTENT_REGEX. It states:
The property is only applicable when Jersey servlet container is configured to run as a Filter, otherwise this property will be ignored
Spring Boot by default configures the Jersey servlet container as a Servlet (as mentioned here):
By default Jersey will be set up as a Servlet in a #Bean of type ServletRegistrationBean named jerseyServletRegistration. You can disable or override that bean by creating one of your own with the same name. You can also use a Filter instead of a Servlet by setting spring.jersey.type=filter (in which case the #Bean to replace or override is jerseyFilterRegistration).
So just set the property spring.jersey.type=filter in your application.properties, and it should work. I've tested this.
And FYI, whether configured as Servlet Filter or a Servlet, as far as Jersey is concerned, the functionality is the same.
As an aside, rather then using the FILTER_STATIC_CONTENT_REGEX, where you need to set up some complex regex to handle all static files, you can use the FILTER_FORWARD_ON_404. This is actually what I used to test. I just set it up in my ResourceConfig
#Component
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
packages("...");
property(ServletProperties.FILTER_FORWARD_ON_404, true);
}
}
For anyone who still can't get this to work, I followed the answer provided by #peeskillet, and had to make an additional change.
Previously I had created the following method in Application.java.
#Bean
public ServletRegistrationBean jerseyServlet() {
ServletRegistrationBean registration = new ServletRegistrationBean(new ServletContainer(), "/*");
registration.addInitParameter(ServletProperties.JAXRS_APPLICATION_CLASS, JerseyConfig.class.getName());
return registration;
}
The problem is that this registered the servlet for the /* path, and then setup the Jersey ResourceConfig configuration file.
Once I removed the above method, and placed the #Configuration annotation on my ResourceConfig class, I noticed the static resource could be retrieved via Spring Boot.
For completeness, this is a snippet of my ResourceConfig now.
#Configuration
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
// Application specific settings
property(ServletProperties.FILTER_FORWARD_ON_404, true);
}
}
This blog post was helpful in determining the difference approach for the ResourceConfig.
Below setup worked for me
Set
spring .jersey.type: filter
set FILTER_FORWARD_ON_404
#Configuration
public class MyResourceConfig extends ResourceConfig {
public MyResourceConfig () {
try {
register(XXX.class);
property(ServletProperties.FILTER_FORWARD_ON_404, true);
} catch (Exception e) {
LOGGER.error("Exception: ", e);
}
}
}
Note: Use #Configuration instead of #component