Peter Bierman
Peter Bierman

Reputation: 383

Spring boot: Securing api endpoint with oauth2 while having mvc UI pages

I'm trying to get a spring-boot mvc application working with standard login while exposing some API endpoints with oAuth2 security. Basically my requirements are as follows:

If a user hits the home page ("/") check if it's authenticated. If not show the login form, else show the home page. But a user should also be able to ask for an oauth authentication token and with that token acces /api/assignment/{id}.

I can get the standard login to work, and I can get the oauth2 to work but I can not get them to work together.

This is my configuration at the moment:

WebSecurityConfig

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private DataSource dataSource;

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);        
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {    
        auth.jdbcAuthentication().dataSource(this.dataSource).passwordEncoder(new BCryptPasswordEncoder());
    }
}

OAuth2Config

@Configuration
@EnableResourceServer
@EnableAuthorizationServer
public class OAuth2Config {

protected static final String RESOURCE_ID = "oauthdemo";

@Configuration
@EnableResourceServer
protected static class ResourceServer extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
      http          
      .httpBasic().disable()
      .authorizeRequests()
        .antMatchers("/js/**", "/css/**", "/images/**", "/webjars/**", "/login").permitAll()
          .anyRequest().authenticated()
          .and()
      .formLogin()
          .loginPage("/login")
          .permitAll()
          .and()
      .logout()
          .permitAll();

    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId(RESOURCE_ID);
    }
}


@Configuration
@EnableAuthorizationServer
protected static class AuthServer extends AuthorizationServerConfigurerAdapter {

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer.allowFormAuthenticationForClients();
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("client")
                .authorizedGrantTypes("password", "refresh_token")
                .authorities("ROLE_USER")
                .scopes("read")
                .resourceIds(RESOURCE_ID)
                .secret("secret").accessTokenValiditySeconds(3600);
    }

}

}

The problem is I always get the following error when trying to open the home page ("/")

<oauth>
<error_description>
Full authentication is required to access this resource
</error_description>
<error>unauthorized</error>
</oauth>

It does not redirect to the login page. I do not need this page to be protected by oauth2, but even if i go directly to the login page ("/login", which i can access) and supply credentials I still get the 'full authentication is required' error. Even though i disabled basic http authentication.

Does anyone know how to separate the normal user UI from the api endpoints that need to be protected by OAuth2?

Upvotes: 5

Views: 1493

Answers (2)

Bassem Reda Zohdy
Bassem Reda Zohdy

Reputation: 12942

Hi you have to specify filters used for each config in your case you need:

in web security configurtion

        http
        .authorizeRequests()
            .antMatchers("/api/**","/oauth/**")
            .permitAll()
            .and()
            .......

this will let web security bypass authorization/resource servers URLs

and in resource server security configuration

        http
        .antMatcher("/api/**")
            .authorizeRequests()
            .anyRequest()
            .authenticated();

this will let resource security bypass all URLs except "/api/**".

in this way you can ignore orders of configuration there is another option by make one of above actions and put its configuration in early order using @Order

Upvotes: 1

Appy
Appy

Reputation: 631

Can you try this

http          
      .authorizeRequests()
        .antMatchers("/js/**", "/css/**", "/images/**", "/webjars/**", "/login").permitAll()
         .antMatchers("/login").permitAll()
         .antMatchers("/home").authenticated();

Considering /home is a page that needs to be authorized.

Upvotes: 2

Related Questions