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/");
}
}
Related
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">
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();
}
}
I've been struggling for a few days over this. Aside from quirky things that seem to be happening inconsistently and unpredictably by simply commenting out a bit of code, running the program, and then uncommenting and running again, I'm failing to understand how overriding various configure methods are working.
I want WebSecurity to always ignore "/static/**".
Upon launching the application and navigating to the homepage, I can access all of the pages for which I have permitted all, but all of the content in "/static/**" is being ignored until after I have navigated to the login page and logged in as an authenticated user. So the application just appears as white pages with text, without any of the styling at all until logged in.
Here is the code for my AppSecurityConfig class. I have omitted the helper methods for handling success and failure of logging in, and I also have to different account types that serve different roles, so I have only included one account here for simplification. The part where I believe the problem exists is in the configure(WebSecurity web) method where I am calling the .ignoring() method and passing the "/static/**" arg. Thank you in advance:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private CompanyService companyService;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(companyService);
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/static/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/",
"/account_registration",
"/candidate_registration",
"/addCandidate",
"/company_registration",
"/addCompany",
"/select_account_type",
"/candidate_login",
"/company_login").permitAll()
.antMatchers("/company_profile").hasRole("COMPANY")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/company_login")
.permitAll()
.successHandler(companyLoginSuccessHandler())
.failureHandler(companyLoginFailureHandler())
.and()
.logout()
.logoutSuccessUrl("/");
}
}
The path to my static folder is "src/main/resources/static", but I did what Sam said and opened the developer tools and realized that all of the contents within the "static" directory were being referenced directly. For example, there are directories referenced in this way: "/vendor/..." and "/images/...", that were being referenced but ignored due to security. There are also some files in the "static" directory like "app.css", "app.js" and "favicon.png" that are having some strange behavior. It appears that they are not being ignored but different colors and styling are being displayed unless I also add them as arguments to the .gitIgnoring() method like "/app.css" etc. This project was built by working through a TeamTreehouse tutorial and then refactoring and adding custom styling between a few people on my 6 person team, and I'm pretty sure there are multiple things under the hood inherited in this project that myself and the front end people are not understanding when it comes to the styling.
The fix that seems to work, although maybe not ideal, was removing "/static/**" from the .ignoring() method and replacing it with all of the contents that were actually inside the "static/" directory:
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers( "/images/**",
"/vendor/**",
"/app.css",
"/app.js",
"/favicon.png");
}
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
I had updated spring security from 3x to 4.0.1.RELEASE. Then I finally had the change to fully remove old XML, and replace it with pure java config. But my security isn't working properly.
Problem:
my default login page does not authorize, under POST /login.htm I have 404.
my main app can run as unauthorized
because I have 404 on login POST, I am not entering UserDetailsService
all beans are provided into this configuration, I have no context start problems
My configuration file:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
#ComponentScan(basePackages = {"com.dal.dao.security", "com.services.security"})
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
LocalUserDao userDao;
#Autowired
UserRoleMapper roleMapper;
#Autowired
StandardPasswordEncoder passwordEncoder;
private UserDetailsService methodSecurityService() throws Exception {
return new UserDetailsServiceImpl(userDao, roleMapper);
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(methodSecurityService()).passwordEncoder(passwordEncoder);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/*")
.authenticated()
.and()
.formLogin()
.loginPage("/login.htm").failureUrl("/login.htm?error")
.usernameParameter("username")
.passwordParameter("password")
.and().logout().logoutSuccessUrl("/index.htm")
.and().csrf()
.and().exceptionHandling().accessDeniedPage("/403");
}
}
Could anyone help me with this? I have already watched few no-xml configuration, but they don't seem to be working on my example.
Source of my code can be found here.
I think the fix is simple (i hope) you didn't advise that anyone can access your login form:
http.authorizeRequests()
.antMatchers("/*")
.authenticated()
.and()
.formLogin()
.loginPage("/login.htm").failureUrl("/login.htm?error")
.usernameParameter("username")
.passwordParameter("password")
.permitAll() // ADD THIS LINE
.and().logout().logoutSuccessUrl("/index.htm")
.and().csrf()
.and().exceptionHandling().accessDeniedPage("/403");
Essentially you are redirecting users to login page without enabling unauthenticated access to it. Basically you are asking them to authenticate to view the authentication form :).
From Spring Security:
Granting access to the formLogin() URLs is not done by default since
Spring Security needs to make certain assumptions about what is
allowed and what is not. To be secure, it is best to ensure granting
access to resources is explicit.