Skip to content

Commit

Permalink
grammar fixes | deploy pipeline
Browse files Browse the repository at this point in the history
  • Loading branch information
kolosovpetro committed Jul 16, 2023
1 parent 7171793 commit 4b824e6
Show file tree
Hide file tree
Showing 11 changed files with 94 additions and 107 deletions.
41 changes: 39 additions & 2 deletions .github/workflows/build-and-deploy-pdf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,55 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Install GitVersion
uses: gittools/actions/gitversion/[email protected]
with:
versionSpec: '5.x'

- name: Determine Version
uses: gittools/actions/gitversion/[email protected]

- name: Print SemVer
run: |
echo ${{ env.GITVERSION_SEMVER }}
echo ${{ env.GitVersion_InformationalVersion }}
echo ${{ env.GitVersion_EscapedBranchName }}
- name: Update version.tex
shell: bash
run: |
newVersion=${{ env.GitVersion_InformationalVersion }}
sed -i "s|Local-0.1.0|$newVersion|" "src/sections/version.tex"
- name: Build PDF
uses: xu-cheng/latex-action@v2
with:
root_file: "${{ env.FILE_NAME }}.tex"
working_directory: src

- name: List src
run: |
ls -lsa src
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: "drop"
path: "src/${{ env.FILE_NAME }}.pdf"
name: "${{ env.FILE_NAME }}-${{ env.GitVersion_InformationalVersion }}"
path: |
src/${{ env.FILE_NAME }}.tex
src/${{ env.FILE_NAME }}.bbl
src/${{ env.FILE_NAME }}.bib
src/sections
- name: Upload artifacts PDF
uses: actions/upload-artifact@v3
with:
name: "${{ env.FILE_NAME }}-PDF-${{ env.GitVersion_InformationalVersion }}"
path: |
src/${{ env.FILE_NAME }}.pdf
- name: Clone repository and add document
continue-on-error: true
Expand Down
Binary file modified out/SecureAzureOIDC.pdf
Binary file not shown.
7 changes: 2 additions & 5 deletions src/SecureAzureOIDC.tex
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
\author[Petro Kolosov]{Petro Kolosov}
\author[Dmitrij Kudryashov]{Dmitrij Kudryashov}
\email{[email protected]}
\urladdr{https://kolosovpetro.github.io}
\email{[email protected]}
\keywords{
OpenID Connect,
OIDC,
Expand All @@ -42,7 +44,6 @@
CSRF,
ASP .NET Core
}
\urladdr{https://kolosovpetro.github.io}
\date{\today}
\hypersetup{
pdftitle={Secure OpenID Connect implementation using Azure Active Directory and ASP .NET Framework},
Expand Down Expand Up @@ -111,10 +112,6 @@
\section{Conclusions}\label{sec:conclusions}
\input{sections/conclusions}


\section{Acknowledgements}\label{sec:acknowledgements}
\input{sections/acknowledgements}

\bibliographystyle{unsrt}
\bibliography{SecureAzureOIDC}
\noindent \textbf{Version:} \input{sections/version}
Expand Down
4 changes: 2 additions & 2 deletions src/sections/abstract.tex
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
In this manuscript we discuss the problem of secure storage and transfer of access tokens between microservices.
In this manuscript, we discuss the problem of secure storage and transfer of access tokens between microservices.
Web browser may store access tokens both, in local storage or in cookie files.
We propose a secure implementation to store and transfer auth cookies between microservices
using Azure Active Directory, OpenID Connect and ASP .NET Core.
using Azure Active Directory, OpenID Connect, and ASP .NET Core.
1 change: 0 additions & 1 deletion src/sections/acknowledgements.tex

This file was deleted.

22 changes: 11 additions & 11 deletions src/sections/authentication_flow.tex
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
Consider a more practical approach that takes all the previously discussed aspects.
Applying modern frameworks like ASP .NET Core, Angular etc.
let be the following authentication flow as per diagram below
Applying modern frameworks like ASP .NET Core, Angular, etc.
let be the following authentication flow as per the diagram below
\begin{figure}[H]
\centering
\includegraphics[width=1\textwidth]{img/Auth_flow_updated}
~\caption{Authentication flow diagram.}\label{fig:authentication_flow_diagram}
~\caption{Authentication flow diagram.}
\end{figure}

Therefore, the whole authentication process can be described as eight steps such that
\begin{enumerate}
\item Compiled Angular frontend application sends request to the authentication endpoint of the ASP .NET Core API
to verify current authentication state.
\item Compiled Angular frontend application sends a request to the authentication endpoint of the ASP .NET Core API
to verify the current authentication state.
Angular application is a set of precompiled bundles that are exposed via same ASP .NET Core API at the \texttt{/app}
endpoint so that cross-origin requests are not necessary and tokens can be stored in cookie files securely
\item Authentication endpoint of the ASP .NET Core API responses either with
HTTP status code \texttt{200 (OK)} or \texttt{401 (Unauthorized)}
\item If \texttt{401 (Unauthorized)} status code received from previous step,
\item If \texttt{401 (Unauthorized)} status code received from the previous step,
then browser is redirected to the \texttt{login} endpoint of the ASP .NET Core API,
otherwise user gets access to the protected resources
\item Login method of the ASP .NET Core API redirects browser to the Azure AD authorize url
\texttt{login.microsoftonline.com/tenant/oauth2/v2.0/authorize} where user enters his credentials.
It is important to clarify that in order to get ID token we have to put parameter \texttt{openid} to the scope
It is important to clarify that in order to get ID token, we have to put parameter \texttt{openid} to the scope
\input{code_snippets/02_openidconnect_add_scope_openid}
\item After successful authentication on the Azure AD side, the browser is redirected to the \texttt{fallback\_url}
\item After successful authentication on the Azure AD side; the browser is redirected to the \texttt{fallback\_url}
that is defined in Azure AD application registration.
This \texttt{fallback\_url} is an active endpoint of the ASP .NET Core API\@.
At this point, the \texttt{TickerStore}~\cite{microsoftIticketstore2023, ticketStore_2023}
comes into the flow to manage user sessions.
Each session is stored as a \texttt{UserSessionEntity} entity in the database.
\input{code_snippets/03_user_session_entity}
The Value property of type \texttt{byte[]} contains serialized \texttt{AuthenticationTicket}~\cite{microsoftAuthenticationTicket2023}
The Value property of type \texttt{byte[]} contains a serialized \texttt{AuthenticationTicket}~\cite{microsoftAuthenticationTicket2023}
object such that contains all required information like access, ID and refresh tokens.
The class \texttt{TickerStore} implements \texttt{ITickerStore} interface that offers 4 methods:
\texttt{StoreAsync, RenewAsync, RetrieveAsync, RemoveAsync}.
Expand All @@ -47,9 +47,9 @@
Example of \texttt{TicketStore} dependency injection can be found at~\cite{ticketStoreDI_2023}.
Authentication cookies are being setup at this step.
\item Step 1 is repeated here, but now the HTTP request is for sure to be with \texttt{200 (OK)} status code.
\item Precompiled Angular frontend application now sends request to the another microservice with authentication cookies
\item Precompiled Angular frontend application now sends a request to another microservice with authentication cookies
attached to the request's \texttt{Bearer} header using \texttt{YARP} library~\cite{microsoftYarp2021},
so that microservice is accessible.
The \texttt{YARP} is configured according to~\cite{yarpDI_2023,yarpSectionAppSettings_2023}.
\item If previous step returns \texttt{401 (Unauthorized)} status code, then Step 1 is repeated
\item If a previous step returns \texttt{401 (Unauthorized)} status code, then Step 1 is repeated
\end{enumerate}
6 changes: 3 additions & 3 deletions src/sections/conclusions.tex
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
In this manuscript we explore the problem of secure storage and transfer of access tokens between microservices.
In this manuscript, we explore the problem of secure storage and transfer of access tokens between microservices.
Particular attention was paid to possible vulnerabilities during transfer of access tokens such
as Cross-Site Scripting (XSS) and Cross-Site Request Forgery (CSRF).
as Cross-Site Scripting and Cross-Site Request Forgery.

To eliminate these vulnerabilities, it is necessary to store authorization tokens in cookies with mandatory
\texttt{HttpOnly} and \texttt{SameSite} settings such that \texttt{SameSite} values should be \texttt{Lax} or \texttt{Strict}.
Expand All @@ -12,7 +12,7 @@

Also, we provide an authentication / authorization implementation based on the ASP.NET Core Web API backend and Angular
frontend application.
These applications are stored under the single domain to eliminate necessity to transfer authorization cookies cross domain way.
These applications are stored under the single domain to eliminate the necessity to transfer authorization cookies cross domain way.
Transfer of access tokens between microservices is implemented using Reverse Proxy YARP~\cite{microsoftYarp2021} so that
the access token is automatically substituted in the request header.

Expand Down
8 changes: 4 additions & 4 deletions src/sections/definitions.tex
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
\begin{itemize}
\item \textbf{Access Token} is credential used to access protected resources.
\item \textbf{Access Token} is a credential used to access protected resources.
An access token is an opaque string representing an authorization issued to the client.
The string is usually opaque to the client.
Tokens represent specific scopes and
durations of access, granted by the resource owner, and enforced by the resource server and authorization server.
\item \textbf{Refresh Token} is credential used to obtain a new pair of access and refresh tokens when the becomes
invalid or expires, or to obtain additional access tokens with identical or narrower scope (access tokens may have a shorter
lifetime and fewer permissions than authorized by the resource owner).
\item \textbf{Refresh Token} is a credential used to obtain a new pair of access and refresh tokens when they become
invalid or expired, or to obtain additional access tokens with identical or narrower scope.
Access tokens may have a shorter lifetime and fewer permissions than authorized by the resource owner.
Refresh tokens are issued to the client by the authorization server.
\item \textbf{Resource Owner} is an entity capable of granting access to a protected resource.
When the resource owner is a person, it is referred to as an end-user.
Expand Down
68 changes: 11 additions & 57 deletions src/sections/introduction_to_open_id_connect.tex
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
%Your introduction here.
%Include some references~\cite{siddiqui2011cross,spett2005cross, bradley2015rfc,hardt2012oauth,fielding2014rfc}.
%Lorem Ipsum is simply dummy text of the printing and typesetting industry.
%Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley
%of type and scrambled it to make a type specimen book.
%It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.
%It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more
%recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
OpenID Connect (OIDC) is a simple identity layer~\cite{siriwardenaOpenid2020, sakimuraOpenid2014}
on top of the OAuth 2.0 protocol~\cite{hardt2012oauth}.
It enables Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server,
Expand All @@ -19,12 +11,11 @@
OpenID Connect uses them to provide identity services.

The problem OAuth 2.0 solves is that in the traditional client-server authentication model,
the client requests an access-restricted resource (protected resource)
the client requests an access-restricted resource
on the server by authenticating with the server using the resource owner's credentials.
In order to provide third-party applications access to restricted resources,
the resource owner shares its credentials with the third party.
This creates several problems and limitations~\cite{hardt2012oauth}:

\begin{itemize}
\item Third-party applications are required to store the resource owner's credentials for future use, typically
a password in clear-text.
Expand All @@ -36,21 +27,6 @@
\item Compromise of any third-party application results in compromise of the end-user's password
and all the data protected by that password.
\end{itemize}

%1. Third-party applications are required to store the resource owner's credentials for future use, typically
%a password in clear-text.
%
%2. Servers are required to support password authentication, despite the security weaknesses inherent in passwords.
%
%3. Third-party applications gain overly broad access to the resource owner's protected resources,
%leaving resource owners without any ability to restrict duration or access to a limited subset of resources.
%
%4. Resource owners cannot revoke access to an individual third party without revoking access to all third parties,
%and must do so by changing the third party's password.
%
%5. Compromise of any third-party application results in compromise of the end-user's password
%and all the data protected by that password.

OAuth 2.0 addresses these issues by introducing an authorization layer and separating the role of the client
from that of the resource owner.
In OAuth, the client requests access to resources controlled by the resource owner and hosted by the resource server.
Expand All @@ -59,20 +35,19 @@
\begin{figure}[H]
\centering
\includegraphics[width=1\textwidth]{img/OAuthPkceScheme_1570_1055}
~\caption{OAuth 2.0 with PKCE flow diagram.}\label{fig:oauth_with_pkce}
~\caption{OAuth 2.0 with PKCE flow diagram.}
\end{figure}

\begin{enumerate}
\item After clicking on the \texttt{Sign in with Google} button,
the browser is redirected to the authorization endpoint, where the resource owner (user) enters credentials e.g.\ login and password.
\item After successful authentication the browser is redirect to \texttt{redirect\_uri} defined in OAuth provider settings.
the browser is redirected to the authorization endpoint, where the resource owner (user) enters credentials e.g., login and password.
\item After successful authentication, the browser is redirect to \texttt{redirect\_uri} defined in OAuth provider settings.
The \texttt{code} parameter is attached to the request parameters.
\item Having the \texttt{code} value application exchanges it to a pair of access and refresh tokens.
Provided that we used PKCE with specified \texttt{code\_challenge} and \texttt{code\_challenge\_method} values exchanging code to a pair of tokens
If we used PKCE with specified \texttt{code\_challenge} and \texttt{code\_challenge\_method} values exchanging code to a pair of tokens,
we must pass the value of \texttt{code\_verifier} to the request.
\end{enumerate}

We mention here such definitions as code and state and they means
We mention here such definitions as code and state, and they mean
\begin{itemize}
\item \textbf{Code} is an authorization code that is obtained through an authorization
server and mediates between clients and resource owners.
Expand All @@ -82,42 +57,21 @@
their credentials are never sent to the client.
\item \textbf{State} is the value used by the client to store the state between the authorization request and the callback.
The authorization server enables this value when redirecting the user agent back to the client.
This parameter is used to prevent Cross-Site Request Forgery (CSRF) attacks.
This parameter is used to prevent CSRF attacks.
\end{itemize}

Adding the Proof of Key Code Exchange (PKCE) to the OIDC flow improves protocol security so that the code
cannot be exchanged by third-party applications by-passing the original application.
Authorization code flow with PKCE is a protocol that represents a client generated secret that can be verified
Authorization code flow with PKCE is a protocol that represents a client-generated secret that can be verified
by an authorization server.
This secret is called \texttt{code\_verifier}.
The client hashes the \texttt{code\_verifier} value and writes it to the \texttt{code\_challenge} parameter
of an HTTP request.
Proof of Key Code Exchange (PKCE) solves the problem of secure code exchange.
PKCE solves the problem of secure code exchange.
If an attacker manages to get an authorization code, then he will not be able to exchange
it for access and refresh tokens.
Therefore, we ensure that the exchange of a code for tokens is produced by the same application
that performed the authentication.
Proof of Key Code Exchange can be compared to the digital signature of an authentication process.
To exchange the \texttt{code} for a pair of access and refresh tokens it is necessary to specify
a valid \texttt{code\_verifier}.

%Code is an authorization code that is obtained through an authorization
%server and mediates between clients and resource owners.
%Before the authorization server redirects the resource owner back to the client,
%the authorization server verifies the authenticity of the resource owner.
%So because the resource owner only authenticates with the authorization server,
%their credentials are never sent to the client.
%
%State is the value used by the client to store the state between the authorization request and the callback.
%The authorization server enables this value when redirecting the user agent back to the client.
%This parameter is used to prevent Cross-Site Request Forgery (CSRF) attacks.

%1. After clicking on the "Sign in with Google" button,
%the browser is redirected to the authorization endpoint, where the resource owner (user) enters credentials e.g. login and password.
%
%2. After successful authentication the browser is redirect to redirect_uri defined in OAuth provider settings.
%Code parameter is attached to the request parameters.
%
%3. Having the code value application exchanges it to a pair of access and refresh tokens.
%Provided that we used PKCE with specified code_challenge and code_challenge_method values exchanging code to a pair of tokens
%we must pass the value of code_verifier to the request.
To exchange the \texttt{code} for a pair of access and refresh tokens, it is necessary to specify
a valid \texttt{code\_verifier}.
8 changes: 4 additions & 4 deletions src/sections/refresh_token_flow.tex
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
The implementation of refreshing user tokens is extremely simple.
It is necessary to create a background service~\cite{microsoftHostedservice2023} that manages sessions,
in particular deletes sessions that has not been used long time, refreshes existing sessions etc.
in particular deletes sessions that have not been used long time, refresh existing sessions, etc.
In case of refresh or initial authentication, the new \texttt{AuthenticationTicket} object~\cite{microsoftAuthenticationTicket2023}
replaces the existing or new instance is created.
In addition, the Azure AD authentication server's response contains a timestamp property \texttt{ExpiresIn}
that determines lifetime of the tokens,
that determines the lifetime of the tokens,
the background service updates the \texttt{ExpiresAt} property of the \texttt{UserSessionEntity} accordingly.

The background service is responsible not only for refreshing the sessions,
but also it is responsible for deleting the sessions that have not been used for a long time.
Once per predefined period, the sessions are selected and their \texttt{DateOfLastAccess} property is
compared to the current \texttt{DateTime.Now}.
If the difference between the \texttt{DateOfLastAccess} and \texttt{DateTime.Now} is more than, for example 3 days,
then session is deleted.
If the difference between the \texttt{DateOfLastAccess} and \texttt{DateTime.Now} is more than, for example, 3 days,
then the session is deleted.
Each time a user performs an action on the site, the \texttt{DateOfLastAccess} property is updated.
Implementation of a background service can be done as per references~\cite{backroundService_2023, configurationBackgroundService_2023}
Loading

0 comments on commit 4b824e6

Please sign in to comment.