Vous êtes sur la page 1sur 11

1.

Security from what used to work to what works today

1.1. A few important definitions

Authentication establishes the identity of a user, while authorization helps control what a user can or
cannot access.
Encryption is the mechanism that helps to protect data as it passes between the client and the server.
In this presentation only one thing is to be said about the encryption: always use SSL.
When securing an application, we also need to know what are we securing. We want to be sure that
some parts of the application are only accessible for authorized users with a set of specific claims. And
we also need to be sure that the API can only be accessed by authorized users as well. Should it?
In what case should the client, for instance our mobile client, should access the API from behalf of the
user? Or is there another method to access the API from server to server, like in the case of an MVC
app?
What I learned:
The thing with security is that a lot of approaches will work, but most are not a good idea.

1.2. Form authentication

Scenario: the user tries to access a protected page on a website. That page is requested, but is
protected so we are reverted to the login page, which allows anonymous access. The user logs in, his
credentials are checked and when they check out an authentication ticket is created.
After login, the form authentication must be sent back to the server on each request so that the user
remains logged in as they browse aside. This is typically accomplished by placing the authentication
ticket in the users cookies collection. The cookie less authentication is also supported, in which case
the authentication information is sent to the query string on each request. The information is
transmitted in the HTTP headers on each request to the website that created the cookie, therefore
once the forms authentication ticket has been created and stored in the browsers cookies each
subsequent visit to that site sends the authentication ticket along with the request, there by identifying
the user.
Figure 1 Form authentication process

Putting aside the API, this form of authentication is not appropriate in our days because we are not in
a web-only world anymore we can have mobile clients. In case of form authentication, the browser
is responsible for sending the cookie in each request. But for a mobile client we are not using a browser.
In fact, we are not using aspx pages nor the form authentication module at all.
We are also trying to restrict unauthorized access to the API, while in the example above we are
securing only the client the API is free for all.
One conceptual problem above all: the application shouldnt be responsible for authentication and
authorization.

1.3. WS-Federation

Federated security allows for clean separation between the service a client is accessing and the
associated authentication and authorization procedures. It also allows collaboration over multiple
systems, networks and organizations.
How does this work? We add a new component to the architecture: a Security Token Service(STS)
which is responsible for authentication. Active Directory Federation Services(ADFS) is one example,
but there is also ThinkTecture Identity Server. There are different flows, some very extensive ones
depending on the scenario that will be fulfilled. In the picture below is a Passive Federation Scenario.

Figure 2 WS-Federation authentication - Passive Federation Scenario

The user tries to access a resource, like a protected page from a website. Rather than using forms
authentication, the user is now redirected to the security token service, where he has to provide his
credentials on the login page of that STS. Those credentials can be checked against a variety of identity
providers it can be a username/password store typically used, but support for active directory or
external providers (Google, Facebook, etc.) are a very typical scenario here as well. If the credentials
check out, the user is authenticated by the STS and the STS issues a security token.
So the application doesnt care where those credentials are, it only cares about receiving a token. That
token contains whether or not the user is authenticated and typically a list of claims that provide the
authorization level for that user. And like this the access is granted or denied.
In a scenario like this we can now add an API to the equation. Currently we have established trust
between the pages and the STS. The token provided by the STS can thus be used to access the
application. In a likewise manner, we can establish trust between and STS and an API. So the token
provided by the STS and sent to each API call, is sufficient to access the resource offered by our API. In
.NET worlds we achieve this by using WS-Federation and WS-Security standard implementations on
top of SOAP with the help of Windows Communication Foundation(WCF).
PROBLEM: we are not working in .NET world anymore. Our client apps can be built in any technology,
while the WS-Security standards are supported in .NET apps and up to a certain level supported for
Windows Phone Apps. Moreover, they are designed as a layer on top of SOAP and they are not
applicable to RESTful services.
Trust between the pages and the STS is ok because the client lives on the server, but our mobile clients
are not part of the trusted subsystems and we dont want them to be. A phone is untrusted by default.
We should not make that phone or the mobile app part of the trusted subsystems.

1.4. OAuth 2.0

