I have a spring boot web server which uses the httpWebSecurityAdapter.
I am trying to display some web pages (HTML CSS, javascript) in a div in my Angular app.
X-frame does not allow me to do it if enabled.
I would like to disable the x-frame options only for a certain type of request.
Right now I have it disabled for everything. I would like to do only for a certain URL.
http.headers().frameOptions().disable()
You will need to provide multiple WebSecurityConfigurerAdapter configurations. In other words, multiple security configurations for each of your url patterns.
Here's a sample configuration:
#Configuration
#EnableWebSecurity
public class SecurityConfig {
// #Order is to specify which WebSecurityConfigurerAdapter should be considered first. This configuration has the highest priority.
// This configuration is activated for url pattern: /home/**
#Order(1)
#Configuration
public static class DefaultSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/home/**")
.authorizeRequests()
.anyRequest().authenticated()
.and().formLogin()
.and().httpBasic();
}
}
// This configuration is considered after DefaultSecurityConfiguration since it has #Order(2).
// This configuration is activated for url pattern: /registerUser/**
#Order(2)
#Configuration
public static class DisabledFrameOptionsSecurityConfigurer extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/registerUser/**")
.authorizeRequests()
.anyRequest().permitAll();
http.headers().frameOptions().sameOrigin();
}
}
}
Related
I have several controllers and want to secure only one of them,
spend some time but haven't figure out proper solution.
How to do it via config ?
Controllers :
#RestController
#RequestMapping("/somepath")
public class UnsecController {
// code here
}
#Secured("ROLE_CUSTOM")
#RestController
#RequestMapping("/somepath2")
public class SecController {
// code here
}
Config:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/js/**", "/css/**", "/fonts/**", "/static", "/swagger-ui.html");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.antMatcher("/**")
.addFilterBefore(authFilter(), BasicAuthenticationFilter.class)
.authorizeRequests()
.antMatchers("/health").permitAll()
.anyRequest().authenticated()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
#Bean
public MacaroonsAuthFilter authFilter() {
return new MacaroonsAuthFilter();
}
}
Edit:
I have 50 controllers from 100 that I want to secure,
but dont want to write them in configuration manually
Controllers are secured by configuring theWebSecurityConfigurerAdapter. If you only want to secure one controller-method, you need to configure the HttpSecurity in that way, that it only matches this path. All other methods are excluded from security. Something as follows:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/somepath").hasRole("CUSTOM")
.anyRequest().permitAll();
}
The #Secured annotation is normally used on service methods and not in the controller.
Using Spring Boot 1.5.2.RELEASE and Java 8
I'm trying to understand, what goes in public void configure(HttpSecurity http) method of WebSecurityConfigurerAdapter and of ResourceServerConfigurerAdapter?
With the following code, configure(HttpSecurity http) method of ResourceServerConfigurerAdapter is taking precedence over WebSecurityConfigurerAdapter. All the changes I'm doing in ResourceServerConfiguration is taking effect, it appears that WebSecurityConfigurerAdapteris ignored completely.
When we use these methods (use case)? And, is override of WebSecurityConfigurerAdapter.configure(..) method even required for grant type password
Using security.oauth2.resource.filter-order = 3
Without this property I keep getting 403 Access Denied
The default order of the OAuth2 resource filter has changed from 3 to SecurityProperties.ACCESS_OVERRIDE_ORDER - 1
WebSecurityConfiguration
#Configuration
#EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/unsecured").permitAll()
.antMatchers("/users").hasRole("USER")
.antMatchers("/api/secured").hasRole("ADMIN")
.antMatchers("/api/admin").authenticated()
.antMatchers("/greeting").authenticated();
}
}
Resource Server
#Configuration
#EnableResourceServer
protected static class ResourceServerConfiguration extends
ResourceServerConfigurerAdapter {
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.anyRequest().permitAll();
}
}
I think you have the answer here, please check out the solution given
Spring Security OAuth2, which decides security?
I am looking for a non invasive way to add a captcha filter for certain api calls.
My setup consists of two WebSecurityConfigurerAdapters with one filter each (not the captcha filter):
Internal api ("/iapi" use Filter A on all calls but also ignore some public requests like /authenticate)
External api ("/eapi" use Filter B on all calls)
How can I add a filter before the Spring Security stuff, on public, internal api or external api calls? I don't need the SecurityContext, just need to check for a Captcha in the request headers, forward to filterChain (normal filters) or manually deny access. I tried declaring a filter in web.xml, but that breaks the ability to use dependency injection.
Here is my Spring Security Configuration:
#EnableWebSecurity
public class SpringSecurityConfig {
#Configuration
#Order(1)
#EnableGlobalMethodSecurity(securedEnabled = true)
public static class InternalApiConfigurerAdapter extends WebSecurityConfigurerAdapter {
#Autowired
private Filter filterA;
public InternalApiConfigurerAdapter() {
super(true);
}
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/public/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/iapi/**")
.exceptionHandling().and()
.anonymous().and()
.servletApi().and()
.authorizeRequests()
.anyRequest().authenticated().and()
.addFilterBefore(filterA, (Class<? extends Filter>) UsernamePasswordAuthenticationFilter.class);
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return authenticationManager();
}
}
#Configuration
#Order(2)
#EnableGlobalMethodSecurity(securedEnabled = true)
public static class ExternalApiConfigurerAdapter extends WebSecurityConfigurerAdapter {
#Autowired
private FilterB filterB;
public ExternalApiConfigurerAdapter() {
super(true);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/external/**")
.exceptionHandling().and()
.anonymous().and()
.servletApi().and()
.authorizeRequests()
.anyRequest().authenticated().and()
.addFilterBefore(filterB, (Class<? extends Filter>) UsernamePasswordAuthenticationFilter.class);
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return authenticationManager();
}
}
Update: At the moment I have a working configuration with a filter declared in web.xml. However, it has the drawback of being seperated from the Spring Context (e.g. no autowiring of beans), so I am looking for a better solution leveraging Spring.
Summary: There are two remaining problems:
add a filter for specific urls only - using beforeFilter(...) inside any configuration adds a filter to all urls of that configuration. Antmatchers didn't work. I need something like that: /iapi/captcha/, /external/captcha/, /public/captcha/*.
I have a public api which bypasses Spring Security completely: (web
.ignoring()
.antMatchers("/public/**");). I need to bypass Spring Security but still declare a filter there, using Spring autowiring but not necessarily Spring Security features, since my captcha filter only rejects or forwards calls in a stateless way.
You already have a working configuration with filters A and B inserted before UsernamePasswordAuthenticationFilter so should be easy to add another custom filter.
First, you create the filter, and declare it as a bean, either annotating the class with #Component, or as a #Bean inside a #Configuration class, so it is ready to be injected with #Autowired.
Now you are able to inject it, as filter A and B, and use it. According to the Filter Ordering section in the Spring Security reference documentation, the very first Filter in the chain is ChannelProcessingFilter, so in order to insert the filter before anything else in the Spring Security filter chain, you'd do this:
#Autowired
private CaptchaFilter captchaFilter;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/iapi/**")
.addFilterBefore(captchaFilter, (Class<? extends Filter>) ChannelProcessingFilter.class)
.addFilterBefore(filterA, (Class<? extends Filter>) UsernamePasswordAuthenticationFilter.class)
.authorizeRequests()
.anyRequest().authenticated();
}
By the way, exceptionHandling() anonymous() and servletApi() aren't needed because when extending WebSecurityConfigurerAdapter, these are already included, except for anonymous() when you actually specify more configuration details, as it states HttpSecurity javadoc
Keep in mind that the Spring Security "entrypoint", the DelegatingFilterProxy still will be executed before your filter, but this component only delegates the request to the first filter in the chain, which in this case would be the CaptchaFilter, so you really would execute your filter before anything else from Spring Security.
But if you still want the captcha filter be executed before the DelegatingFilterProxy, there is no way to do so in the Spring Security configuration, and you need to declare it in the web.xml file.
Update: If you do not desire to include the captcha filter in the other configurations, you can always add a third configuration, and the configurations class would be as follows:
#EnableWebSecurity
#EnableGlobalMethodSecurity(securedEnabled = true)
public class SpringSecurityConfig {
#Configuration
#Order(1)
public static class CaptchaApiConfigurerAdatper extends WebSecurityConfigurerAdapter {
#Autowired
private CaptchaFilter captchaFilter;
public CaptchaApiConfigurerAdatper() {
super(true);
}
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/public/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatchers()
.antMatcher("/iapi/captcha**")
.antMatcher("/external/captcha**")
.and()
.addFilterBefore(captchaFilter, (Class<? extends Filter>) ChannelProcessingFilter.class)
.authorizeRequests()
.anyRequest().authenticated();
}
}
#Configuration
#Order(2)
public static class InternalApiConfigurerAdapter extends WebSecurityConfigurerAdapter {
// ommiting code for the sake of clarity
}
#Configuration
#Order(3)
public static class ExternalApiConfigurerAdapter extends WebSecurityConfigurerAdapter {
// ommiting code for the sake of clarity
}
By the way, another tip, you can refactor all the common configuration outside the specific configurations, into the main class, like #EnableGlobalMethodSecurity(securedEnabled = true) the AuthenticationManager, the WebSecurity to skip security for the public, but for those since the main class is not extending anything you should #Autowire the method declarations.
Although there would be one problem with the WebSecurity, if you are ignoring /public/** the matcher for the HttpSecurity with /public/captcha** would be ignored, so i guess, you shouldnt refactor out the WebSecurity and have a different pattern in the CaptchaConfig class so it doesnt overlap.
With spring-cloud Angel.SR3 release I followed example in https://github.com/spring-cloud-samples/sso and things work fine with spring-boot 1.2.6.RELEASE.
However with spring-boot 1.3.0.RC1, the oauth2 stuff has moved into spring-boot itself, and the code below fails to compile because class OAuth2SsoConfigurerAdapter no longer exists.
What is the spring-boot only way to create equivalent configuration?
public static void main(String[] args) {
SpringApplication.run(MainAppApplication.class, args);
}
...
#Component
public static class LoginConfigurer extends OAuth2SsoConfigurerAdapter {
#Override
public void match(RequestMatchers matchers) {
matchers.antMatchers("/dashboard/**");
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.antMatcher("/dashboard/**").authorizeRequests().anyRequest()
.authenticated().and().csrf()
.csrfTokenRepository(csrfTokenRepository()).and()
.addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
}
private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
...
};
}
...
}
You just have to use org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter and carefully use this annotation org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso
I've written carefully because its behaviour depends on where you add it. As stated in the javadoc:
Enable OAuth2 Single Sign On (SSO). If there is an existing WebSecurityConfigurerAdapter provided by the user and annotated with #EnableOAuth2Sso, it is enhanced by adding an authentication filter and an authentication entry point. If the user only has #EnableOAuth2Sso but not on a WebSecurityConfigurerAdapter then one is added with all paths secured and with an order that puts it ahead of the default HTTP Basic security chain in Spring Boot.
Hope that helps!
Turns out not special adapter needed, just the regular WebSecurityConfigurerAdapter does the trick. You cannot tell the code from below if oauth2 SSO is involved, more transparent, sort to speak.
#Configuration
#Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter {
#Autowired
private SecurityProperties security;
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http
.authorizeRequests()
.antMatchers("/", "/ssologout").permitAll()
.anyRequest().fullyAuthenticated()
.and()
.formLogin()
.loginPage("/login").failureUrl("/login?error")
.permitAll()
.and()
.logout().permitAll();
// #formatter:on
}
}
I am trying to setup a single path (/basic) in my spring-boot spring MVC based application to be basic auth protected. I am just going to configure this using my own custom configuration parameters so the username and password are simply "admin" and "admin".
This currently works for the /basic path (I am prompted and can login correctly). The problem is that logout does not work (and I am not sure why) and also other paths (like /other shown) are being asked for basic auth credentials (before always being denied).
static class MyApplicationSecurity extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/open").permitAll();
http.authorizeRequests().antMatchers("/other").denyAll(); // Block it for now
http.authorizeRequests().antMatchers("/basic").authenticated().and().httpBasic().and().logout().logoutUrl("/basic/logout").invalidateHttpSession(true).logoutSuccessUrl("/");
}
}
I expected /other to always be denied but I don't get why basic auth is coming up for it. /open works as expected. I also don't understand why /basic/logout does not log me out (it also does not produce error messages). I do have a simple bit of code as a placeholder for the logout endpoint but if I do not have that then I get a 404. The "home" view is my web app root so I just want to send the user there after logout.
#RequestMapping("/logout")
public ModelAndView logout() {
// should be handled by spring security
return new ModelAndView("home");
}
UPDATE:
Here is the solution that seemed to work in the end (except the logout part, still not working):
#Configuration
#Order(1) // HIGHEST
public static class OAuthSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/oauth").authorizeRequests().anyRequest().denyAll();
}
}
#Configuration
public static class BasicAuthConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/basic").authorizeRequests().anyRequest().authenticated().and().httpBasic();
http.logout().permitAll().logoutUrl("/logout").logoutSuccessUrl("/").invalidateHttpSession(true);
//.and().logout().logoutUrl("/basic/logout").invalidateHttpSession(true).logoutSuccessUrl("/");
}
}
i'm not sure about the logout, but we had a similar problem with having some of our site under basic and some of it not. Our solution was to use a second nested configuration class only for the paths that needed http basic. We gave this config an #Order(1)..but i'm not sure if that was necessary or not.
Updated with code
#Configuration
#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
private static final Logger LOG = LoggerFactory.getLogger(SecurityConfig.class);
#Autowired
public void registerAuthentication(AuthenticationManagerBuilder auth, Config appConfig) throws Exception {
auth.inMemoryAuthentication()
.withUser(appConfig.getString(APIConfig.CONFIG_KEY_MANAGEMENT_USER_NAME))
.password(appConfig.getString(APIConfig.CONFIG_KEY_MANAGEMENT_USER_PASS))
.roles(HyperAPIRoles.DEFAULT, HyperAPIRoles.ADMIN);
}
/**
* Following Multiple HttpSecurity approach:
* http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#multiple-httpsecurity
*/
#Configuration
#Order(1)
public static class ManagerEndpointsSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/management/**").authorizeRequests().anyRequest().hasRole(HyperAPIRoles.ADMIN).and()
.httpBasic();
}
}
/**
* Following Multiple HttpSecurity approach:
* http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#multiple-httpsecurity
*/
#Configuration
public static class ResourceEndpointsSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
//fyi: This adds it to the spring security proxy filter chain
.addFilterBefore(createBBAuthenticationFilter(), BasicAuthenticationFilter.class)
;
}
}
}
this seems to secure the actuator endpoints at /management with basic auth while the others work with a custom auth token header. We do not prompt for credentials (no challenge issued) though for anything..we'd have to register some other stuff to get that going (if we wanted it).
Hope this helps
only one path will be protected
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception
{
auth.inMemoryAuthentication()
.withUser("user").password(passwordEncoder().encode("user"))
.roles("USER");
}
#Configuration
#Order(1)
public static class ManagerEndpointsSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/add/**").authenticated()
.anyRequest().permitAll()
.and()
.httpBasic()
.and().csrf().disable();
}
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}