Spring Security:I can load static resources but not images - java

I tried all the suggestions from here but i could not make it work
spring boot security static resources
I have to specify that the image i am trying to add is on the log in page.
I am using maven to create a spring boot webapp with security and thymeleaf.
It seems that all my static resources load fine(css/jss)but the images do not.When i check the developer tools in chrome i get a 404 error for that said image in the console.no matter what path i am using i am geting the same error.I have permited access to all the static content here
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().antMatchers(HttpMethod.GET,"/resources/**" ,"/js/**", "/css/**", "/images/**" ,"/fonts/**", "/scss/**", "/index", "/", "/login").permitAll()
.and()
.authorizeRequests()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.defaultSuccessUrl("/home", true)
.and()
.logout()
.logoutSuccessUrl("/")
.logoutUrl("/signout");
}
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/**"); // #3
}}
this is how i access it in thymeleaf
<div class="col-lg-2 ml-auto" data-aos="fade-up" data-aos-delay="100">
<figure class="img-absolute">
<img th:src="#{/images/car.jpeg}" alt="Image" class="img-fluid">
</figure>
</div>
this is my folder structure
src->main->resources->static->images->car.jpeg
and this is the error i get in dev tools
GET http://localhost:8080/images/car.jpeg 404
any help would be greatly appreciated.

Use this approach to get the static images and other resources to load on your html page -
1.) Correct your folder structure for images, It should be -
your_project_name -> src -> main -> resources -> static -> assets -> img --> your images
NOTE - Add your other static files and folders inside assets folder.
2.) And your Security config class -
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// your code
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/assets/**");
}
}
3.) Use correct url on your html page to access the images -
//your code
<img th:src="#{/assets/img/car.jpeg}" alt="Image" class="img-fluid">

Related

Allow anonymous access to springdoc-openapi-ui with Spring Security

How to allow anonymous access to springdoc-openapi-ui (OpenAPI 3.0 /swagger-ui.html) in a Spring Boot application secured by Spring Security?
To use springdoc-openapi-ui /swagger-ui.html, allow anonymous access to the following endpoints in the WebSecurityConfigurerAdapter using permitAll method:
/v3/api-docs/**
/swagger-ui/**
/swagger-ui.html
Example:
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.
.authorizeRequests()
.antMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic(); //or anything else, e.g. .oauth2ResourceServer().jwt()
}
}
Make sure a project has the following dependencies:
org.springdoc:springdoc-openapi-ui
org.springdoc:springdoc-openapi-security
Additionally to Evgeniy's answer, I'd add the proper configuration to avoid conflicts with document fetching used in Swagger's UI (such js, html, images and other files), also in the SecurityConfig class like this:
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//Other configuration methods
#Override
public void configure(WebSecurity web) {
web.ignoring()
.antMatchers("/v3/api-docs/**", "/swagger-ui/**");
}
}
Without this configuration, even though the UI looks like It's loaded, a 401: Unauthorized may arise on the background calls when loading the above mentioned files.
For obtaining access in spring webflux you have to do the following, tested with spring-doc version 1.5.2:
The swagger webpage was failing on html resources with the path /webjars/swagger-ui.
#Configuration
#EnableWebFluxSecurity
public class SecurityConfig {
#Bean
SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
return http.authorizeExchange()
.pathMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html", "/webjars/swagger-ui/**")
.permitAll()
.anyExchange()
.authenticated()
.and()
.build();
}
}

Spring security default form login page failing when antmatcher defined

I am having an issue with Spring 5 form based authentication. This is only an example at this point as I am trying to isolate the issue I'm having. My plan is to include this configuration in a larger project with multiple configurations. The below code (which can be found anywhere) works as expected:
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
auth.inMemoryAuthentication()
.passwordEncoder(passwordEncoder)
.withUser("user").password(passwordEncoder.encode("password")).roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception
{
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.and().csrf().disable();
}
}
and following code does not work after adding antmatcher:
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
auth.inMemoryAuthentication()
.passwordEncoder(passwordEncoder)
.withUser("user").password(passwordEncoder.encode("password")).roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception
{
http.antMatcher("/test/**")
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.and().csrf().disable();
}
}
Notice that I've only added an antmatcher to this config. I only want the config to apply to /test/**. And, in this case, I'm not doing anything custom with regards to the form login and would like to get Spring default form. Of course in a real application I would not use the default but this is only for example purposes. My first config displays the default internal Spring form correctly when I GET the following URL: http://localhost:8080/webapp/test/anything. And I can authenticate successfully. For the second configuration I get 404 errors when issuing the same URL.
Spring security does in fact try to redirect to: http://localhost:8080/webapp/login however, the url does not exist. I did try the following change:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/test/**").authorizeRequests().anyRequest().authenticated()
.and().formLogin().permitAll().loginPage("/test/login").loginProcessingUrl("/test/login")
.and().logout().logoutUrl("/test/logout").invalidateHttpSession(true).logoutSuccessUrl("/");
}
This did not work either. I made several attempts, but have not been successful. Is it possible that the default form behavior is disabled when an antmatcher is defined?
This is ideal solution for your requirement
#Override
protected void configure(HttpSecurity http) throws Exception
{
http
.requestMatchers().antMatchers("/test/**", "/customLoginPage", "/logout").and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/customLoginPage") //If you don't configure default is "/login"
.usernameParameter("userName").passwordParameter("password") //In case of custom form parameters
.defaultSuccessUrl("/app/user/dashboard") //If you don't configure default is "/"
.failureUrl("/login?error=true") //If you don't configure default is "/login?error"
.and().csrf().disable();
}
Let me explain Some cases how spring security deals with
Case 1:
http.authorizeRequests()
is equals to
http.antMatcher("/**").authorizeRequests()
A proxy filter will be defined and url-pattern for that filter will be "/**". With this type of configuration there will be no problem as it is a wild card. But in some cases we don't want to define wild card "/**" then we should configure requestMatchers correctly otherwise we will end up in lot of unguessable problems.
Case 2:
http.antMatcher("/test/**").authorizeRequests()
Here proxy filter will be added with URL pattern "/test/**" and requests with /login and /logout can't pass through the added filter. To overcome this .requestMatchers() should be used as given below
http
.requestMatchers().antMatchers("/test/**", "/customLoginPage", "/logout")
.and().authorizeRequests()
This means filter with filter mapping as given below
<filter-mapping>
<filter-name>/test/**</filter-name>
<url-pattern>/customLoginPage</url-pattern>
<url-pattern>/logout</url-pattern>
</filter-mapping>
You can try out some of basic examples(Working) from my github repository
After many tries, the following is working for me. Only showing the configure method:
#Override
protected void configure(HttpSecurity http) throws Exception
{
http.antMatcher("/test/**")
.authorizeRequests()
.antMatchers("/test/login").permitAll()
.antMatchers("/test/logout").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login.jsp").permitAll()
.loginProcessingUrl("/test/login").permitAll()
.failureUrl("/login.jsp?error=yes")
.and()
.logout().permitAll().logoutUrl("/test/logout").permitAll()
.and().csrf().disable();
}
I did need to create my own login form (login.jsp), however the processing of the login form (the POST) is handled by Spring default processing. Really, that was the important piece. Another key point to make is that the login form POST needs to point to /webapp/test/login. I suppose that the Spring configuration needs these additional "tips" in order to trigger the default form processing in cases where the antMatcher call must be present.

Spring-Boot security - Resource folder doesn't work

I have a quick issue which am not really sure how to sort this out yet.
The issue is that, I'm using Thymeleaf, and was working perfectly fine until I've introduced the Springboot security. Since then, the styling isn't working at all. Looks like the static folder isn't seen for some reason. I've tried several structures to make it work but still no luck. I've tried to include in resource folder static folder, then resource folder (again) with no luck. I've also tried to rename the static into public, still no luck. I've noticed that if you include the URL somewhere on the web it works but if you include the URL somewhere on your local machine doesn't work. So I'm 100% sure there is a problem with the structure of the folders or the Spring configuration.
Any help, would be really much appreciated.
Spring security configuration class:
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.formLogin()
.loginPage("/login")
.usernameParameter("username")
.passwordParameter("password")
.failureUrl("/login?error")
.defaultSuccessUrl("/default")
.and()
.logout()
.logoutSuccessUrl("/")
.and()
.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/", "/static/**").permitAll()
.antMatchers("/createUser").hasRole("ADMIN")
.anyRequest().authenticated();
}
}
WebConfig class:
#Configuration
#EnableWebMvc
public class WebAppConfig {
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}

Serving static Resource with spring boot + spring security

I work on angularjs application and I try to serve static resource (my front end) with Spring boot.
I used gulp to build project and I get this distribution structure:
here is the content of hash folder
my spring security config look like this:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling()
.authenticationEntryPoint(myEntryPoint());
http
.authorizeRequests()
.antMatchers("/__hash__/**").permitAll()
.antMatchers("/views/**").permitAll()
.antMatchers("/index.html").permitAll()
.antMatchers("/api/**").authenticated()
.antMatchers("/**").permitAll();
http // login configuration
.addFilterAfter(springSecurityFilter(), BasicAuthenticationFilter.class);
/*http
.authorizeRequests()
.anyRequest().authenticated();*/
http //logout configuration
.logout()
.logoutSuccessHandler(logoutHandler());
http.csrf().disable();
}
The config spring for serving static content:
#Configuration
public class MyContentConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/**")
.addResourceLocations("file:///" + "c:/front/") ;
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/index.html");
}
}
After authentication, I get the index.html page but without css style and without js.
And when I try to access to css using this url "https://localhost:9999/hash/styles.min.css" I get this error:
There was an unexpected error (type=Not Acceptable, status=406).
Could not find acceptable representation
You are loading livereload.js over http. If you are using https, all resource must be load over https.
so load livereload.js over https.
I resolved the problem. it's related to "spring-cloud-config-server". I just delete this config:
org.springframework.cloud
spring-cloud-config-server

Spring Security "Refused to execute script from ..."

I'm building a Spring MVC application with Spring Security and Bootstrap in my HTML files (thymeleaf templates). The Spring Security part is based on the Spring Guide for Spring Security and combined with a Spring Boot application server.
After enabling Spring Security the bootstrap css file won't load with the error message:
Refused to execute script from 'http://localhost:8080/js/bootstrap.min.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.
The error message above comes from the chrome developer console.
What I've tried:
Disabling the Spring Security
=> bootstrap css works again, but I need the security
Searching on the spring forums, but theres a looped link without a solution
Adding a resources handler, but I can't see that the handler is invoked nor the error disappears
Adding the resources path to the permit call
My dir structure:
/main
|-> /java
| BootStart.java
|-> /security
|SecurityConfiguration.java
|-> /resources
|-> /static
|-> /css /** bootstrap location */
|-> /js
|-> /fonts
|-> /templates
| /user
| sample.html
BootStart.java is the java file that gets picked up by Spring Boot.
BootStart.java:
#EnableAutoConfiguration
#ComponentScan
public class BootStart {
public static void main(String[] args) {
SpringApplication.run(BootStart.class, args);
}
}
SecurityConfiguration.java:
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
http
.authorizeRequests()
.antMatchers("/", "/resources/static/**").permitAll()
.anyRequest().authenticated();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
Sample.html:
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" th:href="#{/css/bootstrap.css}" href="../../css/bootstrap.min.css"/>
<link rel="stylesheet" th:href="#{/css/bootstrap-theme.css}" href="../../css/bootstrap-theme.min.css"/>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<div class="alert alert-danger" role="alert">!Basic template!</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</body>
</html>
Currently I'm using the following dependencies in my pom:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
How must I configure Spring Security that I can load css/ js files from my /static resources directory?
Please check this answer by other with similar question.
If you place js files in /js/ dir, there should not that kind of MIME error.
And, for javascript files, it is better to disable security for them:
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/the_js_path/**");
}
I had the same error too with the same folder structure, it was on the css file.
All I did is added /css/** in antMatcher() as below:
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.authorizeRequests()
.antMatchers("/css/**").permitAll() //Adding this line solved it
.anyRequest().fullyAuthenticated()
.and()
.formLogin()
.loginPage("/login").permitAll()
.loginProcessingUrl("/sign-in")
.defaultSuccessUrl("/home")
.failureUrl("/error")
.and()
.logout()
.logoutSuccessUrl("/logout")
.permitAll()
.and()
.csrf().disable();
}
In your case just add /js/** in the antMatcher() and then use permitAll()
I used this to resolved my problem, you may try this
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**");
}
Hope it help.
I had this problem, and struggled for a while. I had created a route which should match every "unmatched" route, and send index.html.
#Controller
public class DefaultPageController {
#Autowired
private LogService logService;
#GetMapping("/*")
public String defaultPage(Model model){
logService.saveLog(Log.LogType.INFO, null, "Default route");
return "index";
}
}
The problem was, that it overrode the route /file.js, and didn't send the static files, but always index.html.
So the solution was only to customize the route.
I had the same error after adding a new method to a controller.
I forgot to provide a value for the #GetMapping annotation and the #Controller itself was not bound to any URL. Wierdly enough adding #GetMapping("/foo") to my method solved the problem. I still haven't figured out why that happened but I'm planning to find out.
when we use "permitall()" or anyrequest() then it enable Mime check so i specify all url listing which use to be accecs.
I removed any comments from the beginning of the css file and it works.
Checklists to import static resources file into Spring MVC with Security Web Configuration:
Permit pattern matcher in configure method which extends from WebSecurityConfigurerAdapter
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/loginPage").loginProcessingUrl("/authenticateUser")
.permitAll();
}
Mapping resources location in configuration by implements WebMvcConfigurer
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
Create the resources folder and subfolders to store the static files.
/src/main/webapp/
|-> resources
| -> css
| -> style.css
Add resources into the JSP file
<link rel="stylesheet" type="text/css" href="css/style.css">
Remember that in the controller file always specify the path even though the home page
#RequestMapping("/")

Categories