Dev Sabby
Dev Sabby

Reputation: 1425

Basic Auth + oAuth Implementation in Spring Boot

I am trying to implement Basic Auth + oAuth2 in springboot, means some url should work like traditional way after login to system, and some should work on AOuth2.

Like I want to allow access to SuperAdmin for admin panel, with url starts from

/superAdmin/****

I just want to access all the these url after general login into the system.

and Rest service should work on AOuth2 with url starts form

/api/vi/****

these urls are use to give access to the applicants.

Separately both are working fine, but together both are not working.

here is my configurations.

import in.kpis.tracking.configuration.CustomAuthenticationSuccessHandler;
import in.kpis.tracking.service.AdminUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;

@Configuration
public class OAuth2ServerConfiguration {

    protected static final String RESOURCE_ID = "restservice";

    @Configuration
    @EnableResourceServer
    protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) {
            // @formatter:off
            resources.resourceId(RESOURCE_ID);
            // @formatter:on
        }

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests()
                    .antMatchers("/api/v1/*").hasRole("ADMIN")
                    .antMatchers("/greeting").authenticated();
        }
    }


    @Configuration
    public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {

        @Autowired
        private AdminUserService adminUserService;

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(adminUserService);
        }

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

    }

    @Configuration
    @Order(1)
    public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {

            String[] permitAll = new String[]{"/error"};
            String[] permitToSuperAdmin = new String[]{
                    "/superAdmin/*",
            };

            http.authorizeRequests()
                    .antMatchers(permitToSuperAdmin).access("hasRole('SUPER_ADMIN')")
                    .antMatchers("/login").permitAll()
                    .and().formLogin().loginPage("/userLogin.html")
                    .usernameParameter("username")
                    .passwordParameter("password")
                    .loginProcessingUrl("/login")
                    .successHandler(new CustomAuthenticationSuccessHandler())
                    .and()
                    .logout().logoutSuccessUrl("/userLogin.html?logout")
                    .deleteCookies("JSESSIONID")
                    .invalidateHttpSession(true);
            http.csrf().disable();
        }
    }
}

Upvotes: 14

Views: 10073

Answers (3)

ejazazeem
ejazazeem

Reputation: 551

This has been actually explained in Spring security Guide under Multiple HttpSecurity

@Configuration
@Order(1)                                                        2
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
    protected void configure(HttpSecurity http) throws Exception {
        http
            .antMatcher("/api/**")                               3
            .authorizeRequests()
                .anyRequest().hasRole("ADMIN")
                .and()
            .httpBasic();
    }
}

@Configuration                                                   4
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .formLogin();
    }
}

And to secure OAuth2 endpoints using Resource Server, you can configure your resource server as follows

@Configuration
@EnableResourceServer
@Order(1)
protected static class ResourceServerConfig extends ResourceServerConfigurerAdapter {



    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId("resource-id");
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.requestMatcher(new OAuthRequestedMatcher())
            .authorizeRequests().anyRequest().fullyAuthenticated();

    }
}

private static class OAuthRequestedMatcher implements RequestMatcher {
    public boolean matches(HttpServletRequest request) {
        String auth = request.getHeader("Authorization");
        boolean haveOauth2Token = (auth != null) && auth.startsWith("Bearer");
        boolean haveAccessToken = request.getParameter("access_token")!=null;
        return haveOauth2Token || haveAccessToken;
    }
}

Upvotes: 12

Kraken
Kraken

Reputation: 288

Great Question In order to use oAuth with spring security, I think it's there is no any way to use this. You need to create two different projects one is for general sec. and one is for oAuth.

Upvotes: -6

Ján Halaša
Ján Halaša

Reputation: 8421

If you need different security setups for different parts of your application, you need to create separate Spring Security @Configuration-s, where each one will configure just one authentication mechanism. Each configuration should specify the URIs it covers and the configurations need to be @Order-ed. The configuration without the @Order annotation is considered the last - the fallback. It's described in the Spring Security reference manual.

So you will need three configurations:

  1. One for the http.antMatcher("/superAdmin/**")... with @Order(1).
  2. One for the API http.antMatcher("/api/vi/**")... with @Order(2).
  3. A fallback config without authentication for other resources, without the @Order annotation specified.

Upvotes: 10

Related Questions