Skip to content
This repository was archived by the owner on Apr 27, 2021. It is now read-only.

Getting Started

Linda Chan edited this page Aug 15, 2017 · 31 revisions

Getting Started

This documentation will help you quickly get started running Fabric.Identity in Docker and configuring an application to use it in your local environment for testing purpose. For proper installation of fabric.identity in production, please refer to the Installing Fabric.Identity in a Production environment section.

Fabric.Identity implements the OpenID Connect protocol, via IdentityServer4, so you may review related documentations to supplement this quick start guide.

Step 1: Install Docker

You can choose the right docker install and find install instructions on Docker's documentation site.

Step 2: Start the container

Once Docker is installed, simply run the following from a command line:

docker run --name fabric.identity -p 5001:5001 healthcatalyst/fabric.identity

This command will pull the latest Fabric.Identity docker image from Docker Hub, start the container, and set it to listen on port 5001 of your machine. You can verify that it is up and running by opening a browser and navigating to http://localhost:5001. You should see the following screen:

Step 3 (optional): Configure our sample application

We have provided a sample application you may use to test with Fabric.identity. However, if you already have an application of your own to integrate with Fabric.identity, you may skip this step.

Once the fabric.identity container is up and running, use bash to execute the setup-samples.sh script to setup the configuration to run our sample applications against Fabric.Identity. If you are interested in knowing configurations setup in the script, you can review it at the bottom of this page.

NOTE: running the container in this way uses in memory stores for all data, so once the container shuts down, your configuration will be lost. If you would like to persist your configuration, you can run the following script in bash, which will create a container for Fabric.Identity, Fabric.Authorization, and CouchDB, configure the services to use the database, and finally setup the sample applications:

curl -sSL https://healthcatalyst.github.io/InstallScripts/installidentityandauthorization.txt | sh /dev/stdin [couchdb_username] [couchdb_password]

Replace [couchdb_username] and [couchdb_password] with a username and password of your choice to set up the couchdb instance.

The setup-samples.sh script will print out several client secret values. The client secret values are required for interacting with Fabric.Identity. Each application that the setup-samples.sh script registers has its own client secret. One to pay attention to in particular is the Fabric.Installer client secret, as that is the client application that has the necessary scopes to all registration of other client applications.

Step 4: Configure your application

Step 4a: Register your Client Application

If you have opted to use the sample application we provide and completed step 3 above, you may skip this step. Otherwise, follow instructions below to configure your own application.

In order to allow your application to authenticate users via Fabric.Identity, you first need to tell Fabric.Identity about your application. To do that, you need to POST your client application configuration to the Fabric.Identity /api/client endpoint. Before you can do that, you need to determine if your application is an application that can protect a secret like a server side application such as an ASP .NET MVC app, or one that cannot such as a JavaScript SPA. For more in depth reading about the different OpenIDConnect flows, you can read the OpenID Connect Core 1.0 spec.

JavaScript Client Application (Implicit Flow)

For a client side JavaScript application (a SPA) an example configuration, assuming a URL of http://localhost, is:

{
    "clientId": "fabric-spa-sample",
    "clientName": "Sample SPA application",
    "allowedScopes": [
        "openid",
        "profile",
        "fabric.profile"
    ],
    "allowedGrantTypes": [
        "implicit"
    ],
    "allowedCorsOrigins": [
        "http://localhost"
    ],
    "redirectUris": [
        "http://localhost/oidc-callback.html"
    ],
    "postLogoutRedirectUris": [
        "http://localhost"
    ],
    "allowOfflineAccess": false,
    "requireConsent": false
}

To add this configuration to Fabric.Identity, first get a valid access token from Fabric.Identity for the Fabric.Installer application, replacing [installersecret] with the Fabric.Installer client secret output by the setup-samples.sh script:

curl http://localhost:5001/connect/token --data "client_id=fabric-installer&grant_type=client_credentials&scope=fabric/identity.manageresources" --data-urlencode "client_secret=[installersecret]"

Then post the configuration to /api/client, replacing [accesstoken] with the value of the access_token returned from the above call:

curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer [accesstoken]" -d "{ \"clientId\": \"fabric-spa-sample\", \"clientName\": \"Sample SPA application\", \"allowedScopes\": [\"openid\", \"profile\", \"fabric.profile\"], \"allowedGrantTypes\": [\"implicit\"], \"allowedCorsOrigins\": [ \"http://localhost\"], \"redirectUris\": [\"http://localhost/oidc-callback.html\"], \"postLogoutRedirectUris\": [ \"http://localhost\"], \"allowOfflineAccess\": false, \"requireConsent\": false }" http://localhost:5001/api/client

Note above that the "allowedGrantTypes" property is set to "implicit". For a client side application that cannot protect a secret, like a JavaScript SPA, we must use Implicit Flow.

Server Side Client Application (Hybrid and Client Credentials Flow)

For a server side application (an ASP .NET MVC app or a Spring based Java app) an example configuration, assuming a URL of http://localhost, is:

{
    "clientId": "fabric-mvc-sample",
    "clientName": "Sample MVC application",
    "allowedScopes": [
        "openid",
        "profile",
        "fabric.profile"
    ],
    "allowedGrantTypes": [
        "hybrid"
    ],
    "redirectUris": [
        "http://localhost/signin-oidc"
    ],
    "postLogoutRedirectUris": [
        "http://localhost/signout-callback-oidc"
    ],
    "allowOfflineAccess": true,
    "requireConsent": false
}

Again you would need to POST this configuration to the the /api/client endpoint of Fabric.Identity, remember to get the access token as explained above:

curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer [accesstoken]" -d "{ \"clientId\": \"fabric-mvc-sample\", \"clientName\": \"Sample MVC application\", \"allowedScopes\": [\"openid\", \"profile\", \"fabric.profile\"], \"allowedGrantTypes\": [\"hybrid\", \"client_credentials\"], \"redirectUris\": [\"http://localhost/signin-oidc\"], \"postLogoutRedirectUris\": [ \"http://localhost/signout-callback-oidc\"], \"allowOfflineAccess\": true, \"requireConsent\": false }" http://localhost:5001/api/client

Since this is a server side application that can protect a secret, we are allowed to use Hybrid flow. This gives us the added benefit of getting a refresh token, which allows us to get access tokens on behalf of a user even if they are not logged in. Note the "allowOfflineAccess" property is set to true, this will tell Fabric.Identity to give us a refresh token in addition to an access token.

Step 4b: Integrate your application with Fabric.Identity

Once you have registered your client application, you can then begin the process of integrating your application with Fabric.Identity. Below are the steps to do that depending on your type of application:

JavaScript SPA

The oidc-client library is a library that implements the OpenID Connect protocol from a client application perspective. While you don't necessarily have to use this library, it is highly recommended that you use some library as it makes integration much simpler. For a complete, working example of an Angular SPA using the oidc-client library with Fabric.Identity, see our sample.

Below are the steps necessary to get a JavaScript application running with the oidc-client library and Fabric.Identity:

  • Add the oidc-client NPM package to your project
  • Configure and instantiate the UserManager (preferably in some sort of module):
    var clientSettings = {
        authority: 'http://localhost:5001/',
        client_id: 'fabric-spa-sample',
        redirect_uri: 'http://localhost/oidc-callback.html',
        post_logout_redirect_uri: 'http://localhost',
        response_type: 'id_token token',
        scope: 'openid profile fabric.profile',
        filterProtocolClaims: true,
        loadUserInfo: true
    };
    userManager = new UserManager(clientSettings)
  • Create a function to login via the userManager
    function login() {
        userManager.signinRedirect().then(function () {
            console.log("signin redirect done");
        }).catch(function (err) {
            console.log(err);
        });
    };
  • Create a function to logout via the userManager
    function logout() {
        userManager.signoutRedirect();
    };
  • Add the oidc-callback.html that completes the sign-in handshake with IdentityServer,
  • the URI for this html page must match a URI provided in the redirectUris array when you registered the client with IdentityServer
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8" />
      <title></title>
    </head>
    <body>
      <h1 id="waiting">Waiting...</h1>
      <div id="error"></div>
      <script src="assets/oidc-client.min.js"></script>
    <script>
      Oidc.Log.logger = console;
      new Oidc.UserManager().signinRedirectCallback().then(function (user) {
          if (user == null) {
            document.getElementById("waiting").style.display = "none";
            document.getElementById("error").innerText = "No sign-in request pending.";
            console.log("at oidc-callback, but user is null");
          }
          else {
            console.log("user is not null, redirecting to index");
            window.location = "/";
          }
        })
        .catch(function (er) {
          document.getElementById("waiting").style.display = "none";
          document.getElementById("error").innerText = er.message;
        });
    </script>
    </body>
    </html>
  • Once that is all in place, wire up a Login button to call the login() function created previously and the authentication flow should be kicked off.

ASP .NET Core MVC Application

Like the JavaScript application, there are libraries available that allow you to easily integrate with an OpenID Connect server. We will use the following nuget packages for ASP .NET Core:

Microsoft.AspNetCore.Authentication.Cookies Microsoft.AspNetCore.Authentication.OpenIdConnect

To take a look at a working ASP .NET Core MVC application take a look at our sample.

  • Install the above nuget packages using nuget package manager.
  • In the Configure method of Startup.cs, add the CookieAuthenticationMiddleware
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationScheme = "Cookies"
    });
  • After the CookieAuthentication middleware is added, add the OpenIdConnectAuthentication middleware to the pipeline:
    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
    app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
    {
        AuthenticationScheme = "oidc",
        SignInScheme = "Cookies",

        Authority = "http://localhost:5001",
        RequireHttpsMetadata = false,

        ClientId = "fabric-mvc-sample",
        ClientSecret = <the secret returned from the api call made earlier>,

        ResponseType = "code id_token",
        Scope = { "openid", "profile", "fabric.profile"},

        GetClaimsFromUserInfoEndpoint = true,
        SaveTokens = true
    });
  • Finally, add an [Authorize] attribute to one of your Controllers or Controller methods and navigate to the Controller in your browser. The authentication flow should then be kicked off.

