Samples

The examples below are for Client Credentials and Implicit flow types. Samples for actual configuration values can be provided upon request.

Sample Client - Client Credential

Registered with client credential grant/flow type, this client is (or provides) an API resource that other clients can access if given the proper scope.

Server side registration of the client: (C#)

  new Client
  {
      ClientId = "sample.client",
      Description = "Protected API client for sampleApi",
      // no interactive user, use the clientid/secret for authentication
      AllowedGrantTypes = GrantTypes.ClientCredentials,

      // secret for authentication
      ClientSecrets =
      {
          new Secret("sample.secret".Sha256())
      },

      // scopes that client has access to
      AllowedScopes = { "sampleApi" }
  }

This sample client can request tokens (access_token) from the OP and has access to "sampleApi" API resource.

Client side: (C#)

Using IdentityModel nuget package (v4.0.0 as of this writing), the core of the sample request(s) on the client side being:

  // discover endpoints from metadata
  var client = new HttpClient();
  var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest()
  {
      Address = "https://soc.crmls.org",
      Policy = { RequireHttps = true }
  });
  // request token
  var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
  {
      Address = disco.TokenEndpoint,
      ClientId = "sample.client",
      ClientSecret = "sample.secret",

      Scope = "sampleApi"
  });

Then with the tokenResponse, the client can access the API resource similar to this:

  // call api
  var apiClient = new HttpClient();
  apiClient.SetBearerToken(tokenResponse.AccessToken);

  // call/request to arbitrary controller endpoint that is protected
  var response = await apiClient.GetAsync("http://sampleApiUrl/protectedApi");

Sample Client - Implicit Flow

Registered with implicit grant/flow type, this client provides the end user access to an API resource via browser client (e.g. javascript - ajax call to the same protected "sampleApi" endpoint). Assuming the application that provides the API resource has been configured to allow CORS from this sample js client.

Server side registration of the client: (C#)

  // Registration of JavaScript Client
  new Client
  {
      ClientId = "sample.jsClient",
      Description = "Sample Javascript Client",
      ClientName = "sampleJsClient",
      AllowedGrantTypes = GrantTypes.Implicit,
      RequireClientSecret = false,
      RedirectUris =           { "http://sample.jsclient.com/callback.html", "http://sample.jsclient.com/silent.html" },
      PostLogoutRedirectUris = { "http://sample.jsclient.com/index.html" },

      AllowedScopes =
      {
          IdentityServerConstants.StandardScopes.OpenId,
          IdentityServerConstants.StandardScopes.Profile,
          "CrmlsProfile",
          "sampleApi"
      }
  }

This sample client registration allows authentication of an end user and allows the client to access the "sampleApi" API resource (given a successful login that provides an access_token).

Setting up the Browser Client (javascript)

Using oidc-client.js, the core configuration of the client application:

var config = {
  authority: "https://soc.crmls.org",
  client_id: "sample.jsClient",
  redirect_uri: "http://sample.jsclient.com/callback.html",
  response_type: "id_token token",
  scope: "openid profile CrmlsProfile sampleApi",
  post_logout_redirect_uri: "https://idp.crmls.org/idp/logout.jsp",
  loadUserInfo: true,
  // External IDP claims (i.e., Clareity)
  acr_values: "idp:Saml2",
  // For silent renewals (which also provides end of session event when renewal fails)
  silent_redirect_url: "http://sample.jsclient.com/silent.html",
};
var mgr = new Oidc.UserManager(config);

Logging in (e.g., 'login' button) can be bound to a login() function and an API call (e.g., 'call api' button) can be bound to a callApi() function defined as follows:

function login() {
  mgr.signinRedirect();
}

function callApi() {
  mgr.getUser().then(function (user) {
    var xhr = new XMLHttpRequest();
    xhr.onload = function (e) {
      if (xhr.status >= 400) {
        // call to display results of error
        display("#results", {
          status: xhr.status,
          statusText: xhr.statusText,
          wwwAuthenticate: xhr.getResponseHeader("WWW-Authenticate")
        });
      }
      else {
        // call to display results of success
        display("#results", xhr.response);
      }
    };
    xhr.open("GET", "http://sampleApiUrl/protectedApi", true);
    xhr.setRequestHeader("Authorization", "Bearer " + user.access_token);
    xhr.send();
  });
}

The examples above use arbitrary id's and URL's that are not in CRMLS OP's configurations.

For a quick client setup and demo application using CRMLS OP's test servers, see Getting Started

References and Additional Client Samples