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
- JavaScript client library:
- OpenIDConnect Certified Relying Party Libraries
- OpenIDConnect Sample RP: Ruby Sample Client