Get request is not authorized when CSRF is disabled in Spring Security - spring

Spring Security basic authentication works if I don't add the following
#Configuration
#EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
}
After I add this code piece a GET request without an Authorization header gets the response while I expect a response saying Unauthorized. Before adding this configuration GET response gets 401.
The only change is the above class; nothing else was changed.

Try to add .anyRequest().authenticated(), it means, all request must be authenticated. If you want to add an exemption add something like .antMatchers(HttpMethod.GET, "/", "/js/**", "/css/*", "/images/**").permitAll() this will not be authenticated.
Sample Code:
#Configuration
#EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers(HttpMethod.GET, "/", "/js/**", "/css/*", "/images/**").permitAll()
.anyRequest().authenticated();
}
}

Related

Oauth2 security configuration antmatchers request filtering not working as expected

I am working on a simple spring boot project along with spring security oauth2 to use google authentication for a specified endpoint which is /google/login.
With following security configurations everything is working perfectly.
#Configuration
public class SecurityConfigure extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.requestMatchers().antMatchers("/**")
.and()
.authorizeRequests().antMatchers("/ldap/login").permitAll()
.anyRequest().fullyAuthenticated()
.and()
.oauth2Login();
}
}
But I need to specify only /google/login endpoint to authenticate with oauth2. Therefore I specified it like this.
#Configuration
public class SecurityConfigure extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.requestMatchers().antMatchers("/google/**")
.and()
.authorizeRequests().antMatchers("/ldap/**").permitAll()
.anyRequest().fullyAuthenticated()
.and()
.oauth2Login();
}
}
with this security configuration http://localhost:8080/google/login endpoint call redirects to another endpoint called http://localhost:8081/oauth2/authorization/google which is I haven't defined.
Please help me to overcome this problem. Thank you.
This configuration works for me. I had to allow all endpoints that were redirecting while Google's authentication process was running. 
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.requestMatchers().antMatchers("/google/**","/oauth2/authorization/google","/login/oauth2/code/google")
.and()
.authorizeRequests().antMatchers("/ldap/**").permitAll()
.anyRequest().fullyAuthenticated()
.and()
.oauth2Login();
}

Spring Boot AntMatchers vs #PostAuthorize usage

I'm tasked with implementing RBAC(Role-Based Access Control) in the REST API I'm working on.
What puzzles me is that when I use in my Security class that extends WebSecurityConfigurerAdapter, in configure method antMatchers, the Authorisation is working correctly, but when I dispose of antMatchers and try to replace them by #PostAuthorize on top of an endpoint, RBAC fails to work.
That's my configure method from a class extending WebSecurityConfigurerAdapter:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.rememberMe()
.and()
.addFilter(new JwtUsernameAndPasswordAuthenticationFilter(authenticationManager()))
.addFilterAfter(new JwtTokenVerifierFilter(), JwtUsernameAndPasswordAuthenticationFilter.class)
.authorizeRequests()
.antMatchers("/h2-console/**").permitAll()
.antMatchers("/user").authenticated()
.antMatchers("/hello").hasRole(ApplicationUserRole.ADMIN.name())
.anyRequest()
.authenticated();
http.headers().frameOptions().disable();/*REQUIRED FOR H2-CONSOLE*/
}
Which works fine.
Thats by annotarion on top of an endpoint that shoud be authorized, but is not.
#PostAuthorize("hasRole('ADMIN')")
#RequestMapping("/hello")
String hello(){
return "hello";
}
What am I doing wrong, that it is not workind correctly?
Did you try annotating your security config class with the below annotations?
Something like this.
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
protected void configure(final HttpSecurity http) throws Exception {}
}

Spring Boot Security Authentication: Application having 2 different domain URL and need to authenticate with Spring Security

I need help with one of the issue that I am facing with Spring Boot Security. I have application which has 2 different Urls.(Infoblock CNAME)
domain1.com
domain2.com
both Url are point to the same application.
Due to business reason we need 2 different Url and we are planning to land on diff page based on the URL entered in browser. Issue is with Spring Security AntMatcher.
With AntMatcher we can only provide path but how we can address the domain with it.
Could you please guide me.
Thanks in Advance.
Instead of AntMatcher you can use
http.requestMatcher(new RequestHeaderRequestMatcher("Host", "127.0.0.1:8080"))
with any other matcher from org.springframework.security.web.util.matcher package.
Here is an example:
#EnableWebSecurity
#Configuration
public static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Configuration
#Order(1)
public static class SecConfig1 extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(new RequestHeaderRequestMatcher("Host", "127.0.0.1:8080"))
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin();
}
}
#Configuration
#Order(2)
public static class SecConfig2 extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(new RequestHeaderRequestMatcher("Host", "127.0.0.2:8080"))
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
}
#Override
protected void configure(HttpSecurity http) throws Exception {
//default deny all
http.authorizeRequests().anyRequest().denyAll();
}
}

Providing custom OAuth2AccessTokenResponseClient to spring

I have a demo spring boot app and I would like to configure oauth login as well my own custom token response client.
This is my configuration:
#Configuration
#EnableWebSecurity
class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.oauth2Login()
.and()
.oauth2Client()
.authorizationCodeGrant()
.accessTokenResponseClient(customAccessTokenResponseClient());
}
private OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> customAccessTokenResponseClient() {
DefaultAuthorizationCodeTokenResponseClient client = new DefaultAuthorizationCodeTokenResponseClient();
client.setRequestEntityConverter(new CustomOAuth2AuthorizationCodeGrantRequestEntityConverter());
return client;
}
}
The login flow is working find, but it looks like my custom token response client is not getting registered. I put a break point in there, but the flow doesn't go through it. It looks like it is still using the defaults.
Am I missing something here or is the order wrong?
Figured out the issue.
The right way to configure is the following:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().anyRequest().authenticated()
.and()
.oauth2Login()
.tokenEndpoint()
.accessTokenResponseClient(customAccessTokenResponseClient());
}

#PreAuthorize(permitAll) still requires authentication

I have the following example method in my Repository (with #RepositoryRestResource annotation):
#Override
#PreAuthorize("permitAll")
#PostAuthorize("permitAll")
public Iterable<User> findAll();
But I'm still getting 401 Unauthorized, event when I add those permitAll annotation to whole Repository interface.
I got this as my WebSecurityConfigurerAdapter:
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
#Configuration
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().fullyAuthenticated().and().httpBasic().and().csrf().disable();
}
}
I suppose this takes precedence over those method annotations, bu I don't know how to fix this.
Method security is applied after the web security filter.
Since you have anyRequest().fullyAuthenticated() in your configuration, your findAll method will never be hit. anyRequest().fullyAuthenticated() means that all attempts to access a web endpoint that does no have have some from of full user authentication on it will fail.
From the JavaDoc
Specify that URLs are allowed by users who have authenticated and were
not "remembered".
You will need to add an additional path in your web security, some like.
protected void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().fullyAuthenticated()
.antMatchers(HttpMethod.GET, '/somePath').permitAll()
.and()
.httpBasic()
.and()
.csrf().disable();
}

Resources