# JWT and Juniper?

**URL:** <https://discuss.openedx.org/t/jwt-and-juniper/864>\
**Category:** Releases\
**Tags:** juniper\
**Created:** [November 18, 2019, 5:48pm UTC](https://discuss.openedx.org/t/jwt-and-juniper/864 "2019-11-18T17:48:19Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![sambapete](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/sambapete/32/4100_2.png) [@sambapete](https://discuss.openedx.org/u/sambapete)\
**Post date:** [November 18, 2019, 5:48pm UTC](https://discuss.openedx.org/t/jwt-and-juniper/864/1 "2019-11-18T17:48:19Z")

</div>

There is one thing for which I would really like “documentation” when we will be testing Juniper.

How do we create the different JWT ?  
What values do we put where in lms.env.json, cms.env.json or anywhere else ?

A written almost real-life example would definitely benefit me or other operators in the Open edX community.

Or maybe it is simply me not understanding how to create the tokens and where each value created fits in the different JSON files. I hope I am not alone in this situation…

---

<div class="post-metadata">

**Author:** ![sambapete](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/sambapete/32/4100_2.png) [@sambapete](https://discuss.openedx.org/u/sambapete)\
**Post date:** [November 18, 2019, 6:20pm UTC](https://discuss.openedx.org/t/jwt-and-juniper/864/2 "2019-11-18T18:20:09Z")

</div>

I should probably add some background.

I recently tried installing a version of “master” for Open edX. I needed to test something without our fork.

Normally, at least with ironwood and previous open-releases, after installation I can login as [audit@example.com](mailto:audit@example.com), [staff@example.com](mailto:staff@example.com) and a few other users. Now, I can’t…

Looking at /edx/var/log/lms/edx.log I see the following error messages whenever I try to log in with these users:

```auto
Nov 18 17:15:09 ip-10-0-0-208 [service_variant=lms][django.request][env:sandbox] ERROR [ip-10-0-0-208 19883] [user None] [exception.py:135] - Internal Server Error: /user_api/v1/account/login_session/
Traceback (most recent call last):
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 249, in _legacy_get_response
    response = self._get_response(request)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/utils/decorators.py", line 185, in inner
    return func(*args, **kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/views/generic/base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/utils/decorators.py", line 67, in _wrapper
    return bound_func(*args, **kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/views/decorators/debug.py", line 76, in sensitive_post_parameters_wrapper
    return view(request, *args, **kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/utils/decorators.py", line 63, in bound_func
    return func. __get__ (self, type(self))(*args2, **kwargs2)
  File "/edx/app/edxapp/edx-platform/openedx/core/djangoapps/user_authn/views/login.py", line 433, in dispatch
    return super(LoginSessionView, self).dispatch(request, *args, **kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/rest_framework/views.py", line 494, in dispatch
    response = self.handle_exception(exc)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/rest_framework/views.py", line 454, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/rest_framework/views.py", line 491, in dispatch
    response = handler(request, *args, **kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/utils/decorators.py", line 67, in _wrapper
    return bound_func(*args, **kwargs)
  File "/edx/app/edxapp/edx-platform/openedx/core/lib/api/view_utils.py", line 371, in _wrapped
    return func(request)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/utils/decorators.py", line 63, in bound_func
    return func. __get__ (self, type(self))(*args2, **kwargs2)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/utils/decorators.py", line 67, in _wrapper
    return bound_func(*args, **kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/utils/decorators.py", line 149, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/utils/decorators.py", line 63, in bound_func
    return func. __get__ (self, type(self))(*args2, **kwargs2)
  File "/edx/app/edxapp/edx-platform/openedx/core/djangoapps/user_authn/views/login.py", line 429, in post
    return shim_student_view(login_user, check_logged_in=True)(request)
  File "/edx/app/edxapp/edx-platform/openedx/core/djangoapps/user_authn/views/login.py", line 501, in _inner
    response = view_func(request)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/utils/decorators.py", line 149, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/edx/app/edxapp/edx-platform/openedx/core/djangoapps/user_authn/views/login.py", line 362, in login_user
    return set_logged_in_cookies(request, response, possibly_authenticated_user)
  File "/edx/app/edxapp/edx-platform/openedx/core/djangoapps/user_authn/cookies.py", line 151, in set_logged_in_cookies
    _create_and_set_jwt_cookies(response, request, cookie_settings, user=user)
  File "/edx/app/edxapp/edx-platform/openedx/core/djangoapps/user_authn/cookies.py", line 260, in _create_and_set_jwt_cookies
    jwt = _create_jwt(request, user, expires_in)
  File "/edx/app/edxapp/edx-platform/openedx/core/djangoapps/user_authn/cookies.py", line 280, in _create_jwt
    return create_jwt_from_token(access_token, DOTAdapter(), use_asymmetric_key=True)
  File "/edx/app/edxapp/edx-platform/openedx/core/djangoapps/oauth_dispatch/jwt.py", line 73, in create_jwt_from_token
    filters=oauth_adapter.get_authorization_filters(client),
  File "/edx/app/edxapp/edx-platform/openedx/core/djangoapps/oauth_dispatch/jwt.py", line 134, in _create_jwt
    return _encode_and_sign(payload, use_asymmetric_key, secret)
  File "/edx/app/edxapp/edx-platform/openedx/core/djangoapps/oauth_dispatch/jwt.py", line 214, in _encode_and_sign
    serialized_keypair = json.loads(settings.JWT_AUTH['JWT_PRIVATE_SIGNING_JWK'])
  File "/usr/lib/python2.7/json/ __init__.py", line 339, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python2.7/json/decoder.py", line 364, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode
    raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded

```

It seems there is a problem with the default values in /edx/app/edxapp/lms.env.json and /edx/app/edxapp/cms.env.json and I would really like to put correct values so that I could log in.

Any ideas?

---

<div class="post-metadata">

**Author:** ![nedbat](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/nedbat/32/3317_2.png) [@nedbat](https://discuss.openedx.org/u/nedbat)\
**Post date:** [January 2, 2020, 6:50pm UTC](https://discuss.openedx.org/t/jwt-and-juniper/864/4 "2020-01-02T18:50:16Z")

</div>

@sambapete is this still an issue, or was it related to the json/yaml configuration change?

---

<div class="post-metadata">

**Author:** ![sambapete](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/sambapete/32/4100_2.png) [@sambapete](https://discuss.openedx.org/u/sambapete)\
**Post date:** [January 2, 2020, 7:08pm UTC](https://discuss.openedx.org/t/jwt-and-juniper/864/5 "2020-01-02T19:08:26Z")

</div>

No longer an issue as I found a way to generate the keys afterwards. We can close this issue.

---

<div class="post-metadata">

**Author:** ![nedbat](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/nedbat/32/3317_2.png) [@nedbat](https://discuss.openedx.org/u/nedbat)\
**Post date:** [January 2, 2020, 7:33pm UTC](https://discuss.openedx.org/t/jwt-and-juniper/864/6 "2020-01-02T19:33:32Z")

</div>

Can you help me with how to help other people with this? Should there be any code changes? Doc changes?

---

<div class="post-metadata">

**Author:** ![sambapete](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/sambapete/32/4100_2.png) [@sambapete](https://discuss.openedx.org/u/sambapete)\
**Post date:** [January 3, 2020, 2:57pm UTC](https://discuss.openedx.org/t/jwt-and-juniper/864/7 "2020-01-03T14:57:19Z")

</div>

You can find a potential solution for Problem B (the generation of JWT keys) under [Juniper Alpha basic installation](https://discuss.openedx.org/t/juniper-alpha-basic-installation/1068)

---

<div class="post-metadata">

**Author:** ![nedbat](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/nedbat/32/3317_2.png) [@nedbat](https://discuss.openedx.org/u/nedbat)\
**Post date:** [January 10, 2020, 9:28pm UTC](https://discuss.openedx.org/t/jwt-and-juniper/864/9 "2020-01-10T21:28:00Z")

</div>

This is the answer from the other post:

> [@Juniper Alpha basic installation](https://discuss.openedx.org/t/juniper-alpha-basic-installation/1068/2):
>
> I might have a follow-up questions with regards to /edx/etc/lms.yml and /edx/app/edxapp/lms.env.json, but for now I was able to add the correct values in /edx/etc/lms.yml.
> 
> I first had to run the following commands:  
> sudo -H -u edxapp bash  
> cd ~  
> source edxapp\_env  
> source venvs/edxapp/bin/activate  
> cd edx-platform  
> python manage.py lms generate\_jwt\_signing\_key
> 
> The last command generates values for JWT\_PUBLIC\_SIGNING\_JWK\_SET, JWT\_PRIVATE\_SIGNING\_JWK and JWT\_SIGNING\_ALGORITHM that needs to be filled in into /edx/etc/lms.yml.
> 
> And after restarting the LMS and the CMS, I was able to login again with my regular user in the LMS and the CMS.
> 
> I don’t know, if this is the “official” solution but it did work for me.

I will investigate whether there is a better answer than this.

---

<div class="post-metadata">

**Author:** ![nimisha](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/nimisha/32/1511_2.png) [@nimisha](https://discuss.openedx.org/u/nimisha)\
**Post date:** [February 1, 2020, 7:54pm UTC](https://discuss.openedx.org/t/jwt-and-juniper/864/10 "2020-02-01T19:54:30Z")

</div>

Yes, that is an appropriate solution. That management command generates the keys that you need to sign and verify JWTs. For security reasons, we need each installation to generate its own set of keys so we do not ship with default values.

Is there a place in the Juniper installation process where running the management command and copying over the keys can be automated? Or can automation of this be tackled by the build-test-release working group?

---

<div class="post-metadata">

**Author:** ![nedbat](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/nedbat/32/3317_2.png) [@nedbat](https://discuss.openedx.org/u/nedbat)\
**Post date:** [February 1, 2020, 9:58pm UTC](https://discuss.openedx.org/t/jwt-and-juniper/864/11 "2020-02-01T21:58:10Z")

</div>

There is a generate-passwords.sh step in the Native installation. We can add more to it.

> <https://github.com/edx/configuration/blob/master/util/install/generate-passwords.sh>

@nimisha Who can help with the details?

---

<div class="post-metadata">

**Author:** ![jill](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/jill/32/3188_2.png) [@jill](https://discuss.openedx.org/u/jill)\
**Post date:** [April 23, 2020, 4:02am UTC](https://discuss.openedx.org/t/jwt-and-juniper/864/12 "2020-04-23T04:02:16Z")

</div>

Looks like the docs for this question have been added to the [Juniper Confluence](https://openedx.atlassian.net/wiki/spaces/COMM/pages/940048716/Juniper) under **Django Configuration and SetUp** thank you!

@sambapete Can this post be marked SOLVED and [CRI-173](https://openedx.atlassian.net/browse/CRI-173) closed?

---

<div class="post-metadata">

**Author:** ![nedbat](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/nedbat/32/3317_2.png) [@nedbat](https://discuss.openedx.org/u/nedbat)\
**Post date:** [April 23, 2020, 2:00pm UTC](https://discuss.openedx.org/t/jwt-and-juniper/864/13 "2020-04-23T14:00:10Z")

</div>

Should (can?) this be automated in the Native install? Or do we need to add more steps there?

---

<div class="post-metadata">

**Author:** ![sambapete](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/sambapete/32/4100_2.png) [@sambapete](https://discuss.openedx.org/u/sambapete)\
**Post date:** [April 23, 2020, 7:03pm UTC](https://discuss.openedx.org/t/jwt-and-juniper/864/14 "2020-04-23T19:03:02Z")

</div>

I am in favour of both closing it and automating it in the Native install. I am afraid that if it isn’t automated people will ask again and again and again why they can’t login to their site anymore or where to find the instructions. Not everyone has the same technical background as you @nedbat or @jill or me @sambapete

Just my 2 canadian cents. If found a piggy bank full of them while cleaning up my apartment recently. We do not have a cent currency in Canada for the last few years.
