Skip to content

Authentication Authorization plan for time tracker project

Juan Gabriel Guzman edited this page Apr 13, 2020 · 1 revision

Original document

OVERVIEW

Time tracker is an application intended to help ioet members to keep track of the activities they do during the work day. It is currently being built and one of the requirements this application has is that it must be secured so that only allowed members are able to use it. This document proposes a mechanism for securing this application.

GOALS

  1. Share with the team the strategy to handle authentication and authorization inside the time tracker app.
  2. Define a plan to adopt the auth strategy into the time tracker application.

BIG PICTURE OF THE APPLICATION

This application mainly consists of a frontend application built as a SPA and a backend application built on top of flask framework and deployed as a docker container. This is a common architecture and there are well-defined strategies to implement authentication/authorization around the architecture this application has. Going through the OAuth2 documentation the approach we can include in our application is Implicit grant flow.

IMPLICIT GRANT FLOW

This diagram shows the flow the application must follow to implement the implicit grant flow. Below, this flow is detailed:

  1. The SPA redirects the user to sign in using the ID server (Google).
  2. The ID server shows the users a page where they can enter their credentials.
  3. If the credentials are correct, the ID server returns an ID token.
  4. The ID token is used to contact Azure AD B2C and receive an access token. The access token contains the user’s information including their custom attributes
  5. The SPA calls the web API to get/set the information the users demand/send.
  6. The call is intercepted by the API gateway solution Azure offers ( Azure API management).
  7. The API management using policies grants access to the backend checking the access token included as part of the request sent from the SPA.

AUTHORIZATION

The access token is going to contain all the info related to the user. This access token is going to be a JWT [RFC 7519]. This is an example of a decoden JWT.

{ "exp": 1586215102, "nbf": 1586211502, "ver": "1.0", "iss": "https://securityioet.b2clogin.com/b21c4e98-c4bf-420f-9d76-e51c2515c7a4/v2.0/", "sub": "eb5c6ff2-2b14-4919-a611-e866d0fc3c1a", "aud": "b7e72a5b-c054-4bf8-99e7-f11bbf99a6b1", "nonce": "0912f8af-3d62-4f4f-99ba-9eaf1a063fdc", "iat": 1586211502, "auth_time": 1586211502, "idp_access_token": "ya29.a0Ae4lvC3FH0pON5guFQ8jgVKusawREXi3uziqb_rsFAbehil9XxidH-C6Q4cq7mt6nZhS6CIMj7AsIYIvdNarUNOGk6x5VDTjiHmvHCMDFfCjt6Gy6SK_k9mgSjqr0NQHPsKkfXUo3yiOIN0pwr5_fn1FzvflYZ1JdGwP", "given_name": "Juan", "family_name": "Guzmán", "name": "Juan Gabriel Guzman", "idp": "google.com", "oid": "eb5c6ff2-2b14-4919-a611-e866d0fc3c1a", "emails": [ "[email protected]" ], "tfp": "B2C_1_securityioetweb", "extension_role": "admin of admins" }

Below there are some details about what the attributes (aka jwt claims) of the decoded JWT mean:

Claim Format Description
exp int, a UNIX timestamp The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. It's important to note that a resource may reject the token before this time as well - if, for example, a change in authentication is required or a token revocation has been detected.
nbf int, a UNIX timestamp The "nbf" (not before) claim identifies the time before which the JWT MUST NOT be accepted for processing.
ver String, either 1.0 or 2.0 Indicates the version of the id_token.
iss String, an STS URI Identifies the security token service (STS) that constructs and returns the token, and the Azure AD tenant in which the user was authenticated. If the token was issued by the v2.0 endpoint, the URI will end in /v2.0. The GUID that indicates that the user is a consumer user from a Microsoft account is 9188040d-6c67-4c5b-b112-36a304b66dad. Your app should use the GUID portion of the claim to restrict the set of tenants that can sign in to the app, if applicable.
sub String, a GUID The principal about which the token asserts information, such as the user of an app. This value is immutable and cannot be reassigned or reused. The subject is a pairwise identifier - it is unique to a particular application ID. If a single user signs into two different apps using two different client IDs, those apps will receive two different values for the subject claim. This may or may not be wanted depending on your architecture and privacy requirements.
aud String, an App ID URI Identifies the intended recipient of the token. In id_tokens, the audience is your app's Application ID, assigned to your app in the Azure portal. Your app should validate this value, and reject the token if the value does not match.
nonce String The nonce matches the parameter included in the original /authorize request to the IDP. If it does not match, your application should reject the token.
iat int, a UNIX timestamp "Issued At" indicates when the authentication for this token occurred.
auht_time Time when the authentication occurred
given_name String Given name(s) or first name(s)
family_name String Surname(s) or last name(s
name String The name claim provides a human-readable value that identifies the subject of the token. The value isn't guaranteed to be unique, it is mutable, and it's designed to be used only for display purposes. The profile scope is required to receive this claim.
idp String, usually an STS URI Records the identity provider that authenticated the subject of the token. This value is identical to the value of the Issuer claim unless the user account not in the same tenant as the issuer - guests, for instance. If the claim isn't present, it means that the value of iss can be used instead. For personal accounts being used in an organizational context (for instance, a personal account invited to an Azure AD tenant), the idp claim may be 'live.com' or an STS URI containing the Microsoft account tenant 9188040d-6c67-4c5b-b112-36a304b66dad.
oid String, a GUID The immutable identifier for an object in the Microsoft identity system, in this case, a user account. This ID uniquely identifies the user across applications - two different applications signing in the same user will receive the same value in the oid claim. The Microsoft Graph will return this ID as the id property for a given user account. Because the oid allows multiple apps to correlate users, the profile scope is required to receive this claim. Note that if a single user exists in multiple tenants, the user will contain a different object ID in each tenant - they're considered different accounts, even though the user logs into each account with the same credentials. The oid claim is a GUID and cannot be reused.
emails Email associated to the user
extension_role String This is an example of an user custom attribute. Custom attributes are going to be used as user claims which are going to control the access to the backend.

IMPLEMENTATION

What is already implemented

Steps 1 to 4 of the process was already implemented in this PR #Missing parts Configuration to get steps 1 to 4 working was made by hand and it is working for only one environment. This process should be automated so that we can replicate it for other environments that eventually we will need. Steps 5 through 7 are still missing. After the user log-in set the custom attribute role=user automatically. This might be triggered from the SPA or a function in Azure.

SECURITY RISKS

  • Some implementations of Implicit grant flow only verifies the access token once and not on every single request to the backend resources.
  • Leaking of the refresh token

More details here https://app.pluralsight.com/library/courses/b18ae9f6-827e-4dc5-bd61-3dcf72c6d115/table-of-contents

Clone this wiki locally