OAuth 2 .0 is an open protocol to allow secure authorization in a simple and standard method from
web, mobile and desktop application. OAuth 2.0 defines 4 different roles:
RESOURCE OWNER. This is an entity capable of granting access to a protected resource. When the
resource owner is a person, its referred to as an end user.
RESOURCE SERVER. This is the server hosting the protected resources, capable of accepting and
responding to protected resource requests using an access token. For example: the API
CLIENT an application making protected resource requests on behalf of this resource owner and
with its authorization. This term does not imply any particular implementation characteristics. For
example, a client can be an application that executes on the server, on the desktop, on a mobile
phone, etc.
AUTHORIZATION SERVER. The server issuing access tokens to the client after successfully
authenticating the resource owner and obtaining authorization.
INTERACTION: the client requests access to resources controlled by the resource owner and hosted by
the resource server. The client is issued a different set of credentials than those of the resource owner.
Instead of using the credentials of the resource owner to access protected resources, the client obtains
an access token from the authorization server. That access token is a string denoting a specific scope,
a lifetime and other specific attributes. Access tokens are issued to third party client by the
authorization server with the approval of the resource owner. The client then uses the access token to
aces the protected resource hosted by the resource server.

Figure 3 Interaction between the roles of OAuth 2.0


Clients can be confidential or public.
CONFIDENTIAL CLIENTS are the client capable of maintaining the confidentiality of their
credentials or one that is capable of secure client authentication using other means. Example: MVC
Web App living on the server therefore no need to send the credentials to the user, since it can
be stored on the server.

PUBLIC CLIENTS are incapable of maintaining the confidentiality of their credentials. The
credentials cannot be confidential anymore because they have to be stored on the client.
Native applications (Windows Phone Client)
User-Agent based applications (JavaScript-based applications)
Based on the client type, the authentication flow will be selected.
Next to different client types, OAuth 2.0 defines also protocol endpoints which are used by the client
or server, depending on the flow that is used to obtain authorization.
a) Protocols used by the AUTHORIZATION SERVER
AUTHORIZATION ENDPOINT used by the client to obtain authorization from the
resource owner via user-agent redirection.
TOKEN ENDPOINT used by the client to exchange an authorization grant for an
access token, typically with client authentication.

b) Protocols used by the CLIENT


REDIRECTION ENDPOINT used by the authorization server to return responses
containing authorization credentials to the client via the resource owner user-
agent.

AUTHORIZATION GRANT is a credential representing the resource owners authorization to access its
protected resources, used by the client o obtain an access token. OAuth 2.0 defined 4 different grant
types, and each grand type on its turn represents different flows. The flows will be implemented using
external components.
1. AUTHORIZATION CODE GRANT can be used to obtain access tokens and refresh tokens, which
allows us to refresh access without the user having to consent again. Is important to notice
that the client makes separate requests for authorization and for access token. The client must
be able to:
Interact with the resource owners user-agent(browser)
Receive incoming requests (via redirection) from the authorization server
This grant is optimized for confidential clients, but it can be used for a native client as well. In fact,
Microsofts Azure AD uses this flow for authorization from native mobile apps.
This flow supports access tokens that can be refreshed a big plus for mobile apps.
HOW DOES IT WORK:
1. A client initiates the flow by redirecting the resource owner to the authorization endpoint. The
client includes his client identifier, requested scope, state and redirection URI to which the
authorization server will send the user agent back once the access is granted or denied.
2. Then the authorization server authenticates the resource owner via the user agent and
stablished whether the resource owner grants or denies the access request sent by the client.
3. Assuming the resource owner grants access, the authorization server redirects the user agent
back to the client using the redirection URI provided earlier. The redirection URI contains an
authorization code and any local state provided by the client earlier.
4. The client then requests an access token from the authorization servers token endpoint by
including the authorization code received in the previous step. By making the request the client
authenticates with the authorization server. The client includes the redirection URI used to obtain the
authorization code for verification.
5. The authorization server authenticates the client, validates the authorization code and ensures
that the redirection URI matches the URI used to redirect the client in the previous step. If valid, the
authorization server responses back with an access token and optionally with a refresh token.

Figure 4 Authorization Code Grant Process

