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

Creating tokens manually from admin interface #258

Closed
eshaan7 opened this issue Jun 17, 2020 · 9 comments
Closed

Creating tokens manually from admin interface #258

eshaan7 opened this issue Jun 17, 2020 · 9 comments
Labels

Comments

@eshaan7
Copy link

eshaan7 commented Jun 17, 2020

It would be great if the administrator user could create tokens for user from the django admin interface.

I have tried to implement this by overriding the default OutstandingTokenAdmin like this:

class OutstandingTokenForm(forms.Form):
    user = forms.ModelChoiceField(queryset=User.objects.all(), required=True, initial=1)

    def form_action(self, obj, user):
        sliding = SlidingToken.for_user(user)
        return sliding

class CustomOutstandingTokenAdmin(OutstandingTokenAdmin):
    form = OutstandingTokenForm

    def get_readonly_fields(self, *args, **kwargs):
        fields = [f.name for f in self.model._meta.fields]
        fields.remove('user')
        return fields

    def has_add_permission(self, *args, **kwargs):
        return True

admin.site.unregister(OutstandingToken)
admin.site.register(OutstandingToken, CustomOutstandingTokenAdmin)

But this does not work. I just want a simple select input to select a user and then a create button that adds a new token to OutstandingTokens.

Any help regarding this would be greatly appreciated.

@Andrew-Chen-Wang
Copy link
Member

Is there a reason for this? Yes, it's possible. You can find code here: https://github.com/SimpleJWT/django-rest-framework-simplejwt/blob/ce80c2d31f0d9aff6a246d30d9aaa27f1e57a364/rest_framework_simplejwt/tokens.py#L214

Actually returning the tokens in the interface is more of a Django issue. Imo, there is not good usage example for this (maybe for developing... but in that case just use curl)

@eshaan7
Copy link
Author

eshaan7 commented Jun 17, 2020

