-
Notifications
You must be signed in to change notification settings - Fork 6
Getting Started
The below documentation will help you quickly get started running Fabric.Identity in Docker and configuring an application to use it. Fabric.Identity implements the OpenID Connect protocol, via IdentityServer4. So the documentation provided by each can supplement this quick start guide.
You can install docker based on the instructions found 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.
Once the fabric.identity container is up and running, execute the setup-samples.sh script to setup the configuration to run our sample applications against Fabric.Identity.
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.
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.
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 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.
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.
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.
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:
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.
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: