1

In my Spring Boot application I have a single back-end application that exposes REST API.

I'm going to consume this API from different client applications(for example written in AngularJS).

Based on different OAuth2 clientId I'd like to allow or restrict user access to different functionalities or data how it was described in my previous question Spring OAuth 2 + Spring Data Neo4j multi-tenancy

For example I have 3 different web domains:

example1.com
example2.com
example3.com

and for domain example1.com I'd like to allow user login only with clientapp1

My current login url:

http://localhost:8080/oauth/authorize?response_type=token&client_id=clientapp1&redirect_uri=http%3A%2F%2Flocalhost%3A8080

In my Spring OAuth2 server(with JWT tokens) I have configured multiple clients - clientapp1, clientapp2, clientapp3

@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        // @formatter:off
        clients
            .inMemory()
                .withClient("clientapp1")
                    .authorizedGrantTypes("password","refresh_token")
                    .authorities("ROLE_CLIENT")
                    .scopes("read", "write")
                    .resourceIds(RESOURCE_ID)
                    .secret("123456")
                .and()
                .withClient("clientapp2")
                    .authorizedGrantTypes("implicit")
                    .scopes("read", "write")
                    .autoApprove(true)
                .and()
                .withClient("clientapp3")
                    .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
                    .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
                    .scopes("read", "write", "trust")
                    .accessTokenValiditySeconds(60);
        // @formatter:on
    }

}

The issue is that right now any user in the system can login into the applications with any clientId and thus can use for example domain3.com with clientapp1

I need the following behavior:

REST API calls from domain1.com must be only allowed with OAuth2 JWT token only with clientapp1 inside, for domain2.com only with clientapp2 and so on.

How to configure my application in order to be able only login user with a correct clientId for appropriate domain ?

Is it safe to store and directly use clientId value on client side(in user browser) ?

Also, if my approach is wrong - please suggest how to correctly implement multi-tenancy with OAuth2.

Community
  • 1
  • 1
alexanoid
  • 24,051
  • 54
  • 210
  • 410
  • oAuth2 is a system where a user (a resource owner) can allow one client to access data (resources) belonging to that user available in another client. Example a user "owns" a list over his friends on Facebook. With oAuth2, the user can allow a third party wen application to access his Facebook friends list. I don't see that this is what you are trying to achieve, and in that case the oAuth2 solution is probably not your best choice. And no, you cannot store a client secret in a web app. It is not safe there. The client in oAuth2 is NOT a User Agent, it is another third party (often BE) app. – Andreas Lundgren Oct 25 '16 at 19:22
  • Thanks for your answer. It is not the client secret - it is a client id – alexanoid Oct 25 '16 at 19:32
  • Ah, sorry! Just be aware that public connections with a clientID cannot be used for any security, this can be altered in the request. ClientID is not meant to be used as an id for different web or native apps, but for other applications. If you for example would allow your users to login via Facebook, you will receive I Client Id from Facebook to identify your web service. (Your end users normally never sees your Client Id or Secret.) – Andreas Lundgren Oct 25 '16 at 19:39
  • Can't you just sign your JWTs with different secrets for different clients? – Andreas Lundgren Oct 25 '16 at 19:46
  • I think it is possible, but how it will help ? Also, I planned to use the single BE application with own OAuth2 server and multiple AngularJS applications without own BEs.They will directly call RESTful API from common BE. Users will authenticate/authorize via OAuth2 server of this BE application. Is there any chance to get this idea working ? – alexanoid Oct 25 '16 at 20:03
  • 1
    I'm not an expert so I will lean this unanswered, let's hope you get a real answer. It is very hard for a web client to identifies itself in a way that cannot be manipulated. Edge case is that a third party writes a client to your API. And oAuth2 will not assist you here in any way. A proprietary field in your JWT telling what client was used for signing in is probably safer since it is signed. But that will not protect you from third party clients or from someone moving a JWT from one client to another. – Andreas Lundgren Oct 25 '16 at 20:31
  • Yeah.. this is the biggest issue.. how to check that JWT is not moved from another client.. I think some extra logic should be added at BE in order to validate that the request was made from the client(based on the domain ?) which is allowed to use this clientId inside of this JWT.. Is any chance to get this logic done based on Spring Security/oAuth2 functionality out of the box ? – alexanoid Oct 26 '16 at 07:04
  • 1
    Notting that I've ever seen. You can set a proprietary field in your response with Target Client, and if clientapp A gets a response aimed for clientapp B, it discards the response. Not helping of someone writes a third party client towards your api though. (And with clientapp I mean the JavaScript application running in the Use Agent, not Client as specified in the oAuth2 spec.) – Andreas Lundgren Oct 26 '16 at 07:17

0 Answers0