-1

I'm developing Spring boot and security web application with authorization and resource servers enabled. I have defined a set of users with roles assigned to them and have implemented roles based access to rest endpoints. Besides that my application has straightforward UI with web pages. Those pages display the same data that is on rest. I'm trying to implement the same roles based access to pages with ResourceServerConfig#configure and my current code:

public void configure(final HttpSecurity http) throws Exception {

        http.authorizeRequests()
                .antMatchers("/rest/products/add").hasAnyRole("ADMIN")
                .anyRequest().authenticated()

                .and().formLogin()
                .loginPage("/login.jsf").permitAll()
                .loginProcessingUrl("/login")
                .defaultSuccessUrl("/login-successful", true)
                .and().logout().permitAll();
    }

This configuration works perfectly for REST controllers access with bearer token, but authorization with the login form leads to the redirect to the /login-successful and the message
Full authentication is required to access this resourceunauthorized is displayed.

The reason is that SecurityContextHolder.getContext().getAuthentication() for /login-successful request in spite it was correctly initialized in AbstractAuthenticationProcessingFilter#successfulAuthentication at the point of login form post. The same issue with other web pages in my app as well.

What should be added to the above configuration so that make it work for the REST and form login bought ?

Here is indicted that HttpSecurity configuration provided above is enough for authorization with form login to work correctly as far as .anyRequest().authenticated() should pass security context for all the resources in the application.

A similar case is described here but the reason over there is that an url was explicitly ignored in WebSecurity configurer.

Dmitry
  • 11
  • 4

1 Answers1

1

The problem was in the fact that I was using deprecated @EnableResourceServer annotation that adds OAuth2AuthenticationProcessingFilter. For the form login authorization flow this is incorrect and that filter was removing authentication object from the SecurityContext. Here is indicated that OAuth2AuthenticationProcessingFilter shouldn't present in the filter chain for the form login authorization flow.

The reason why I was needed @EnableResourceServer annotation is that there are there is the bearer authentication flow in my application alongside with form login.

I replaced @EnableResourceServer annotation and ResourceServerConfigurerAdapter for the bearer authentication flow with Spring Security 5 resource server as http.oauth2ResourceServer() that is in WebSecurityConfigurerAdapter ( see here ). Finally the solution is with the following two WebSecurityConfigurerAdapter-s:

For bearer authorization flow:

@Configuration
@Order(2)
public class SecurityConfigRest extends WebSecurityConfigurerAdapter {

@Override
    protected void configure(HttpSecurity http) throws Exception {
        NimbusJwtDecoder jwtDecoder = Build custom JWT decoder;

    http.csrf().disable()
            .requestMatcher(new AntPathRequestMatcher("/rest/**"))
            .authorizeRequests()
            .mvcMatchers("/products/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated()
            .and()
            .oauth2ResourceServer().jwt().decoder(jwtDecoder);
}`

and for the form login authorization flow:

@Configuration
@Order(1)
@EnableWebSecurity
public class SecurityConfigFormLogin extends WebSecurityConfigurerAdapter {
 protected void configure(HttpSecurity http) throws Exception {
        http .requestMatcher(new AntPathRequestMatcher("/view/**"))
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin().loginPage("/view/login").permitAll()
                .defaultSuccessUrl("/view/login-successful", true)
        .and().logout()
                .logoutUrl("/view/perform_logout")
        .logoutSuccessUrl("/view/login");

    }

These two WebSecurityConfigurerAdapter-s make it possible to separate those two authorization flows.

As far as Spring Security 5 resource server supports only JWT or Opaque tokens ( see here ) it requires additional configuration. Here is a detailed description of such a configuration for Spring Security 5 resource server.

Dmitry
  • 11
  • 4