Spring Security Not Allowing Static Content - spring

I have been fighting with Spring Security for the past few days so I hope someone can help me out here.
I am using Spring Boot 1.2.5
I was using Spring Actuator and Spring Remote Shell, those have since been removed from the classpath thinking they may be causing issues
I excluded SecurityAutoConfiguration on the off chance it was causing my issues
Here is my main class
#SpringBootApplication(exclude = {org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class})
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Here is my security configuration
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private AuthFailureHandler authFailureHandler;
#Autowired
private AuthSuccessHandler authSuccessHandler;
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/css/**")
.antMatchers("/js/**")
.antMatchers("/images/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.exceptionHandling()
.authenticationEntryPoint(new Http403ForbiddenEntryPoint())
.accessDeniedPage("/403")
.and()
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/about").permitAll()
.antMatchers("/login").permitAll()
.anyRequest().fullyAuthenticated()
.and()
.formLogin()
.usernameParameter("sec-user")
.passwordParameter("sec-password")
.loginPage("/login")
.failureHandler(authFailureHandler)
.successHandler(authSuccessHandler)
.permitAll()
.and()
.logout()
.deleteCookies("JESSIONID")
.invalidateHttpSession(true)
.permitAll();
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());
}
#Bean
#Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
}
My questions / issues are
CSS, JavaScript, Images, basically no static content will load, and I can't seem to figure out why
What makes things even more interesting, instead of getting a 403 error which is what I would expect, it redirects to the Login page? I don't want that, it should return 403 is they don't have access.
I am calling my static resources from Thymeleaf like so
<link rel="stylesheet" media="screen" th:href="#{/css/main.css}" />
My static resources were working fine before adding security.
My static files are in resources/public/.
This is fine acording to Spring Boot docs
By default Spring Boot will serve static content from a folder called /static (or /public or /resources or /META-INF/resources) in the classpath or from the root of the ServletContext.

Try adding a resource handler.
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**")
.addResourceLocations("classpath:/css/**");
registry.addResourceHandler("/img/**")
.addResourceLocations("classpath:/img/**");
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
}

Related

Spring boot (v2.6.7) security with JWT, web.ignoring() is working but not antMatchers permitAll()

I migrated Spring boot from 2.1.5 to 2.6.7. Now the security configuration is throwing a warning about antMatchers in web.ignoring in the WebSecurity configuration lines, although it works correctly. Upon moving the web.ignoring to antMatchers permitAll() in httpConfiguration, the warning goes away but the urls are no longer permitted.
I am also using JWT and it looks like the JWT filters are kicking in and not honoring the httpConfiguration. I am really confused as to how to configure this. I am including the before and after here.
WORKS WITH WARNING:
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(SecurityConfiguration.class);
#Override
public void init(WebSecurity web) throws Exception {
super.init(web);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
LOGGER.debug("**********************SECURITY INITALIZE NORMAL#######################################");
http.cors().and().csrf().disable().authorizeRequests()
.anyRequest().authenticated().and()
.addFilter(new JWTAuthorizationFilter(authenticationManager(), getApplicationContext()))
.addFilter(new JWTAuthenticationFilter(authenticationManager(), getApplicationContext()))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/v2/api-docs/**");
}
}
DOES NOT WORK:
#EnableWebSecurity
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(SecurityConfiguration.class);
#Override
public void init(WebSecurity web) throws Exception {
super.init(web);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
LOGGER.debug("**********************SECURITY INITALIZE NORMAL#######################################");
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers("/v2/api-docs/**").permitAll() // ADDED LINE
.anyRequest().authenticated().and()
.addFilter(new JWTAuthorizationFilter(authenticationManager(), getApplicationContext()))
.addFilter(new JWTAuthenticationFilter(authenticationManager(), getApplicationContext()))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
#Override
public void configure(WebSecurity web) throws Exception {
//web.ignoring().antMatchers("/v2/api-docs/**");
}
}
Looks like somehow the configuration breaks when using http security versus web security. I have tried many of the suggestions but nothing seems to work.
Can someone familiar with Spring Boot Security in 2.6.7 with JWT filters please suggest what I am doing wrong?

spring security | security config permitall not working

#EnableWebSecurity
public class WebSecurityConfig implements WebMvcConfigurer {
#Bean
public UserDetailsService userDetailsService() throws Exception {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withDefaultPasswordEncoder().username("user").password("user").roles("USER").build());
return manager;
}
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().antMatchers("/css/**").permitAll()
.anyRequest().authenticated();
}
}
Above code is not working, url: localhost:8080/css/styles.css is redirecting to login page.
The code layout is, src/main/resources/static folder has html, css and js folders inside of which files remain.
Thanks in advance.
I think addResourceHandlers method can help you.
public class WebSecurityConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
}
}
it means find your resources in your static folder.
Not sure if this will work, but currently in my project, this is my config. and it's working properly.
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(HttpMethod.GET, "/js/**", "/css/*", "/images/**")
.permitAll()
.anyRequest()
.authenticated();
}

spring-boot project with spring-security do not access views

I start a new project based on spring-boot, using this working configuration class for spring-security from another project:
#Configuration
#ComponentScan
#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private PasswordEncoder passwordEncoder;
#Autowired
private PermissionEvaluator permissionEvaluator;
#Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/signin")
.loginProcessingUrl("/login").permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/");
}
#Override
public void configure(WebSecurity web) throws Exception {
DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler();
handler.setPermissionEvaluator(permissionEvaluator);
web.expressionHandler(handler);
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder);
}
}
when I deploy the project in the tomcat server, without errors, and try access the application, instead of the index page, I get a popup windows asking me for username and password.
the full code for the project is: https://github.com/klebermo/basic_webapp
anyone can see what's wrong with this configuration?
add this to your application.properties file:
security.basic.enabled=false
By default everything is secured with HTTP Basic authentication.
Ref: http://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/autoconfigure/security/SpringBootWebSecurityConfiguration.html

Authorization roles Spring-boot Oauth2 ~ Restful API

i'm needing help with this problem...
i can't secure my controllers in my security configuration files. but i can do it in my controller using
#PreAuthorize("hasAuthority('ROLE_ADMIN')")
but this is really annoying, i want to do it from my security conf. files
this is my WebSecurityconfigurerAdapter:
#Configuration
//#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(prePostEnabled = false)
//#Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
//#EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
CustomAuthenticationProvider customAuthenticationProvider;
#Autowired
CustomUserDetailsService cuds;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(cuds)
.passwordEncoder(passwordEncoder())
.and()
.authenticationProvider(customAuthenticationProvider);
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/**").authenticated()
.antMatchers("/test").authenticated()
.antMatchers("/usuarios/**").hasRole("ADMIN");
}
}
and this is my Oauth2Configuration:
#Configuration
public class Oauth2Configuration {
private static final String RESOURCE_ID = "restservice";
#Configuration
#EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Autowired
private CustomLogoutSuccessHandler customLogoutSuccessHandler;
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources
.resourceId(RESOURCE_ID);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
// Logout
.logout()
.logoutUrl("/oauth/logout")
.logoutSuccessHandler(customLogoutSuccessHandler)
.and()
//Session management
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
//URI's to verify
.authorizeRequests()
.antMatchers("/oauth/logout").permitAll()
.antMatchers("/**").authenticated()
.antMatchers("/usuarios/**").hasRole("ADMIN");
}
}
i've tried to use authority and roles, but nothings works. some idea what i'm doing wrong?
Well thanks to Yannic Klem i got the answer, was a problem with the order
First on my WebSecurityConfigurerAdapter i set my authentication on "usuarios"
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/usuarios").authenticated();
}
after that in my Oauth2Configuration set my authorizarion with my rol.
#Override
public void configure(HttpSecurity http) throws Exception {
http
// Logout
.logout()
.logoutUrl("/oauth/logout")
.logoutSuccessHandler(customLogoutSuccessHandler)
.and()
//Session management
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
//URI's to verify
.authorizeRequests()
.antMatchers("/oauth/logout").permitAll()
.antMatchers("/usuarios/**").hasRole("ADMIN");
}
and now all works pretty fine. thank you all!

Spring boot: Securing api endpoint with oauth2 while having mvc UI pages

I'm trying to get a spring-boot mvc application working with standard login while exposing some API endpoints with oAuth2 security.
Basically my requirements are as follows:
If a user hits the home page ("/") check if it's authenticated.
If not show the login form, else show the home page.
But a user should also be able to ask for an oauth authentication token and with that token acces /api/assignment/{id}.
I can get the standard login to work, and I can get the oauth2 to work but I can not get them to work together.
This is my configuration at the moment:
WebSecurityConfig
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private DataSource dataSource;
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(this.dataSource).passwordEncoder(new BCryptPasswordEncoder());
}
}
OAuth2Config
#Configuration
#EnableResourceServer
#EnableAuthorizationServer
public class OAuth2Config {
protected static final String RESOURCE_ID = "oauthdemo";
#Configuration
#EnableResourceServer
protected static class ResourceServer extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.authorizeRequests()
.antMatchers("/js/**", "/css/**", "/images/**", "/webjars/**", "/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID);
}
}
#Configuration
#EnableAuthorizationServer
protected static class AuthServer extends AuthorizationServerConfigurerAdapter {
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.allowFormAuthenticationForClients();
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("client")
.authorizedGrantTypes("password", "refresh_token")
.authorities("ROLE_USER")
.scopes("read")
.resourceIds(RESOURCE_ID)
.secret("secret").accessTokenValiditySeconds(3600);
}
}
}
The problem is I always get the following error when trying to open the home page ("/")
<oauth>
<error_description>
Full authentication is required to access this resource
</error_description>
<error>unauthorized</error>
</oauth>
It does not redirect to the login page.
I do not need this page to be protected by oauth2, but even if i go directly to the login page ("/login", which i can access) and supply credentials I still get the 'full authentication is required' error.
Even though i disabled basic http authentication.
Does anyone know how to separate the normal user UI from the api endpoints that need to be protected by OAuth2?
Can you try this
http
.authorizeRequests()
.antMatchers("/js/**", "/css/**", "/images/**", "/webjars/**", "/login").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/home").authenticated();
Considering /home is a page that needs to be authorized.
Hi you have to specify filters used for each config in your case you need:
in web security configurtion
http
.authorizeRequests()
.antMatchers("/api/**","/oauth/**")
.permitAll()
.and()
.......
this will let web security bypass authorization/resource servers URLs
and in resource server security configuration
http
.antMatcher("/api/**")
.authorizeRequests()
.anyRequest()
.authenticated();
this will let resource security bypass all URLs except "/api/**".
in this way you can ignore orders of configuration there is another option by make one of above actions and put its configuration in early order using #Order

Resources