Skip to content

Latest commit

 

History

History
508 lines (312 loc) · 11.9 KB

slides.md

File metadata and controls

508 lines (312 loc) · 11.9 KB

class: middle, center

#Token Based Authentication system using JWT By Jaysinh Shukla


Speacker Description

.center[Speaker Image]


Types of Authentication

  • Session / Cookie Authentication

  • Token Authentication


background-image: url(images/session_authentication_multiple_user.svg)

Session Authentication for Multiple User


Session or Cookie Authentication

  • Client sends authentication credentials (username and password) to Server.

  • Server verifies authentication credentials

    • if valid, assigns session storage, creates session id and returns session id to requested client.
  • Client stores session id probably at Cookie storage. This id is sent by client with every request. And from that session id user is identified further.

  • This allows to identified the same user from upcoming request without reasking user credentials.


Disadvantages of Session Authentication

  • Difficult to handle with Load balancer

  • Required high amount of resource(RAM without mass-storage) for maintaining huge amount of user session parallaly.

  • CORS doesn't work well with cookies

Birth of Token Authentication

  • Token based authentication are most popular authentication system for APIs.

  • Comparatively puts less load than Session authentication.

  • Best for

    • Scaling

    • Load balancer

  • No cookie, No CSRF protection.

  • Same API, Authentication will be used for Mobile and Front end app.


Algorithm of Token Authentication

  • Client sends authentication credentials.

  • Authentication credentials are varified by server. If valid Token is crated.

  • Token is logged to database and the token is sent back as authentication token

  • The client sends Token with every request to get verified.

  • Normally token is generated with random value and hashed with popular hashing algorithm.

  • Revoking access of specific Token by deactivating record at token table.


background-image: url(images/Normal_token_authentication.svg)


Example of authentication at Djnago Rest Framework

from rest_framework.authtoken.models import Token

token = Token.objects.create(user=...)
print token.key

Above code is used at authentication view where that token.key is returned if credentials are right.

Assuming random output 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b

Example of Client request using curl

curl -X GET http://127.0.0.1:8000/api/example/ -H 'Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b'

Example of Token Authentication at Django Rest Framework

@python_2_unicode_compatible
class Token(models.Model):
    """
    The default authorization token model.
    """
    key = models.CharField(_("Key"), max_length=40, primary_key=True)
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL, related_name='auth_token',
        on_delete=models.CASCADE, verbose_name=_("User")
    )
    created = models.DateTimeField(_("Created"), auto_now_add=True)

    class Meta:
        verbose_name = _("Token")
        verbose_name_plural = _("Tokens")

    def save(self, *args, **kwargs):
        if not self.key:
            self.key = self.generate_key()
        return super(Token, self).save(*args, **kwargs)

    def generate_key(self):
        return binascii.hexlify(os.urandom(20)).decode()

Problems, Problems every where

  • Impossible to

    • identify user from which client (like Angular App, Android App, etc) is authenticated with.

    • provide way of access control with respect to client.

    • judge that the token is valid by time or not.

    • predict for how much time token is valid for.

  • Difficult to

    • Scale because of having dependancy on database to authenticate client with each request

    • run authentication logic seperate from API server.

  • Quite difficult to

    • scale

    • identify when client is identified from multiple sources symentically.


Solution is awesome JWT!

  • Suggested pronunciation is "jot".

  • JSON Web Token is JSON based Web Authentication Token.

  • The token is a combination of three parts. Header, Claim set and Signature.

  • Each part of authentication token is encoded with base64url encoding and seperated with "."


background-image: url(images/JWT_token_authentication.svg)


Structure Of JSON Web Token

eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4
MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K2
7uhbUJU1p1r_wW1gFWFOEjXk
  • The token is containing three different part seperated with "."

  • Each part is encoded with base64url encoding.

  • The first part the .red[Red Part] is JOSE Header

  • The second part the .blue[Blue Part] is JWT Claim set

  • The third part the .green[Green Part] is JWT Signature

  • Base64URL(JOSE Header).Base64URL(JWT Claims).Base64URL(JWT Signatuer)


JOSE Header

eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9
  • Decoded with Base64 encoding:
  {
    "typ":"JWT",
    "alg":"HS256"
  }
  • Here,
    • typ defines type of the JSON Web Token. It is not optional.

    • alg represents type of algorithm used for signing the claim set.


JWT Claim-set

eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ
  • Decoding with Base64 encoding:
  {
    "iss":"joe",
    "exp":1300819380,
    "is_root":true
  }
  • Here,

    • iss is registered claim. It represents the name of Issuer of the token

    • exp is registered claim. It represents expiration time in format of Unix time

    • is_root is unregistred claim. User defined claim which can be presumed that it is considring user as root user.


JWT Signature

dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
  • Signature is MAC of encoded JOSE Header and encoded JWS Payload with the HMAC SHA-256 algorithm.

  • And then base64url encoding of that HMAC value.

  • This signature helps to verify the authenticity of the Token.


Generate JWT Token

  • Define secret key

  • Example using pyjwt

>>> import jwt
>>> token = jwt.encode({'user_id': 1}, '12345', algorithm='HS256')
>>> token
b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxfQ.0X_1nSfbSETzHhcoeywtv6zXXlQd13M3d0-su89rfvM'
  • Here, 12345 is considered as secret key and HS256 is the algorithm we are using.

Example of Verifying Token

# Assume token is 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxfQ.0X_1nSfbSETzHhcoeywtv6zXXlQd13M3d0-su89rfvM'
>>> jwt.decode(token, '12345', algorithms=['HS256'])
{'user_id': 1}
  • Here, 12345 is secret key.

JWT Authentication at Django

from django.contrib.auth import authenticate


class Login(View):

    def post(self, request, *args, **kwargs):
        username = request.POST.get('username')
        password = request.POST.get('password')
        user = authenticate(username=username, password=password)

        if user:
            payload = {
                'id': user.pk,
                'username': user.username,
                'staff': user.is_staff,
                'exp': datetime.utcnow() + EXPIRY_TIME
            }
            token = {'token': jwt.encode(payload, SECRET)}
            return HttpResponse(
              json.dumps(token),
              content_type="application/json"
            )
        else:
            return HttpResponse(
              json.dumps({'Error': "Invalid credentials"}),
              status=400,
              content_type="application/json"
            )

JWT Token Verification at Django

class JWT_AuthMiddleware(object):

    def _get_token(request=None):
        return request.META.get('HTTP_AUTHORIZATION') or request.GET.get('token')

    def process_request(self, request):
        token = self._get_token(request)
        try:
            payload = jwt.decode(token, SECRET)
            request.user = User.objects.get(
                username=payload.get('username'),
                pk=payload.get('id'),
                is_active=True
            )
        except jwt.ExpiredSignature, jwt.DecodeError, jwt.InvalidTokenError:
            return HttpResponse({'Error': "Token is invalid"}, status="403")
        except User.DoesNotExist:
            return HttpResponse({'Error': "Internal server error"}, status="500")

Still it is not over!

  • If user is logged out, then also the token will be accepted until it is expired by time.

  • For Example, We assigned the token to "X" user and assigned the expire time to next 3 days and user is logged out after 1 day, that token can be used by attacker for that unused 2 days and API will consider Token as valid.

  • As a best practice, set expiry time not longer than 10 minutes!

  • As a good practice keep less values in claim. Adding many claims may increase size of token which takes time to transfer the token.

  • Change your Secret key periodically and Black list tokens if possible.


What we are doing with JWT

  • Creating JWT token

  • Validating Token at every request.

  • Allowing user to refresh token if given Token is valid.

  • If user is logging out then creating entry of token to Black list table

  • Advantage:

    • Token will not be used further if it is Black listed even in the valid time frame.

background-image: url(images/Our_token_authentication.svg)


JWT Claims

  • Types of Claims

    1 Registered Claim Names

    2 Public Claim Names

    3 Private Claim Names


JWT Registered Claim names

  • iss: Dipicting Issuer of the token

  • sub: Subject of the Token

  • aud: Audiance for which token is given for

  • exp: Expiration time in Unix time.

  • nbf: Token should not be accepted before this value. In Unix time format

  • iat: Representing age of the token

  • jti: Dipicting ID of the token


JWT Public Claim names


JWT Private Claim names

  • Custom claims which are not publicly used but represented as claims in JWT.

  • This custom claims should be considered as private claims.


Similar Technologies

1 Simple Web Token

2 JSON Simple Singh


Why not to go with Oauth 2.0?

  • Oauth 2.0 uses JWT as token exchange standard.

  • But Oauth 2.0 is more focused for three parties. Resource owner, Authorization Server, Resource Server

  • Using JWT is simple and more efficient when focus is only authentication.

  • OAuth 2.0 contains many payload values which will increase the size of token.


References