What is causing this "Access Denied" error? - spring-security

I'm getting an "Access Denied" error when I run this Postman request.
Here is my security configuration:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JWTAuthenticationFilter(authenticationManager()))
.addFilter(new JWTAuthenticationVerificationFilter(authenticationManager()))
// this disables session creation on Spring Security
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
And the constant is
public static final String SIGN_UP_URL = "api/user/create";
My entire project is here.
I'm not quite sure what I'm doing wrong here.

Beginning slash is missing from the SIGN_UP_URL...

Related

On what basis requireCsrfProtectionMatcher is initialised in csrfFilter

The CsrfFilter has a validation
if (!this.requireCsrfProtectionMatcher.matches(request)) {
filterChain.doFilter(request, response);
return;
}
in the above snippet, this.requireCsrfProtectionMatcher is getting initialised to AndRequestMatcher. But I want to use only DefaultRequiresCsrfMatcher. Can anyone please provide more information about this?
My security Configuration
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().and().
cors().and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/rest/open/**").permitAll()
.and().authorizeRequests()
.antMatchers("/**").authenticated()
.anyRequest().permitAll()
.and()
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(getJwtAuthoritiesConverter());
}
The requireCsrfProtectionMatcher is being initialized with AndRequestMatcher because you are using oauth2ResourceServer().jwt().
The oauth2ResourceServer DSL tells the CsrfFilter to ignore requests which contain a Bearer token. You can check it in the source code.
Since the JWT authentication is stateless, you would not need a CSRF token in the request.

Oauth2Login for only specific urls

I'm trying to have an oauth2 configuration setup for login through Spring Security. But only for specific urls.
My security config looks as follows.
#Override
public void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/secured/**")
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.oauth2Login()
.clientRegistrationRepository(clientRegistrationRepository())
.authorizedClientService(authorizedClientService());
}
Basically I only want the oauth2Login to be trigger for urls that start with /secured. It seems to almost work, the only issue is whenever Spring trys to re-direct my session to google for authentication it triggers a 404.
The standard redirect for an oauth authentication should fire off to http://localhost:8080/oauth2/authorization/google, which my application attempts to do, but it 404's.
I'm assuming the http://localhost:8080/oauth2/authorization/google url is being blocked by some type of security config? But I cannot for the life of me figure out why.
I'm guessing I need to find the right combination of .permitAll() for any request going to "/oauth2/authorization/**"
I've tried this below.
#Override
public void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/secured/**")
.authorizeRequests()
.antMatchers("/oauth2/authorization/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.oauth2Login()
.clientRegistrationRepository(clientRegistrationRepository())
.authorizedClientService(authorizedClientService());
}
But that won't work.....does anyone see my issue? I have no other security config conflicting with this one, I'm at a bit of a loss.
According to previous answer, the version with no lambda-style should look like this right?
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests
.antMatchers("/secured/**").authenticated()
.anyRequest().authenticated()
.and()
.oauth2Login()
.clientRegistrationRepository(clientRegistrationRepository())
.authorizedClientService(authorizedClientService());
}
If we want oauth2Login only for "/secured/**", why have we to use authenticated() for antMatcher("/secured/**") and for anyRequest() (and not permitAll() for anyRequest())?
Thank you.
The first step to understanding the issue here is understanding the difference between http.antMatcher() and http.authorizeRequests().
Let's look at the following configuration.
(I am using the lambda-style configuration, available as of Spring Security 5.2, to make it more readable)
#Override
public void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/secured/**")
.authorizeRequests(authorize -> authorize
.anyRequest().authenticated()
)
.oauth2Login(oauth2Login -> oauth2Login
.clientRegistrationRepository(clientRegistrationRepository())
.authorizedClientService(authorizedClientService())
);
}
Here, we are specifying that HTTP security will only be invoked when matching "/secured/**".
In other words, the request will only be processed by the SecurityFilterChain if it matches "/secured/**".
This is a problem because the SecurityFilterChain is what initiates the Authorization Request from "/oauth2/authorization/google".
However, the SecurityFilterChain is not called because "/oauth2/authorization/google" does not match "/secured/**".
Consider the following configuration instead.
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorize -> authorize
.antMatchers("/secured/**").authenticated()
.anyRequest().permitAll()
)
.oauth2Login(oauth2Login -> oauth2Login
.clientRegistrationRepository(clientRegistrationRepository())
.authorizedClientService(authorizedClientService())
);
}
Here, the HTTP security will be invoked for all requests.
However, only requests that match "/secured/**" will require the user to authenticate.
The answer of #eleftheria-stein-kousathana brought me to another possible solution.
As stated it is important to know that the OAuth Endpoints won't called because the security config for them is bound to the antMatcher() call directly following the HttpSecurity object.
But as stated in the docs you can also change the baseUris of the redirectionEndpoint and the authorizationEndpoint
#Override
public void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/secured/**")
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.oauth2Login()
//New Code Starting here
.authorizationEndpoint()
.baseUri("/secured/oauth2/authorization")
.and()
.redirectionEndpoint()
.baseUri("/secured/oauth2/code/*")
.and()
//new code ending here
.clientRegistrationRepository(clientRegistrationRepository())
.authorizedClientService(authorizedClientService());
}
Be sure to change the redirectUriTemplate of your clientRegistration and also the redirect uri configured at your AuthorizationServer
AND be sure to add the asterisk at the end of the redirectionEndpoint.baseUri ... that cost me some minutes to figure out what was wrong :-)

Disable Basic Authentication while using Spring Security Java configuration

I am trying to secure a web application using Spring Security java configuration.
This is how the configuration looks:-
#Configuration
#EnableWebMvcSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private String googleClientSecret;
#Autowired
private CustomUserService customUserService;
/*
* (non-Javadoc)
*
* #see org.springframework.security.config.annotation.web.configuration.
* WebSecurityConfigurerAdapter
* #configure(org.springframework.security.config
* .annotation.web.builders.HttpSecurity)
*/
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/","/static/**", "/resources/**","/resources/public/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.httpBasic().disable()
.requiresChannel().anyRequest().requiresSecure();
// #formatter:on
super.configure(http);
}
#Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
// #formatter:off
auth
.eraseCredentials(true)
.userDetailsService(customUserService);
// #formatter:on
super.configure(auth);
}
}
Notice that I have explicitly disabled HTTP Basic authentication using:-
.httpBasic().disable()
I am still getting HTTP Authenticaton prompt box while accessing a secured url. Why?
Please help me fix this.
I just want to render the default login form that comes bundled.
Spring Boot Starter Version : 1.1.5
Spring Security Version : 3.2.5
Thanks
First of all, calling super.configure(http); will override whole your configuration you have before that.
Try this instead:
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.httpBasic().disable();
In case you use Spring Boot, the documentation states:
To switch off the Boot default configuration completely in a web
application you can add a bean with #EnableWebSecurity
So if you want to fully customize itself that might be an option.
Just to make it clear... You just need to put #EnableWebSecurity annotation on your main application class or application configuration class.
You can disable the formLogin through the HttpSecurity instance as follow:
http.authorizeRequests().antMatchers("/public/**").permitAll()
.antMatchers("/api/**").hasRole("USER")
.anyRequest().authenticated()
.and().formLogin().disable();
This will lead receiving 403 Http error when trying to access any secured resource
Anonymous option worked for me. My code like
http.csrf().disable().headers().frameOptions().sameOrigin().and().
authorizeRequests().anyRequest().anonymous().and().httpBasic().disable();
Suitable for Spring Boot or folks using OAuth
#Profile("test")
#EnableWebSecurity
static class BasicWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().anyRequest().anonymous().and().httpBasic().disable();
}
}
If you are using #EnableOAuth2Client or #EnableResourceServer, then in test profile switch to basic auth and then disable the same. In Spring Boot,to switch off the spring security default configuration completely in a web application you need to add a bean with #EnableWebSecurity
The following worked for me:
http
.authorizeRequests()
.anyRequest().permitAll();

Spring Security 3.2.0RC2 logout url POST only?

I am experimenting with Spring Security 3.2.0.RC2 using javaconfig and it appears that the logout url is POST only. Is this by design and is there any way to make it logout a user with a GET request?
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**", "/signup", "/about", "/password").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated().and()
.formLogin()
.loginPage("/login")
.permitAll();
}
This is intentional and is documented within the CSRF documentation. The reason is to prevent CSRF attacks that forcibly log users out of your application. If you would like to support non-POST requests you can do so with the following Java Configuration:
protected void configure(HttpSecurity http) throws Exception {
http
// ...
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
}
You can also find information about configuring log out on the Javadoc of the LogoutConfigurer (i.e. the object returned by the http.logout() method).

Spring Security 3.2 setting authenticationEntryPoint in HttpSecurity has no effect (Java-Config)

I want to convert spring security configuration from xml to java config.
Is't nearly done, the last issue is the AuthenticationEntryPoint. The settings of it in HttpSecurity will be ignored.
I use Spring security 3.2.0.M2
Snipped of SecurityConfig.class
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterAfter(httpPayloadFilter(), ChannelProcessingFilter.class)
.addFilterAfter(httpRestLoginFilter(), SecurityContextPersistenceFilter.class)
.authorizeUrls()
.antMatchers("/**").hasRole("USER")
.antMatchers("/secure/clientident/**").hasRole("REQUESTVALID")
.and()
.httpBasic().authenticationEntryPoint(delegatingAuthenticationEntryPoint());
}
#Bean
public DelegatingAuthenticationEntryPoint delegatingAuthenticationEntryPoint() {
ELRequestMatcher matcher = new ELRequestMatcher("hasHeader('user-agent', 'Mozilla') or " +
"hasHeader('user-agent', 'Chromium') or " +
"hasHeader('user-agent', 'Chrome') or " +
"hasHeader('user-agent', 'Safari')");
LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> map =
new LinkedHashMap<RequestMatcher, AuthenticationEntryPoint>();
map.put(matcher, new BasicAuthenticationEntryPoint());
DelegatingAuthenticationEntryPoint delegatingAuthenticationEntryPoint = new DelegatingAuthenticationEntryPoint(map);
delegatingAuthenticationEntryPoint.setDefaultEntryPoint(new Http403ForbiddenEntryPoint());
return delegatingAuthenticationEntryPoint;
}
I always get the "HTTP 403" (guess Http403ForbiddenEntryPoint) on client side.
I also have tried an easier config without delegatingAuthenticationEntryPoint like.
.httpBasic().authenticationEntryPoint(new BasicAuthenticationEntryPoint())
this will not work too.
Has anyone an idea what I'm doing wrong?
Add:
Should have locked better. Found another post about this issue.
need spring security java config example showing basic auth only
A Ticket SEC-2198 has also been placed.
current workaround.
.exceptionHandling()
.authenticationEntryPoint(delegatingAuthenticationEntryPoint())
.and()
.httpBasic();

Resources