Springboot filter executed in case of permitAll urls as well - spring-boot

I am new to springboot and trying to implement security where no filters are applied to my login, signup and home urls.
I am using springboot 2.7.1
I am expecting antMatchers("/**/signup").permitAll() to remain free of any security filter.
Upon debugging, I found that my signup url was being hit and user details were saved, but my AuthorizationFilter was also being executed .
This is my SecurityFilterChain :
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
AuthenticationManagerBuilder authenticationManagerBuilder=http.getSharedObject(AuthenticationManagerBuilder.class);
authenticationManagerBuilder.userDetailsService(userLoginService).passwordEncoder(bCryptPasswordEncoder);
AuthenticationManager authenticationManager=authenticationManagerBuilder.build();
http.csrf().disable().authorizeHttpRequests()
.antMatchers("/**/login").permitAll()
.antMatchers("/**/signup").permitAll()
.antMatchers("/home/**").permitAll()
.anyRequest().authenticated().and()
.addFilter(getAuthenticationFilter(authenticationManager))
.addFilter(new AuthorizationFilter(authenticationManager))
.authenticationManager(authenticationManager)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
return http.build();
}
I don't understand why is it happening this way.

When you use permitAll() you are not disabling the filters, you are just specifying that you do not want to apply any authorization checks for that RequestMatcher. All the filters will still work.
The AuthorizationFilter will be invoked but since you configure permitAll() for that endpoint, it will always grant access.

Related

Keep session id in case of presence of special parameter in request. Spring Security

Does anybody know if there any way to configure Spring Security in the way that it doesn't change session id if there is some parameter in the request.
For example:
somesite.com/home.jsp?password=encrypted- change session id after
authentication
somesite.com/home.jsp?password=encrypted& keepsessionid - don't
change session id after authentication
I was thinking about filter chain, maybe removing conditionally SessionManagementFilter, but not sure if this is a proper way, and even if this will be working
For someone with the same question. I found the answer. Different session management strategy can be achieved by using multiple http security configuration (inner classes of main security classes). The special case http security configurer should be adjusted to some special request
#Configuration
#Order(1)
public class SpecialCaseSessionHandlingConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(request -> Check1(request))
.authorizeRequests()
.anyRequest().authenticated();
}
}

Spring security 5 - UsernamePasswordAuthenticationFilter and basic authentication

I'm trying to implement simple security for a small API school project and am a bit confused and overwhelmed. I followed
this blog post.
Everything works and I'm able to login and receive a jwt token. However login is currently performed by sending the username and password along with the URL as query parameters. That is of course something I would like to avoid.
I have tried adding httpbasic to the security configuration like this:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.addFilter(new JwtAuthenticationFilter(authenticationManager(), jwtAudience, jwtIssuer, jwtSecret, jwtType))
.authorizeRequests(authorizeRequests ->
authorizeRequests
.antMatchers("/board/**").hasAnyRole("MEMBER", "BOARD")
.antMatchers("/members/**").hasRole("MEMBER")
.anyRequest().authenticated()
)
.httpbasic().and().
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
Login however ceases to work and I constantly get an unauthorized while trying basicAuth with postman.
So my question is: How can I change the behaviour of these code snippets to accept basic authentication and not send user credentials by URL? Do I have to override the AttemptAuthentication method too?

How can I allow public access to parts of Spring Security app using permitAll?

I'm trying to get a Spring application to allow some requests to public (without login) and some requests to private (with login).
At this point I'd like to just get the public part to work properly.
I have tried most of the example configurations listed on the Spring Security documentation, including all sorts of combinations of anonymous(), and permitAll(). All end up redirecting to the login page.
protected void configure(HttpSecurity http) throws Exception{
http.authorizeRequests()
.antMatchers("/resources/**", "/signup", "/about","/api/home").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
.anyRequest().authenticated()
.and()
// ...
.formLogin();
}
Expected result: items under permitAll() are accessible without logging in
Actual result:
redirect to login page. This shows up in the log: 2019-06-06
17:29:43.593 INFO 56330 --- [ main]
o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: any
request, [org.sprin...
This leads me to believe that it isn't even reading this configuration. Is there any way to fix this?
Thanks!
UPDATE: I tried adding the websecurity ignores, and it doesn't appear to be working still. It appears to still print the "defaultsecuritychain" error so I feel like this may have something to do with it.
UPDATE 2: Added application.properties file under src/main/resources with this line logging.level.org.springframework.security=DEBUG to make it log debug messages.
pastebin.com/2u9k7eHD
Have a look at http://blog.florian-hopf.de/2017/08/spring-security.html, it may explain your use-case in more detail.
My recommendation is to try and use WebSecurity for static and public resources
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**", "/signup", "/about","/api/home");
}
You can achieve your requirements with below configurations. It's a good way to use the URLs which does't require Authentication/Authorization to be placed in WebSecurity using ignoring instead of HttpSecurity as WebScurity will bypass the Spring Security Filter Chain and reduce the execution time
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/**", "/signup", "/about","/api/home");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
.anyRequest().authenticated()
.yourConfigurations
}
When you use HttpSecurity and try to permitAll() requests. Your requests will be allowed to be accessed from the Spring Security Filter Chain. This is costly as there will be requests other requests which would also come into this filter chain which needs to be allowed or disallowed based on Authentication/Authorization
But when you use WebSecurity, any requests to "/resources/**", "/signup", "/about","/api/home" will completely by pass the Spring Security Filter Chain all together. It is safe because you don't need any Authentication/Authorization to be in place to see an image or read a javascript file.
Turns out that I was missing the #SpringBootApplication annotation all along in one of my source files. Make sure that's in there and perhaps it will work.
Thank you to all who replied!

Spring security antMatchers permitAll doesn't work

I know that there are topics with this problem, but the config which I made is correct and I compared it to a project where it works correctly.
I want to "unsecure" a /login endpoint for JWT security, but still the AuthenticationFilter runs before reaching the /login endpoint.
I'm confused why it is no working.
My Code Below :
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated();
http
.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
http.headers().cacheControl();
}
Duplicate: How to add a filter only for one special path WebSecurityConfigurerAdapter
You can't do that with a single Configuration class. Take a look at this question: How to apply spring security filter only on secured endpoints?.
In this case, I think the better solution is to configure multiple HttpSecurity. From Spring IO documentation:
We can configure multiple HttpSecurity instances just as we can have
multiple blocks. The key is to extend the
WebSecurityConfigurationAdapter multiple times. For example, the
following is an example of having a different configuration for URL’s
that start with /api/.
The documentation has a full example with the necessary steps to accomplish this:
Configure Authentication as normal
Create an instance of WebSecurityConfigurerAdapter that contains
#Order to specify which WebSecurityConfigurerAdapter should be
considered first.
The http.antMatcher states that this HttpSecurity
will only be applicable to URLs that start with /api/
Create another instance of WebSecurityConfigurerAdapter. If the URL does not start with /api/ this configuration will be used. This
configuration is considered after ApiWebSecurityConfigurationAdapter
since it has an #Order value after 1 (no #Order defaults to last).
Good luck!

how to implement a authentication with spring boot security?

i am using spring boot. i want to post a username and password params to login, and if login success then return a token. after, i will use the token to judge login status. here is my security configure code. but i don't konw where to write the login authentication logic code.
SecurityConfig.java
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.fullyAuthenticated()
.and()
.formLogin()
.loginPage("/user/unlogin")
.permitAll();
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/user/login")
.antMatchers("/user/logout")
.antMatchers("/user/register");
}
}
==========================
thank you !
There's always more than one way to do something with Spring. There is a happy path (probably) with Spring Boot, and you seem to have started on it. Note though, if you want Boot to provide some default behaviour, then don't use #EnableWebSecurity (as advised in the user guide). The web-secure sample has an example you can follow.
If you use formLogin() the default login URL is /login (not /user/login), so you should be able to post the username and password to that endpoint to authenticate. Don't add /login to the unsecured paths using web.ignoring() or Spring Security will never process it. When you post to /login you get back a JSESSIONID cookie. That's your authentication token, and it expires when the session expires in the server (30min by default, but easily configurable). Include it in future requests for secure resources - some HTTP clients will even do that for you (like a browser does).

Resources