I need this because our project (https://github.com/intelowlproject/) has a CLI client and only the administrator should issue tokens to the user; since for added security, we have removed any endpoint for obtaining sliding token via basic auth. We are using the refresh-access token pair everywhere else.

PS: I was able to implement it. I have made a gist with the required code:

https://gist.github.com/Eshaan7/4485a089c4f51420067d3bcf0b5fa6ab

Hope it helps others too.

PS: Thankyou for this great library.

@eshaan7 eshaan7 closed this as completed Jun 17, 2020
@Andrew-Chen-Wang
Copy link
Member

@eshaan7 Ah I see! Consider OAuth (django-oauth-toolkit). Generally greater security if you know which endpoints certain users can be picking out. Although I'm slightly concerned that you're thinking about JWT incorrectly. Based on what you're saying, are you saying you're only using the regular access-refresh token pairs? Are you using this package for cross-domain usage? Is this for browser (if so, don't ref #71) or (mobile) client (which is ok)? What is the expiration period of those tokens?

If you need any help in your project regarding security or this package, just ping me! I'm happy to help.

Note: I'm not sure what a sliding token technically is. I'm aware that it came from a different JWT package, but Dave was considering removal in the future as this functionality was only meant to port users from one package to this one. Just a heads up.

@eshaan7
Copy link
Author

eshaan7 commented Jun 18, 2020

@Andrew-Chen-Wang Thanks for your interest.
Our project is not a Saas, it's a threat intelligence gathering tool that companies would integrate with their current set of security/incident response toolkit so ease-of-use is a big priority.

We have a web app in angular 9 that uses access-refresh token pair with rotation and blacklisting of old refresh tokens, and It works perfectly. In production, the angular and django both are served from same origin with nginx.
For the command line tool/ library that interacts with the server, we are considering using sliding tokens with values SLIDING_TOKEN_LIFETIME=30 minutes and SLIDING_TOKEN_REFRESH_LIFETIME=7days.... because:

  • easier for the administrator to just create a single token from admin interface and give it to the user.
  • this token would only expire if user doesn't use it for 7 days since last use.
  • main reason for using sliding here instead of access-refresh pair was because we could set a longer lifetime for sliding tokens and easily integrate it in the command line tool.

PS: IMO, django-oauth-toolkit is too advanced and heavy for our current usage.

@eshaan7
Copy link
Author

eshaan7 commented Jun 18, 2020

Just saw #154. This is a deal breaker, seems like we'd have to use access-refresh in the CLI tool as well. Is there a way to specify the lifetime of a token at creation without copying and modifying code from the library ?

@Andrew-Chen-Wang
Copy link
Member

Andrew-Chen-Wang commented Jun 18, 2020

tl;dr Shouldn't there be a library already for how to render your Angular code into HTML and then insert your Django templates with jinja2 very easily?

I don't believe so. When I was creating a websockets security guideline for Django, I couldn't use this library. However, you can use a bit of this library's code for similar purposes (i.e. low-level coding with the JWT package itself).

Otherwise, no. SimpleJWT is just that: simple. Extension of the library is fairly easy imo, but I dislike flexibility regarding security (which is one of the reasons there are new frameworks besides OAuth now for authorization... and Auth0 keeps getting ganged up on).

I've never seen a good third-party frontend framework be able to do a proper example of integrating with SimpleJWT without getting into JS, leaking a portion of code for XSS, simply storing in a local storage, etc. I'm no frontend coder, but when I was browsing some of those articles, someone mentioned Axios. There's someone who created a library for AWS deployment w/ vue; I believe when I was looking through his source code, he was using Axios. Didn't get the time to properly digest it, but hope that gives some sort of inspiration.

I'm curious how it'll work for you guys. I'll take a look at your source code and see if I can tap into wherever you store the tokens.

Shouldn't there be a library already for how to render your Angular code into HTML and then insert your Django templates with jinja2 very easily? I mean that's all frontend frameworks are right? Is it just hard to map out where these values are supposed to go?

Edit: ah It seems like you found Dave's comment too in 154 about not wanting to keep the sliding token feature. I'm just most worried about frontend devs with these JS frameworks continuously using this library...

@Andrew-Chen-Wang
Copy link
Member

@eshaan7 This may be of interest to you: https://www.valentinog.com/blog/drf/ I haven't gone through it all, but perhaps this is the way of going about JS? It takes advantage of session authentication, which is exactly what you need for a browser based app.

@eshaan7
Copy link
Author

eshaan7 commented Jun 20, 2020

SimpleJWT is just that: simple. Extension of the library is fairly easy

Yes, I was able to understand the codebase and extend it as per our requirements. Now, we are using access-refresh token pair in the web with a shorter lifetime whereas a longer lifetime for Refresh Tokens created from the admin interface (to be used with the CLI).

You are very welcome to look at the code. Here's the final PR: intelowlproject/IntelOwl#94

Shouldn't there be a library already for how to render your Angular code into HTML and then insert your Django templates with jinja2 very easily?

I don't think this can work because angular bundles your large application into smaller incomprehensible bundles of different .js files/modules. Also, the entire point of using a framework such as Angular 9 is so we don't have to write any templates in django or jinja2. Our django app therefore is a pure REST API that has no templates besides the default django's admin interface.

I've never seen a good third-party frontend framework be able to do a proper example of integrating with SimpleJWT without getting into JS, leaking a portion of code for XSS, simply storing in a local storage, etc.

Angular 2+ provides really good DOM sanitization for any kind of inputs/user content. Using best practices, XSS is something we don't need to worry about. You can look at the final angular code here as well.
Briefly, we are using localStorage and not sessionStorage because we want sessions to persist. Plus, since we are rotating both tokens momentarily + blacklisting old token immediately + good protection against XSS, I'd say it's quite secure especially for an internal application.

@Andrew-Chen-Wang
Copy link
Member

I see.

Should be fine then. SimpleJWT should be a secure package as itself; I just worry about a leaked package which could lead to a leaked SECRET_KEY with leaked OAuth credentials. Good luck!

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

No branches or pull requests

2 participants