I'd trying to activate basic authentication with password hash encryption.
#Configuration //gets picked up automatically by spring-boot
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(details).passwordEncoder(new BCryptPasswordEncoder());
}
}
I want the authentication only being active in production. So I'm trying to deactivate it in general at first, use:
security.basic.enabled=false
Result: the application is still secured. I'm presented with the username/password screen.
But how could I then disable the need for authentication?
Solved with ConditionalOnProperty:
#Configuration
#ConditionalOnProperty("security.basic.enabled")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
}
To do different things in different environments you should use Spring Profiles
Suppose you need security configuration bean only in production environment, then you should mark it to be loaded conditionally when a specific profile is enabled.
#Configuration //gets picked up automatically by spring-boot
#Profile("Production")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(details).passwordEncoder(new BCryptPasswordEncoder());
}
}
Profile specific configuration is done in properties files named application-{profile}.properties and bootstrap-{profile}.properties files.
Now since security configuration bean is marked with profile Production it will be loaded only when Production profile is enabled.
To enable a profile you have to set following property.
#One or more profiles can be active simultaneously
spring.profiles.active=Production,Dev,Local
This property can either be edited in the common properties file application.properties (Always loaded unlike profile specific properties files like application-Production.properties which are conditionally loaded) or it can provided as a environment variable as below.
On Windows
set SPRING_PROFILES_ACTIVE=Production
On Unix
export SPRING_PROFILES_ACTIVE=Production
It can be done using a million other ways that spring supports to load properties. For a list of all the methods go through this link https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
Finally to disable default Spring security (Basic) Autoconfiguration, you can use following properties.
security.basic.enabled=false
management.security.enabled=false #For actuator
Above should be in the profile specific properties files where you wish to disable Spring Security auto configuration.
To disable spring-security autoconfiguration entirely use the following property
spring.autoconfigure.exclude[0]=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration
Related
I am trying to implement Spring basic auth into the app. I added the folowing lines to application.properties:
#Security
security:
user:
name: admin
password: admin
So the Spring will create a web security config bean by itself. But I ran some tests and everything works as expected for any method besides POST as it throws 403 status. I browsed the web and discovered that it happens due to csrf protection and I disabled it, creating additional web security config class:
#EnableWebSecurity
public class WebSecurityConfig {
#Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable();
return http.build();
}
}
However, it completely disables the authentication. The user does not need a password and a login to use the resources.
My question is, how do I configure the authentication in a way POST method will not throw 403? Do I need to write a full web security config and delete those 4 lines from application.properties or there is an alternative way? Thanks in advance.
I have a spring boot library module and I want to enable logging into a file.
What I did was to add logging settings in module-conf.properties, but no file is created.
module-conf.properties
logging.file.name=test.log
I also created a configuration bean:
#Configuration
#ComponentScan("...")
#EnableJpaRepositories("...")
#PropertySource("classpath:module-conf.properties")
public class ModuleConfiguration {
#Autowired
private Environment environment;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUrl(environment.getProperty("spring.datasource.url"));
dataSource.setUsername(environment.getProperty("spring.datasource.username"));
dataSource.setPassword(environment.getProperty("spring.datasource.password"));
return dataSource;
}
Do I have to configure the logging system the same way I configure the datasource ?
Is there a way avoid manual configuration?
This is interesting!
It appears logging is initialized before the ApplicationContext is created.... and the #PropertySources is read after ApplicationContext is created. As per the documentation, you can override the config by updating one of the config file based on your logging system(Spring's default is logback)
Reference: https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-custom-log-configuration
Problem:
Since logging is initialized before the ApplicationContext is created,
it is not possible to control logging from #PropertySources in Spring
#Configuration files. The only way to change the logging system or
disable it entirely is via System properties.
The recommendation:
When possible, we recommend that you use the -spring variants for
your logging configuration (for example, logback-spring.xml rather
than logback.xml). If you use standard configuration locations, Spring
cannot completely control log initialization.
I have a 'legacy' application build with Vaadin 8 that I need to secure with Keycloak.
Unfortunately, the redirect to Keycloak is not even triggered.
As a test, I created a Spring Boot application and tried to secure it with Keycloak without any problems, but it fails to work with Vaadin 8.
My configuration files for the Spring Boot application are;
application.properties
keycloak.realm=myrealm
keycloak.resource=test-app
keycloak.auth-server-url=http://localhost:8080/auth
keycloak.ssl-required=external
keycloak.public-client=true
keycloak.securityConstraints[0].authRoles[0]=Patient
keycloak.securityConstraints[0].authRoles[1]=Admin
keycloak.securityConstraints[0].securityCollections[0].name=boeken
keycloak.securityConstraints[0].securityCollections[0].patterns[0]=/books
keycloak.securityConstraints[1].authRoles[0]=Admin
keycloak.securityConstraints[1].securityCollections[0].name=backend
keycloak.securityConstraints[1].securityCollections[0].patterns[0]=/manager
server.port=8090
KeycloakConfig class
#Configuration
public class KeycloakConfig {
#Bean
public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
}
Just by adding this, the Keycoal-redirect is triggered and I can log in. Easy.
What should I change/add when i'm trying to secure the Vaadin 8 application?
It's not a Spring/Spring boot-application (not started by SpringApplication.run()), I don't think it's mandatory to have a Spring/Spring boot app in order to secure it with Keycloak (correct me if i'm wrong).
The problem seems to be that the application.properties file is ignored (although it is on the class path), as I can navigate to the urls that should be secured.
Does anyone see what's missing/wrong?
In case you would consider using Spring boot, I created a working example of integration between Vaadin 8, Spring Boot and Keycloak.
It makes use of vaadin-spring-boot, keycloak-spring-boot-adapter and keycloak-spring-security-adapter plugins to get jump started and your application.properties will get picked up correctly. In essence, this setup tells Vaadin to let Spring Security handle all security, and in turn Keycloak is hooked up as the security handler.
The only configuration needed is to have a custom SecurityConfiguration to define your specific security needs.
But the bulk comes down to:
#Configuration
#EnableWebSecurity
#EnableVaadinSharedSecurity
#EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, proxyTargetClass = true)
public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
...
#Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().disable();
http.formLogin().disable();
// disable spring security csrf as Vaadin already provides this
// also possible to disable this in Vaadin and leave this enabled
http.csrf().disable();
http
.authorizeRequests()
.antMatchers("/vaadinServlet/UIDL/**").permitAll()
.antMatchers("/vaadinServlet/HEARTBEAT/**").permitAll()
.anyRequest().authenticated();
http
.logout()
.addLogoutHandler(keycloakLogoutHandler())
.logoutUrl("/sso/logout").permitAll()
.logoutSuccessUrl("/");
http
.addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class)
.addFilterBefore(keycloakAuthenticationProcessingFilter(), BasicAuthenticationFilter.class);
http
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint());
http
.sessionManagement()
.sessionAuthenticationStrategy(sessionAuthenticationStrategy());
}
...
}
I recently implemented a Spring Cloud Config Server. My application (client) is able to retrieve application profiles and refresh them in flight.
Unfortunately, CORS settings, which are also declared there, are not reloaded by Spring during runtime. I did a small investigation and check that in terms of refresh everything looks good - ConfigurationPropertiesRebinder rebind() method successfully destroys old bean holding CORS setup and creates a new with up-to-date settings. I also see that Environment bean is holding new settings in propertySources field.
Is there any way to force Spring to reload CORS during runtime or should I need to reload application context?
Use below code for resolve CORS issue.
#Configuration
#EnableWebMvc
class WebConfig implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
I have migrated a Spring Boot web application from 1.5.10 to 2.0.0, which is deployed with Heroku and runs over several domains. For the main domain, that was the first one to be set, everything is working smoothly but for the rest any of the static resources; like Javascript, CSS, images and icons (Webjars) are not accessible.
maindomain.com/js/example.js works fine and can be directly accessed with the browser. secondarydomain.com/js/example.js can't be accessed by the browser and running the app arises this error, I guess because instead of the .js file is returning some text message:
Refused to execute script from '' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled
The static resources are located at:
/resources/static/css
/resources/static/js
/resources/static/images
I have set the Spring security configuration with an extension of WebSecurityConfigurerAdapter, where I have withdrawn the annotation #EnableWebSecurity and I have added this code, with the intention to make sure that those resources are accessible, without success:
http
.authorizeRequests()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
There is a HandleInterceptor, which deals with the directories accessible by each secondary domain. The main one, has access all over the application.
In this other question, with a different approach to the same problem, there is an extract of the HandleInterceptor.
Spring Boot 2.0.0 & static resources with different domains for the same app
Spring Security with boot is on the classpath, the auto-configuration secures all endpoints by default.
However, when it comes to complex applications, we need different security policies per endpoints. We also need to configure which endpoints should be secured, what type of users should be able to access the endpoints, and which endpoints should be public.
WebSecurity allow we to configure adding RequestMatcher instances that Spring Security should ignore.
HttpSecurity allow we can configure the endpoints that should be secured and the endpoint that should be public
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/resources/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/css/**", "/js/**", "/image/**"").permitAll()
}
}
Hope it help.