Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 809
Peter Bierman Avatar asked Oct 18 '22 20:10

Peter Bierman


2 Answers

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.

like image 86
Appy Avatar answered Oct 21 '22 21:10

Appy


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

like image 35
Bassem Reda Zohdy Avatar answered Oct 21 '22 22:10

Bassem Reda Zohdy