2. IMPLICIT GRANT used to obtain access tokens, but no refresh tokens. Is optimized for public
clients. The client must be able to:
Interact with the resource owners user-agent(browser)
Receive incoming requests (vis redirection) from the authorization server
Unlike the authorization code grant, in which the client makes separate requests for authorization and
for an access token, the client receive the access token as a result of the authorization request.
The implicit grant does NOT include client authentication and relies on the presence of the resource
owner and registration of redirection URI.
Because the access token is encoded in the redirection URI, maybe be exposed to resource owner and
to other applications installed on the same device. This grant is typically used for JavaScript clients or
native clients.
HOW DOES IT WORK:
1. The client initiates the flow by redirecting the resource owners user-agent to the
authorization endpoint; the client includes: the client identifier, requested scope, local state
and the redirection URI to which the authorisation server will send the user back once the
access is granted or denied.
2. The authorization server authenticates the resource owner via the user-agent and establishes
if the resource owner denies or grants the clients access request.
3. The authorization server redirects the user agent back to the client using the redirection URI
provided earlier. The redirection URI includes the access token in the URI fragment.
4. The user agent follows the redirection instructions by making a request to the Web-hosted
client resource. The User Agent retains the fragment information locally. The Web-hosted
client resource then return a web-page, typically an HTML document with an embedded script,
capable of accessing the full redirection URI, including the fragment retained by the User Agent
and of extracting the access token and other parameters.
5. The User Agent executes the scripts provided by the Web-hosted client resource locally, which
extracts the access token. Then the User Agent passes the access token onto the client.

Figure 5 Implicit Grant Process

3. CLIENT CREDENTIALS GRANT is typically used for application API access, server-to-server
communication. A client can request an access token by using its Client Credentials (ClientId,
ClientSecret).
!!! Client Credentials = Client ID + Client Secret
User Credentials = User name + password
This grant must be used only by confidential clients. It ca only be used when the client is requesting
access to the protected resources under control or belonging to another resource owner that has
been previously arranged with the authorization server.
HOW DOES IT WORK:
1. The client authenticates with the authorization server and requests an access token from the
token endpoint.
2. The Authorization Server authenticates the client and if allowed it issues an access token.
Figure 6 Client Credentials Grant Process

4. RESOURCE OWNER PASSWORD CREDENTIALS GRANT is only suitable for trusted applications.
This type of grant is suitable in cases when the resource owner has a trust relationship with
the client, such as a device operating system or highly privileged application. The authorization
server should take very special care when enabling this grant type and only allowed when
other flows are no longer viable.
This grant type is suitable for clients capable of obtaining the resource owners credentials (username
and password). In the other grants we input our credentials to the authorization server, here we input
them on the client itself. This flow is included for completeness but is really recommended to avoid it.

Figure 7 Resource Owner Password Credentials Process

OAuth 2.0 is for AUTHORIZATION, but many applications require identity information as well. We need
to know who the user accessing the app is. But authorization doesnt tell us that. It just simply tells us
if a user is allowed or not to access a resource, not who that user is. This is where OpenID Connect
comes to play.
OpenID Connect 1.0 is a simple identity layer on top the OAuth 2.0 protocol. It allows clients to verify
the identity of the end user based on the authentication performed by an authorization server, as well
as to obtain basic profile information about the end user in an interoperable and REST-like manner.
OpenID Connect allows clients of all types to request and receive information about authenticated
sessions and end users.
While OAuth 2.0 defines access tokens, OpenID Connect defines standardised identity tokens. The
identity token is sent to the app, so the app can validate who the user is. Next to that, it defines an
UserInfo endpoint to get user information (e-mail, nickname, website, picture, etc.).
OpenID Connect is built on top of OAuth 2.0 so the flows are the same. It can be used with
Authorization Code Grant and Implicit Grant. Its not possible with Client Credentials Grant as this grant
is for server to server communication. There is no end user involved in the process so there is not end
user identity either. Likewise, it makes sense for the resource owner flow.
HOW DOES IT WORK: instead of requesting just an access token, we will request an additional id token
from the Security Token Service that implements the OpenID Connect specification. The client receives
an ID token and usually also an access token. To get more information about the authenticated user,
the client can then send a request to the UserInfo endpoint with the access token and that UserInfo
endpoint then return claims about the new user.
5. HYBRID FLOW is a flow specified by OpenID Connect, on top of Authorization Code Flow and
Implicit Flow. This is a combination of the Authorization Code Flow and Implicit Flow.
The Authorization Flow returns an authorization code to the client that can be exchanged for an access
token, and in case of OpenID Connect for an id token. The Implicit Flow returns the id token and the
access token directly to the client. In the Hybrid Flow, some tokens are returned from the authorization
endpoint, others are returned from the token endpoint. This allows for extra scenarios. It allows the
client application to use the id token to get access to users identity, but at the same time receive an
authorization code through refresh token can be obtained so it gets long-life access to resources.
2. Configuring and Deploying a Security Token Service

2.1. Choosing a Security Token Service

