You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

oauth_service.py 1.9KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import json
  2. import uuid
  3. from core.plugin.impl.base import BasePluginClient
  4. from extensions.ext_redis import redis_client
  5. class OAuthProxyService(BasePluginClient):
  6. # Default max age for proxy context parameter in seconds
  7. __MAX_AGE__ = 5 * 60 # 5 minutes
  8. __KEY_PREFIX__ = "oauth_proxy_context:"
  9. @staticmethod
  10. def create_proxy_context(user_id: str, tenant_id: str, plugin_id: str, provider: str):
  11. """
  12. Create a proxy context for an OAuth 2.0 authorization request.
  13. This parameter is a crucial security measure to prevent Cross-Site Request
  14. Forgery (CSRF) attacks. It works by generating a unique nonce and storing it
  15. in a distributed cache (Redis) along with the user's session context.
  16. The returned nonce should be included as the 'proxy_context' parameter in the
  17. authorization URL. Upon callback, the `use_proxy_context` method
  18. is used to verify the state, ensuring the request's integrity and authenticity,
  19. and mitigating replay attacks.
  20. """
  21. context_id = str(uuid.uuid4())
  22. data = {
  23. "user_id": user_id,
  24. "plugin_id": plugin_id,
  25. "tenant_id": tenant_id,
  26. "provider": provider,
  27. }
  28. redis_client.setex(
  29. f"{OAuthProxyService.__KEY_PREFIX__}{context_id}",
  30. OAuthProxyService.__MAX_AGE__,
  31. json.dumps(data),
  32. )
  33. return context_id
  34. @staticmethod
  35. def use_proxy_context(context_id: str):
  36. """
  37. Validate the proxy context parameter.
  38. This checks if the context_id is valid and not expired.
  39. """
  40. if not context_id:
  41. raise ValueError("context_id is required")
  42. # get data from redis
  43. data = redis_client.getdel(f"{OAuthProxyService.__KEY_PREFIX__}{context_id}")
  44. if not data:
  45. raise ValueError("context_id is invalid")
  46. return json.loads(data)