Spring Boot doesn't serve HTML after Spring Security is enabled - java

In my Spring Boot application, I configure Spring Security as
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/css/**", "/js/**", "/images/**", "**/index.html").permitAll()
.antMatchers("/**.html").permitAll()
.antMatchers(HttpMethod.POST, "/login").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(new LoginFilter("/login"), BasicAuthenticationFilter.class)
.addFilterBefore(new TokenFilter(), BasicAuthenticationFilter.class);
}
}
I have index.html under resources/static/index.html. This stopped serving after I enabled security. What am I missing?
If I go back when I do not have any security, I get my HTML rendered on server.

try to change to /**/index.html. For Ant path matcher
? matches one character
* matches zero or more characters
** matches zero or more directories in a path
{spring:[a-z]+} matches the regexp [a-z]+ as a path variable named "spring"

Related

Spring Security ignores URL patterns from requestMatchers

I just created a new Spring Boot application with the following web security config (using spring-security-config:6.0.0):
#Configuration
#EnableWebSecurity
public class WebSecurityConfig {
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((requests) -> requests
.requestMatchers("/", "/login", "/info/**").permitAll()
.anyRequest()
.authenticated()
)
.formLogin((form) -> form
.loginPage("/login")
.permitAll()
)
.logout(LogoutConfigurer::permitAll);
return http.build();
}
}
When trying to access any url I get redirected to /login with ERR_TOO_MANY_REDIRECTS. Something seems to be wrong with my SecurityConfig.
In previous versions I always used http.authorizeHttpRequests().antMatchers("/") instead of requestMatchers but it seems like they removed it.
Does requestMatchers() do the same thing or how can I configure url patterns that don't require login?

Java Spring Boot Security Class Configuration

