-
Notifications
You must be signed in to change notification settings - Fork 6
Getting Started Old
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 Server environment section.
Fabric.Identity implements the OpenID Connect protocol, via IdentityServer4, so you may review related documentations to supplement this quick start guide.
Note if you already have fabric installed and are looking to register a new API resource or new client. You can skip the first 2 steps and start with step 3.
You can choose the right docker install and find install instructions on Docker's documentation site.
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:
Next, you will want to register your client or API resource with fabric.identity. Clients are applications or services that need to request resources whereas API resources are those that provide resources to clients. When registering an API resource, you will need to specify scopes you are expect clients to present to you before they can gain access to use your resource. When registering a client, you will need to specify scopes the client needs in order to request services from API resources.
If you want to register and use our sample application on fabric.identity, you may follow instructions in step 3a. If you have your own appliation/client you want to register, you may follow instructions in step 3b. If you want to register API resources, you may follow instructions in step 3c.
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 choose to skip this step.
Once the fabric.identity container is up and running, use command line window 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. You will also need the client secret for Mvc sample app if you wish to run that application.
After registering and configuring the sample applications with fabric.identity and authorization, you may follow instructions here to build and run the sample applications.
Before you can register your client, you need to first 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.
Once you determine the type of application you have and the appropriate grant type, you will need to POST your client application configuration to the Fabric.Identity /api/client endpoint. See instructions and sample configurations below for implicit flow and hybrid/client-credentials flow.
To register an application, first get a valid access token from Fabric.Identity for the Fabric.Installer application. Run the curl command below, 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]"
Save the access token that is returned.
Next, determine configurations for your client side JavaScript application (a SPA). Below is an example configuration, assuming a URL of http://localhost for the application:
{
"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
}
For detailed explanation of each field in configuration, please visit identity server resource for client.
To register the client and post the configurations to /api/client, run the following curl command, replacing [accesstoken] with the value of the access_token returned from above:
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.
To register an application, first get a valid access token from Fabric.Identity for the Fabric.Installer application. Run the curl command below, 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]"
Save the access token that is returned.
Next, determine configurations for your server side application (an ASP .NET MVC app or a Spring based Java app). Below is an example configuration, assuming a URL of http://localhost for the application:
{
"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
}
For detailed explanation of each field in configuration, please visit identity server resource for client.
To register the client and post the configurations to /api/client, run the following curl command, replacing [accesstoken] with the value of the access_token returned from before:
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.
If you have API resources you want to integrate with fabric.identity for extra security, you will need to first register the API with identity.
Similar to registering clients, to register API resource, you must first get a valid access token from Fabric.Identity for the Fabric.Installer application. Run the curl command below, 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]"
Save the access token that is returned.
Next, determine configurations for your API resource. Below is an example configuration for a SampleAPI
resource with patient.read
and patient.write
scopes:
{
"enabled": true,
"name": "SampleAPI",
"userClaims": [
"name",
"email",
"role",
"groups"
],
"scopes": [
{
"name": "patient.read",
"displayName": "patient.read",
"description": null,
"required": false,
"emphasize": false,
"showInDiscoveryDocument": true,
"userClaims": []
}
{
"name": "patient.write",
"displayName": "patient.write",
"description": null,
"required": false,
"emphasize": false,
"showInDiscoveryDocument": true,
"userClaims": []
}
]
}
For detailed explanation of each field in configuration, please visit identity server resource for apiresource.
To register the client and post the configurations to /api/client, run the following curl command, replacing [accesstoken] with the value of the access_token returned from before:
curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer [accesstoken]" -d "{ \"enabled\": \"true\", \"name\": \"SampleAPI\", \"userClaims\": [\"name\", \"email\", \"role\", \"groups\"], \"scopes\": [{\"name\": \"patient.read\",\"displayname\": \"patient.read\", \"required\": \"false\", \"showInDiscoveryDocument\": \"true\"},{\"name\": \"patient.write\", \"displayname\": \"patient.write\", \"required\": \"false\", \"showInDiscoveryDocument\": \"true\"}]}" http://localhost:5001/api/v1/apiresource
Once you have registered your client application or API resource, you can then begin the process of integrating them with Fabric.Identity. Below are the steps to do that depending on your type of application:
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.
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.
You will need to implement the middleware to handle access token and checking for the appropriate scope for API resource.
If you are using .net core, we have a sample here that implemeneted middleware. This API is set up to require the patientapi
scope (defined in appsettings.json).
If you are using full framework, we have a sample here that implemented middleware This API is set up to require the webapi2
scope (defined in startup.cs).
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.
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: