HttpSecurity With SpringBootDev - spring-boot

I'm working on spring reload with spring dev tools in remote app.
I got a bug with HttpSecurity configuraiton.
As explain on Here, I put this in config http security :
http.requestMatchers("/.~~spring-boot!~/restart").anyRequest().anonymous()
.and().csrf().disable();
First requestMatchers doesn't exists in 2.2.4.RELEASE version so I replaced it by antMatcher. But the application has to authenticate others urls. I tried multi differents configurations but never worked.
First
http.csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.antMatcher("/.~~spring-boot!~/restart").anonymous().and().
authorizeRequests(aR -> aR
.antMatchers("/.~~spring-boot!~/restart").anonymous()
.anyRequest().authenticated()
)
.logout().disable()
.addFilterBefore(new AuthTokenFilter(userRepository, env), UsernamePasswordAuthenticationFilter.class);
Second
http.csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.antMatcher("/.~~spring-boot!~/**").authorizeRequests().anyRequest().anonymous()
.and()
.authorizeRequests().anyRequest().authenticated()
.and()
.logout().disable()
.addFilterBefore(new AuthTokenFilter(userRepository, env), UsernamePasswordAuthenticationFilter.class);
Third
http.csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.antMatcher("/.~~spring-boot!~/restart").anonymous().and().authorizeRequests().anyRequest().authenticated().and().logout().disable()
.addFilterBefore(new AuthTokenFilter(userRepository, env), UsernamePasswordAuthenticationFilter.class);
could you help me? Some conf's result are the exception :
Exception in thread "File Watcher" java.lang.IllegalStateException:
Unexpected 401 UNAUTHORIZED response uploading class files. Some are :
Can't configure anyRequest after itself.
I'm quite lost cuase thinking that antMatcher will work. Any ideas?

Related

Spring Security - Custom Authentication Provider and HTTP Basic for Actuator Endpoints

I´ve got a running Spring Boot Application (Spring Boot v2.4.1) and I would like to monitor it using Spring Boot Admin.
I have already setup the server and I can monitor the instance of my application with the /actuator/ endpoint not secured. I have a permitAll() on it.
Now I´d like to secure it, but I do not know how to do it without messing with my current Security Configuration.
I have Spring Security configured to match username and password from a DB and with a CustomAuthenticationProvider. If possible I would like to add a Actuator Endpoints with a HTTP Basic authentication.
This is my current security config:
http.
authorizeRequests()
.antMatchers("/admin/**").hasAuthority(AUTHORITY_ADMIN)
.antMatchers("/user/**").hasAnyAuthority(AUTHORITY_ADMIN, AUTHORITY_USER)
.anyRequest().authenticated()
.and()
.csrf().disable()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error=true")
.successHandler(new CustomUrlAuthenticationSuccessHandler(translator))
.usernameParameter("username")
.passwordParameter("password")
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/")
.and()
.exceptionHandling().accessDeniedPage("/403")
.and()
.headers().frameOptions().sameOrigin();
I would like to keep that configuration and also tell spring that whenever a user hits /actuator/ endpoint, it will requiere HTTP Basic Security credentials.
I was thinking on having two #Configuration classes, extending WebSecurityConfigurerAdapter. One would be the one I´ve already got and the other one for the actuator endpoints. But I had no luck with it.
Thank you
Thank you very much
You can create two SecurityFilterChain beans, one for your /actuator/** endpoint with higher priority, and other to every other endpoint with lower priority, like so:
#Bean
#Order(1)
public SecurityFilterChain actuatorWebSecurity(HttpSecurity http) throws Exception {
http.requestMatchers((matchers) -> matchers
.antMatchers("/actuator/**"));
http.authorizeRequests((authz) -> authz
.anyRequest().authenticated());
http.httpBasic();
http.userDetailsService(myUserDetailsService);
...
return http.build();
}
#Bean
#Order(2)
public SecurityFilterChain defaultWebSecurity(HttpSecurity http) throws Exception {
// your current configuration
}
In this configuration, the #Order annotation tells the order that the SecurityFilterChains are gonna be matched against the requests.
This is how I solve it: I create a new #Configuraiton class extending WebSecurityConfigurerAdapter,
I was unable to stop using WebSecurityConfigurerAdapter (as suggested by #Marcus-Hert-da-Coregio in the comments) because if I do not extend it I was not able to define my custom AuthenticationProvider.
This class has #Order(1) so it would take precedence over my other initial configuration (which I set to #Order(2)). And this is it's content:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/actuator/**")
.csrf().disable()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
Then my custom AuthenticationProvider will verify if the given credentials for accessing the actuator endpoints are valid.
Addittional information
The reason why this fails the first time I test it was because I was not setting the initial
.antMatcher("/actuator/**")
by adding it I was telling SpringSecurity that this configuration should only be applied to those endpoints. I get that notion from this article
I hope this helps someone in the future

Spring Security custom authentication provider's authenticate() method is not working

I followed the article Using Custom Authentication Provider Spring Security adding a custom authentication provider in Spring Security.
I found that if I POST to /login, it is redirected to /login.
My custom Authentication Provider's authenticate() is not called.
Even if I use Spring Security's TestingAuthenticationProvider, POST to /login still get redirected to /login.
Is there some thing wrong with my WebSecurityConfigure? This is my configure.
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/webjars/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
I use Spring Boot. Do I need to modify the application.properties file? Is there any working sample project on using custom authentication provider?
Have you tried using
http.authorizeRequests()
.antMatchers("/", "/webjars/**").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic();
in your WebSecurityConfigure?
You will get a generated login-window that is using your CustomAuthenticationProvider as soon as you are trying to call a page you have not included in
.antMatchers("/", "/webjars/**").permitAll().

Spring Boot Security: How to run authentication filter before CSRF in Spring Boot?

I am always getting unauthorize on Login.
On Login i need to authenticate user as well as generate CSRF token based on JWT token generated from user credentials.
I have CsrfCookieGeneratorFilter but i need to pass JWT generated after sucessfull authentication. My current code always execute CsrfFilterfirst and after that run authentication thing.
So Authentication First and then CsrfCookieGeneraterFilter.
Could anyone guide how to achieve using following builder (I am quite new to this Spring security thing implementation)
Following is code i am trying:
httpSecurity
.authorizeRequests().antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.csrf()
.requireCsrfProtectionMatcher(csrfRequestMatcher)
.csrfTokenRepository(customCsrfTokenRepository)
.and()
.cors()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
.authenticationEntryPoint(this.jwtAuthenticationEntryPoint);
httpSecurity.addFilterAt(new CsrfCookieGeneratorFilter(customCsrfTokenRepository), CsrfFilter.class);
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);

Should I disable CORS in spring backend? Unathorized request is blocked

I'm working on project with spring boot and Vue, I need to protect my endpoints. The user will have specific role, admin role or typical user role. When I search for tutorials how to configure JWT and spring security I'm getting articles with disabled cors by cors().disable() only . And that's my question.. May I send request from my front Vue app via axios if cors in spring backend is disabled? Is it right approach to disable it? A lot of my requests from api were blocked by cors so I enabled it but I didn't implement user roles and it made me confused what to do now because I have to do it... Another problem is when I implemented httpSecurity.csrf().disable().authorizeRequests().antMatchers("/authenticate", "/register","/login").permitAll(). and tried to call /authenticate from another device in same network then spring blocked it but it shouldn't be blocked.. On the top of controller I have #CrossOrigin(origins="*", maxAge=3600) and #RestController so I don't know why my request is blocked.
Help me please if You have some ideas.
Best regards!
Set this in top of every controller
#CrossOrigin(origins = "*")
#RestController
And set the code in SecuriyConfig as follows. It worked for me.
httpSecurity.cors()
.and()
.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/",
"/favicon.ico",
"/**/*.png",
"/**/*.ttf",
"/**/*.woff",
"/**/*.woff2",
"/**/*.gif",
"/**/*.svg",
"/**/*.jpg",
"/**/*.jpeg",
"/**/*.html",
"/**/*.css",
"/**/*.js")
.permitAll()
.antMatchers("/authenticate", "/register","/login")
.permitAll()
.antMatchers(HttpMethod.OPTIONS, "/**")
.permitAll()
.anyRequest()
.authenticated();

405 Method Not Allowed for POST

I have a very simple spring boot application, which is secured by the following code:
http.authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
.and()
.formLogin().loginPage("/login").failureUrl("/login?error")
.usernameParameter("username").passwordParameter("password")
.and()
.logout().logoutSuccessUrl("/login?logout")
.and()
.exceptionHandling().accessDeniedPage("/403");
the idea is to secure "admin" portion. It exposes a REST API.
The problem is all the POSTS returns
405 Method Not Allowed
If I remove the security starter from the application, it works. This makes me believe that the security configuration is the problem. But I cannot find out how.
This should be easy.
POSTs and PUT requests would not be allowed if CSRF is enabled,and spring boot enables those by default.
Just add this to your configuration code :
.csrf().disable()
that is :
http.
.csrf().disable().
authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
.and()
.formLogin().loginPage("/login").failureUrl("/login?error")
.usernameParameter("username").passwordParameter("password")
.and()
.logout().logoutSuccessUrl("/login?logout")
.and()
.exceptionHandling().accessDeniedPage("/403");
Refer docs ,if you need to enable CSRF :
http://docs.spring.io/spring-security/site/docs/4.0.x/reference/htmlsingle/#csrf-configure
This can also happen if using Spring Security SAML extension and your SAMLUserDetailsService returns a UsernameNotFoundException. Seems pretty counter-intuitive, but that's what it does by default (in my experience).

Resources