My aim is to add security class to my Java project except paths like "api/public/*".
When I request in POSTMAN
http://localhost:8080/api/public/signup
with a json body, I get 401. Here's my security class which permits all matchers of api/public/*:
What am I missing?
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
// we don't need CSRF because our token is invulnerable
.cors()
.and()
.csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler)
// don't create session
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/public/**").permitAll()
.anyRequest().authenticated();
// Custom JWT based security filter
JwtAuthorizationTokenFilter authenticationTokenFilter = new JwtAuthorizationTokenFilter(userDetailsService(), jwtTokenUtil);
httpSecurity
.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
// disable page caching
httpSecurity
.headers()
.frameOptions().sameOrigin() // required to set for H2 else H2 Console will be blank.
.cacheControl();
}
#Override
public void configure(WebSecurity web) throws Exception {
// AuthenticationTokenFilter will ignore the below paths
web
.ignoring()
.antMatchers("/api/public/*");
}
Mvn clean solved my problem. It seems build somehow stuck in a previous state.
mvn clean

Confusion with Spring Security in Spring Boot

I'm working with Spring Boot 1.4.2.RELEASE, Spring Security 4.1.3.RELEASE, and Java 8.
For the security configuration I have the following class:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/assets/**", "/logout", "/login");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement() // 1
.sessionFixation() // 2
.migrateSession() // 3
.maximumSessions(1) // 4
.maxSessionsPreventsLogin(true).expiredUrl("/login").and() // 5
.invalidSessionUrl("/login") // 6
.and() // 7
.authorizeRequests()
.antMatchers("/app/**").authenticated()
.antMatchers("/about").permitAll()
.anyRequest().authenticated().and()
.formLogin()
.loginPage("/login").permitAll()
.loginProcessingUrl("/auth").permitAll()
.defaultSuccessUrl("/app/index", true)
.failureUrl("/login?error")
.usernameParameter("uid")
.passwordParameter("pwd").and()
.logout()
.permitAll()
.invalidateHttpSession(true)
.logoutUrl("/logout").permitAll()
.logoutSuccessUrl("/login").permitAll()
.clearAuthentication(true).and()
.exceptionHandling().and()
.csrf().disable()
.headers().frameOptions().disable()
.cacheControl().and();
}
}
When try access to "/about" (permit all everyone), redirects me to "/login". I try it a second time and now it allows me to access "/about".
I have changed the authorization order of requests in the configuration class but don't works. When I delete the lines of sessionManagement (1 to 7), everything works normally.
Do I need any extra configuration?
When you are testing this, did you clear your browser's cookie with regard to your testing site? The session management filter sets a jsessionid cookie, which gets sent back. Your browser has no idea that you reset your server, so thinks the cookie is just fine, and you send back an invalid session.
You may want to take a look at your session creation policies to see whether or not it suits your purpose.

Secure an Angular JS app with Spring Security

I have created a Spring Boot app and I have my front-end app in the /resources/static folder.
For the routing, I am using Angular JS UI Router library.
I have defined a route, which I only want to be accessed by the admin and now I am trying to secure it using Spring Security.
Here is my WebSecurity Configuration class:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER", "ADMIN");
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/#/admin").hasRole("ADMIN")
.and()
.formLogin()
.and()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/member", "/member/**").permitAll()
.antMatchers(
HttpMethod.GET,
"/",
"/*.html",
"/favicon.ico",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/**/**/*.css",
"/**/**/*.js",
"/**/**/*.html",
"/**/**/**/*.css",
"/**/**/**/*.js",
"/**/**/**/*.html",
"/**/**/**/**/*.css",
"/**/**/**/**/*.js"
).permitAll()
.antMatchers("/auth/**", "/member/**", "/account/**").permitAll()
.and()
.csrf().disable();
}
}
The route I am trying to secure can be accessed through http://localhost:8080/#/admin.
However, whenever I am accessing that route, no login is requested and the page can be viewed by anyone.
Is it there another approach I should follow?
The URL: http://localhost:8080/#/admin is mapped to / in your permitAll list instead of the /#/admin rule, since #/admin part is just URL fragment, and usually not the business of the server side.
You have to define an API between your frontend and backend. Usually in RESTful web services form, and serve at /api/* path. Secure the path, and let your frontend talk to your backend through those APIs only.
It is eaiser to fix your issue,
Update
.antMatchers(HttpMethod.GET, "/#/admin").hasRole("ADMIN")
To
.antMatchers(HttpMethod.GET, "/#/admin").hasRole("ADMIN").anyRequest().authenticated()
For every matchers, you always need with permitAll() or authenticated() for it.

Correctly configuring Spring with security - Java

So I'm new to Spring, and learning in the way as I develop a web application using Spring-Boot.
Currently my page consists of two html pages: index.html and login.html. I'm also using Spring-Security.
Here's my current MvcConfig:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
#Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/login").setViewName("login");
}
}
The way the website is designed, an user goes to the url http://localhost:8080, then he/she is presented with the initial page, there's a login tab there where he/she can log in, and move to the dashboard view (which I will add later).
However, when I load the initial, the page is totally misconfigured (css / js / images resources aren't loaded). After I go to http://localhost:8080/login, perform the login and everything works again.
Therefore, any url of the form http://localhost:8080 is to be allowed (index.html), but anything else would require login.
Here's my Spring-Security config:
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.regexMatchers("/", "/index").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
}
How can I correctly configure my webpage?
*** Notes:
* I currently don't have any Controller class.
problem with regex matchers that i found is any resource loaded from your server you will need to account for in the mapping.
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login", "/admin").hasRole('ADMIN') // e.g. for pages that need to be authenticated
.anyRequest().permitAll() // all the others will be accessable by all
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
}
The most simplest way to do matching is following steps:
Declare your resource files by overriding addResourceHandlers
Use antmatchers to handle url security (simpler and easier), unless you have extremely dynamic urls with critical parameter
sorry guy, I will try to make it clear
anyRequest().authenticated() make your request to html resource need to authorized. You only permitAll to '/' & '/login'
so, add permitAll to css, js, image too
http
.authorizeRequests()
.regexMatchers("/", "/index").permitAll()
.antMatchers("/**/*.js", "/**/*.css").permitAll()
or more easy, make a style for login page. no depend on other static resource.

Categories

Resources