-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How-to: Implement multi-tenancy #663
Comments
@arfatbk Support for multi-tenancy would be implemented in a product implementation of an OAuth/OIDC server, e.g. Keycloak. This isn't a feature the framework would implement. I changed the title to a "How-to Guide" to see if there is demand from the community for this. If there is enough upvotes, we can consider adding a How-to guide. I would also recommend posting this question on Stack Overflow and linking the post back to this issue. |
Here's the stack overflow question related to this issue. It looks like I suggested @arfatbk open an issue. I think it's a good idea to see if the community has interest via upvotes (👍). |
@sjohnr Hi. Hope you are doing well. Actually I was implementing it and I stuck at a point. I am not sure it is right place to ask if I stuck at some point or what. Anyways for AuthorizationCode grant type flow. I am sending request parameter name tenantDatabaseName. What I did I added a filter in my AuthoirzationServer Configuration.
`
Now when request comes for authorization code grant type flow. This filter intercept the request. But in OAuth2AuthorizationEndpointFilter it is check if user is authenticated. The following line is present in OAuth2AuthorizationEndpointFilter.java's doFilterInternal() method
So now it throws the exception. Ultimately comes to LoginUrlAuthenticationEntryPoint and it redirects to Login Page using DefaultRedirectStrategy. As it is redirecting so now there is no tenantDatabaseName request parameter. But I overridden the method. Here what I did. Basically I am just appending the request parameter. So when it redirects I get the parameter.
Then in the Login controller I get the parameter.
Now I set it as a hidden form element. Then I created a custom filter. Added it before UsernamePasswordAuthrntiationFilter. I get the parameter value. I set it in the Thread Local Context and it works. I mean it connects to right database. Now after validating user it goes back to client and again comes to server with the tenantDatabaseName request paamter. But this time it shows the Consent page. Now here is the code in the OAuth2AuthorizationEndpointFilter. It can be seen that in the sendAuthorizationConsent() method it is adding request parameters client_id, scope and state. And I get these parameters in the Consent Controller.
My question is how can I customized the sendAuthorizationConsent() method so I can include my tenantDatabeName request parameter too. ? Is there any way that I can modify AuthorizationServer configuration or am I doing it in the right way. Is there any better way of doing it ? Like in the configuration we are customizing the consent page Is there similar way I can customize this ? If you can assist me it would be very helpful. Thanks |
@Basit-Mahmood, thanks for getting in touch, but it feels like this is a question that would be better suited to Stack Overflow. We prefer to use GitHub issues only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that other people can find it) and I will be happy to take a look. If you'd prefer to discuss the issue more to get ideas, I'd also be happy to discuss it with you on the #spring-security gitter channel. I should mention that I have not actually implemented SAS as a multi-tenant application either, so I can only provide ideas for you at the moment. |
@sjohnr Thank you so much for the reply. Yes I need your idea how to get through it. I remember when I was trying to implement password grant type then I stuck that how can I add Password Converter using the Authorization server configuration. Then you replied that I can either use the following code
or this
And this was very helpful. Similarly I want to ask is there any way that I can customize the OAuth2AuthorizationEndpointFilter using some AuthorizationServerConfiguration ? If there is any. If customizing is not possible in this version of Authorization Server Configuration. Then I think may be for now I can change the end point Actually I am asking it here because As Authorization Server Server is expanding. Which is very great. May be my question can trigger something that you guys think, ok we can include it in the later version of Authorization Server because it can be useful. Thanks |
Thanks @Basit-Mahmood. I appreciate how excited you are to contribute! I do want to be conscious of the fact that extended discussions about how to do something in your own application are often off-topic for the issue at hand, which feels like the case here at the moment. We could circle back to this issue with ideas we come up with together though. For now, please post a question on stackoverflow or start a thread on gitter and I will jump right in to discuss it with you! |
I expand the |
@zmlgit you can take a look at the stack overflow post Stack Overflow I described their that how to get the tenant Id for authorization code grant type flow when it redirects to login page and after login. May be it would help you. Thanks & Regards |
if it is still an issue for you, there is a way you can solve it. |
I successfully use the authorization server in a multitenant environment and now also want to use OpenId Connect functionality and struggle with what is currently offered for configuration. I encode the tenant name in the URL and for other projects like spring saml it is easy for me to implement multi-tenancy as all filters support to set a custom request matcher so I can e.g. set it to /oauth2/{tenantName}/authorize instead of the default /oauth2/authorize and there is some kind of resolver interface like Saml2AuthenticationRequestResolver that in the openid case would resolve the AuthorizationServerContext. Currently we have a final class AuthorizationServerSettings and a AuthorizationServerContextFilter were you can't influence how a AuthorizationServerContext is built. Also the filters don't support setting customing request matchers and use the settings from AuthorizationServerSettings (apart from OidcProviderConfigurationEndpointFilter). Without these changes at least I don't see how you can implement multi-tenancy without writing your own OidcProviderConfigurationEndpointConfigurer and rewriting a few filters. |
+1 |
@Yneth Can you please advise, How to retrieve this HTTP session object? |
@abilash-sethu
Then in any place of your service while the session is still active and you have access to HttpServletRequest, you can use the following function:
|
@Yneth Thank you so much for the quick response, This would really help. |
I am thinking of A single Authorization server in an organization providing identity federation for multiple clients(tenants), where tenant data should be isolated from each other.
Other OAuth servers like KeyCloak provide Multi-tenancy. https://www.keycloak.org/docs/latest/securing_apps/index.html#_multi_tenancy
One of the following approaches can be configured:
Separate Schema – one schema per tenant in the same physical database instance
Separate Database – one separate physical database instance per tenant
Partitioned (Discriminator) Data – the data for each tenant is partitioned by a discriminator value(ex. A column for tenant identifier)
Organization can choose which of the above approach is suitable for any given tenant. For example 'A' tenants wants it's data completed isolated and is ok with separate physical database. Where 'B' tenant is ok with separate schema in shared physical database etc.
I am not sure if it is in roadmap or as a framework we want to implement this. Can anyone please direct me to resources if you have one that would be awesome.
Thanks
Related gh-499
The text was updated successfully, but these errors were encountered: