Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Spring Boot 2 OAuth Client and Resourceserver in the same context

I'd like my spring boot application to serve a protected frontend, as well as being an API resource server for said frontend at the same time, but I can't get the oauth stuff working.

What I want is the spring boot application to return a 302 redirect to the oauth server (gitlab in my case) when the browser requests the index.html without a token, so the user is sent to the login form. But I also want that the API to return a 401 when the API is called without a token, as I think a 302 redirect to a login page is not very useful there.

In pseudo code:

if document_url == /index.html and token not valid
  return 302 https//gitlab/loginpage
if document_url == /api/restcall and token not valid
  return 401
server document_url

I am working with spring boot 2.1, regarding oauth my pom.xml contains

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-client</artifactId>
    </dependency>

This is my naive try in the SecurityConfig

public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests().antMatchers("/index.html").authenticated()
        .and()
            .oauth2Login().loginPage("/oauth2/authorization/gitlab")

        .and()
            .authorizeRequests().antMatchers("/api/restcall").authenticated()
        .and()
            .oauth2ResourceServer().jwt();
    }
}

Both configurations (oauth2Login and oauth2ResourceServer) work fine for themself. But as soon as I combine them the last one wins (so in the above example there would be no 302 and the browser would also see a 401 for the index.html). I presume they share some configuration objects so the last write wins.

Is there an (easy) way to get what I want? I know spring can do almost anything, but I would very much not to end up manually configuring a gazillion beans ...

Update:

I've made a minimal example (including @dur's suggestion) of my code here

like image 746
schrom Avatar asked Nov 11 '19 16:11

schrom


People also ask

Can authorization server and resource server be the same?

The Oracle API Gateway can be used as an Authorization Server and as a Resource Server. An Authorization Server issues tokens to client applications on behalf of a Resource Owner for use in authenticating subsequent API calls to the Resource Server.

How does OAuth2 2.0 work in spring boot?

Spring Security OAuth2 − Implements the OAUTH2 structure to enable the Authorization Server and Resource Server. Spring Security JWT − Generates the JWT Token for Web security. Spring Boot Starter JDBC − Accesses the database to ensure the user is available or not. Spring Boot Starter Web − Writes HTTP endpoints.

Is OAuth2RestTemplate deprecated?

RELEASE classes such as OAuth2RestTemplate , OAuth2ProtectedResourceDetails and ClientCredentialsAccessTokenProvider have all been marked as deprecated.


1 Answers

You need to create multiple configurations and restrict them only to specific URL patterns using requestMatcher. Based on your example, your configurations should look like this:

SecurityConfigHTML

public class SecurityConfigHTML extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .requestMatchers().antMatchers("/index.html")
                .and()
                .authorizeRequests().anyRequest().authenticated()
                .and()
                .oauth2Login().loginPage("/oauth2/authorization/gitlab");
    }
}

SecurityConfigAPI

public class SecurityConfigAPI extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .requestMatchers().antMatchers("/api/call")
                .and()
                .authorizeRequests().anyRequest().authenticated()
                .and()
                .oauth2ResourceServer().jwt();
    }
}
like image 68
Anar Sultanov Avatar answered Oct 22 '22 17:10

Anar Sultanov