We need a Security Token Service that will provide us with the tokens we need and that implements
OAuth 2.0 and OpenID Connect. There are the following options:
Azure Active Directory is a service that provides identity and access management capabilities
in the cloud. It implements OAuth 2.0. We can use it, but we cant really go into details on how
its implemented and how it matches all the theory above. Its a good option when the we
dont care about the implementation details.
Active Directory Federation Services (AD FS) 3.0 it only supports the Authorization Code Flow
and no OpenID, so no identity.
ThinkTecture Identity Server V3 is an extensible OpenID Connect and OAuth 2.0 Security
Token Service and Authorization Server. It is part of .NET Foundation.

2.1. Clients, Scopes and Users in ThinkTecture ID Server

The Client models an OpenID Connect or OAuth 2.0 client.


The Scope models and OpenID Connect (Identity) or OAuth2 (Resource) scope. This shows the intent
of the client: I, the client, ask you the user or resource owner to grant me access to your name or to
the API you own.
The Users are the users of the application, where applicable and their credentials stored in a custom
user store or credentials provided by third-party providers.

2.2. Hosting, Configuring and Deploying Identity Server

We are adding to the solution an empty Web project with Owin enabled:
[assembly: OwinStartup(typeof(RESTful_API.IdSrv.Startup))]

This project will be used to make security tokens out of it using ThinkTectures Identity Server Model.
This Security Tokens Service will be used by any possible client we will include in the solution (such as
MVC, Windows Phone, etc.).
1. Enable SSL
2. Enable RunAllManagedModulesForAllRequests to ensure that all the assets are loaded correctly.
This can be done by adding the following lines in the Web.config file:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"></modules>
</system.webServer>

3. Microsoft.Owin.Host.SystemWeb is a Owin Server that enables Owin based apps to run on IIS
using the ASP.NET request pipeline
Install-Package Microsoft.owin.Host.SystemWeb

4. Add IdentityServer3 package itself


Install-Package IdentityServer3
CONFIGURING THE IDENTITYSERVER PROJECT
1. Create InMemory Clients, Users and Identity Scopes
2. Configure identity server by going to Owin Startup Configuration and adding a path and a
config option. Optionally we can add also the certificates used to sign the tokens.

3. Test the IdSrv Project by surf to the next link:


https://localhost:44305/identity/.well-known/openid-configuration

SECURING THE CLIENT APPLICATIONS MVC HYBRID FLOW


MVC is a confidential client Authorization Code flow (access_token, refresh_token)
We also require identity OpenID Connect (id_token, opened scope)
Considering the two requirements above, Hybrid flow is the one which fits the best for this case
because is combining implicit and authorization code grant.
We already configure the client the ID Server level to support Hybrid Flow. Now is time to use that flow
from the MVC client.
1. Make sure that the web client is using SSL in both Properties windows and Web tab.
2. Install the package below to enable cookie based authentication
Install-Package Microsoft.Owin.Security.Cookies

3. Install the package that contains the OpenID Connect middleware


Install-Package Microsoft.Owin.Security.OpenIdConnect

4. Install Microsoft.Owin.Host.SystemWeb package


Install-Package Microsoft.Owin.Host.SystemWeb

5. Add a new Owin start up class to the MVC project and include the following code
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies"
});

app.UseOpenIdConnectAuthentication(new
OpenIdConnectAuthenticationOptions
{
ClientId = "mvc",
Authority = "https://localhost:44304/identity/",
RedirectUri = "https://localhost:44303/",
SignInAsAuthenticationType = "Cookies",

ResponseType = "code id_token",


Scope = "openid profile",

Notifications = new OpenIdConnectAuthenticationNotifications()


{

MessageReceived = async n =>


{

//EndpointAndTokenHelper.DecodeAndWrite(n.ProtocolMessage.IdToken);
}

});

Clicking on the about link will now trigger the authentication. IdentityServer will show the login screen
and send a token back to the main application. The OpenID Connect middleware validates the token,
extracts the claims and passes them on to the cookie middleware, which will in turn set the
authentication cookie. The user is now signed in.

2.3. UerInfo endpoint getting more information about the user

To get more information about the user it requires an access token and that access token must contain
the scopes that define exactly what we can ask for from the UserInfo endpoint using that access token.
We can ask for an addition access token as a response type. As we asked previously already for the
openid and profile scopes, there will be included in the access token.
For calling the UserInfo endpoint we need to make sure we are passing the access token as a Bearer
token. Then we use an HttpClient to call the UserInfo endpoint and if the status is OK, we read out
what is returned.

Vous aimerez peut-être aussi