Sample Setup Script

We ship the setup-samples.sh script to help you quickly get started using Fabric.Identity. For a production scenario, you will likely want to configure your own setup script.

Our setup-samples.sh script performs the following:

  • Registers the REST API embedded in Fabric.Identity that allows configuring Clients and API's. This is required for protecting that API so that only authorized clients can access it. It defines a required scope of fabric/identity.manageresources.
  • Registers the Fabric.Installer application. This application is the configured client application that can register Clients and API's with Fabric.Identity and Fabric.Authorization as well. It requests the following scopes: fabric/identity.manageresources, fabric/authorization.read, fabric/authorization.write, fabric/authorization.manageclients.
  • Registers the Fabric.Authorization API as a protected API resource, with the required scopes of fabric/authorization.read, fabric/authorization.write, fabric/authorization.manageclients.
  • Registers the Fabric.GroupFetcher client application, which is a utility that gets installed with Fabric.Authorization that helps to sync Active Directory groups with Groups registered with Fabric.Authorization.
  • Registers the Fabric.Identity.Samples.API sample API as a protected API resource with the scope patientapi.
  • Registers the Fabric.Identity.Samples.MVC client application with the requested scopes of openid, profile, fabric.profile, fabric/authorization.read, fabric/authorization.write, patientapi
  • Registers the Fabric.Identity.Samples.Angular client application with the requested scopes of openid, profile, fabric.profile, fabric/authorization.read, fabric/authorization.write, patientapi

In a production scenarios, you will likely want to keep the first four operations that register the embedded REST API, Fabric.Installer, Fabric.Authorization, and Fabric.GroupFetcher. The samples are only meant as quickstarts to show how to integrate with Fabric.Identity and Fabric.Authorization.

Additional Resources

There are libraries for integrating your application with an OpenID server available for many languages. If you don't see a sample for your language above or in our samples you can reference the following links to find samples and libraries in other languages:

http://openid.net/developers/certified/ http://openid.net/developers/uncertified/

If you want to read the full OpenID Connect spec, it can be found here:

http://openid.net/developers/specs/

You can find more details about IdentityServer4 here:

https://identityserver4.readthedocs.io/en/release/

Finally, for the full source of our samples, you can visit our samples repo, which will be added to over time:

https://github.com/HealthCatalyst/Fabric.Identity.Samples

Clone this wiki locally