Skip to content
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

Document or fix classes to be tenant aware (GORM 6 multitenancy) #5

Open
bluesliverx opened this issue Oct 17, 2018 · 1 comment
Open

Comments

@bluesliverx
Copy link
Collaborator

bluesliverx commented Oct 17, 2018

To get this working, I had to override the default token store and provide my own implementation that was a direct copy of the GormTokenStoreService with two modifications:

  • The CurrentTenant annotation on the class
  • Move the Transactional annotation to the individual methods instead of on the class

It looks like the transactional annotation does its work before the CurrentTenant one (which is probably a bug and should be filed with Grails? Or maybe the order of the annotations matter here? I don't know), and causes problems.

It's possible that if we move the Transactional annotations to the class methods in the implementation in this plugin, a tenant aware version would be very simple to just extend and add the CurrentTenant annotation.

@bluesliverx
Copy link
Collaborator Author

I simplified the solution to this, at least for the password and refresh token flows (along with the typical access token resource protection). Only two classes needed to be overridden, and they do not have transactional annotations so it is much simpler. Also, none of the classes need methods implemented since they can just call the super class.

src/main/groovy/my/package/TenantAwareWrappedTokenEndpoint.groovy``

package my.package

import grails.gorm.multitenancy.CurrentTenant
import grails.plugin.springsecurity.oauthprovider.endpoint.WrappedTokenEndpoint
import org.springframework.http.ResponseEntity
import org.springframework.security.oauth2.common.OAuth2AccessToken
import org.springframework.web.HttpRequestMethodNotSupportedException
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.bind.annotation.RequestParam

import java.security.Principal

/**
 * Override of WrappedTokenEndpoint that has the current tenant set.
 */
@CurrentTenant
class TenantAwareWrappedTokenEndpoint extends WrappedTokenEndpoint {
	@Override
	public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal,
			 @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
		return super.postAccessToken(principal, parameters);
	}

	@RequestMapping(value = "/oauth/token", method= RequestMethod.GET)
	public ResponseEntity<OAuth2AccessToken> getAccessToken(Principal principal, @RequestParam
			Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
		return super.getAccessToken(principal, parameters)
	}
}

src/main/groovy/my/package/TenantAwareOAuth2AuthenticationProcessingFilter.groovy

package my.package

import grails.gorm.multitenancy.CurrentTenant
import groovy.util.logging.Slf4j
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter

import javax.servlet.FilterChain
import javax.servlet.ServletException
import javax.servlet.ServletRequest
import javax.servlet.ServletResponse

/**
 * Override of OAuth2AuthenticationProcessingFilter that has the current tenant set.
 */
@CurrentTenant
@Slf4j
class TenantAwareOAuth2AuthenticationProcessingFilter extends OAuth2AuthenticationProcessingFilter {
	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
			ServletException {
		super.doFilter(req, res, chain)
	}
}

resources.groovy


	// Override the default oauth 2 auth filter and token endpoint with a tenant aware versions
	tenantAwareOAuth2AuthenticationProcessingFilter(TenantAwareOAuth2AuthenticationProcessingFilter) {
		authenticationEntryPoint = ref('oauth2AuthenticationEntryPoint')
		authenticationManager = ref('oauth2AuthenticationManager')
		authenticationDetailsSource = ref('oauth2AuthenticationDetailsSource')
		tokenExtractor = ref('tokenExtractor')
	}
	springConfig.addAlias("oauth2ProviderFilter", "tenantAwareOAuth2AuthenticationProcessingFilter")
	tenantAwareWrappedTokenEndpoint(TenantAwareWrappedTokenEndpoint) {
		clientDetailsService = ref('clientDetailsService')
		tokenGranter = ref('oauth2TokenEndpointTokenGranter')
		OAuth2RequestFactory = ref('oauth2RequestFactory')
		OAuth2RequestValidator = ref('oauth2RequestValidator')
	}
	springConfig.addAlias("oauth2TokenEndpoint", "tenantAwareWrappedTokenEndpoint")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants