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

How to create a SSO service? #28

Open
kinwoon opened this issue Sep 3, 2021 · 4 comments
Open

How to create a SSO service? #28

kinwoon opened this issue Sep 3, 2021 · 4 comments

Comments

@kinwoon
Copy link

kinwoon commented Sep 3, 2021

  • Is there any specific way to create the service?
  • How to create the Standalone server callback url in Django in this example?
@Vibhu-Agarwal
Copy link
Owner

Vibhu-Agarwal commented Sep 6, 2021

Hey @kinwoon, I'm assuming that you've watched my PyCon talk.
If you haven't, please watch it. It'll help you understand how this project is set up.
If you have already, thanks a lot for attending my talk :)

Is there any specific way to create the service?

If you're following a particular protocol (like OAuth), you have to follow its guidelines. In this repository, as discussed in the talk, a custom implementation has been done, which doesn't fully comply with any standard protocol, but did the job for us. If you have to develop a Stand-Alone-Service corresponding to the SSO given in this repository, you've got to keep the public key of SSO with the Stand-Alone-Service, and you've got to set up the Service (model) instances (on SSO side) properly in order to maintain licence management stuff.

How to create the Standalone server callback url in Django in this example?

For SSO given in this repository, I've provided the Stand-Alone-Service implementation as well.
I've pointed out the implementation below:

path('user/create/', UserCreateAPIView.as_view(), name='user-create-callback-url'),

class UserCreateAPIView(CreateAPIView):
permission_classes = (IsAuthenticated, IsSSOAdmin,)
authentication_classes = (JWTTokenUserAuthentication,)
serializer_class = UserSerializer

class IsSSOAdmin(BasePermission):
"""
Custom permission to only allow owners of an object to edit it.
"""
def has_permission(self, request, view):
try:
assert request.user and request.user.is_authenticated
if request.auth.payload.get('sso_admin'):
return True
user = request.user
if isinstance(request.user, TokenUser):
user_set = User.objects.filter(id=user.id)
if user_set.exists():
user = user_set.first()
else:
return False
return user.email == SSO_ADMIN_EMAIL
except AssertionError:
return False

@kinwoon
Copy link
Author

kinwoon commented Sep 6, 2021

Hi @Vibhu-Agarwal,

The talk is great. I tried to follow the protocol as you described. Both private and public keys pair is generated on the SSO side and public key is retrieved on the Standalone server (Client server).

Basically, I tried to run the .json file that you have provide in the SSO branch. I could not run the "List and Create Services" and "Create Connection" that keep returns 400 Bad Request response status. Currently, I am not sure what is wrong with my Standalone Service. I have tried user creation in Standalone Service via Postman. It seem possible. However, service creation in SSO seem not possible as the problem might been in the callback-url. In the observation, the code always falls into:
if not response.ok:
raise APIException(f"Call to Service ({service}) Failed!"
f"Returned with status code: {response.status_code}")

I appreciate your advice. Thank you in advance.

@Vibhu-Agarwal
Copy link
Owner

The lines you're pointing to, are used here:

response = requests.post(service.callback_url, data=user_data, headers=headers)
if not response.ok:
raise APIException(f"Call to Service ({service}) Failed!"
f"Returned with status code: {response.status_code}")

... which, in turn, is being used here while saving Service (model) instances
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
if self._state.adding:
make_request_to_callback_url(self)

It seems odd that user creation on the stand-alone-service is working but the same thing through SSO is not.
Try to print out the arguments passed in line 24 above to see how the callback URL is being called.
Also if you can, please show me the logs of both SSO and StandAloneService.

PS. If you're running the SSO and StandAloneService on localhost, check if you've put the correct address of StandAloneService in the callback URL, which in this case, would differ from SSO by the port number.

@eznix86
Copy link

eznix86 commented May 2, 2022

This is SSO part:

Screenshot 2022-05-02 at 18 46 43

This is Debug tool bar for Standalone app
Screenshot 2022-05-02 at 22 02 11

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

No branches or pull requests

3 participants