Skip to content
This repository has been archived by the owner on Dec 13, 2022. It is now read-only.

Commit

Permalink
update docs for 2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
brockallen committed Sep 26, 2017
1 parent 8516a4f commit 09cd44f
Show file tree
Hide file tree
Showing 17 changed files with 325 additions and 230 deletions.
1 change: 1 addition & 0 deletions docs/index.rst
Expand Up @@ -132,6 +132,7 @@ IdentityServer is officially certified by the OpenID Foundation and part of the
reference/api_resource
reference/client
reference/grant_validation_result
reference/profileservice
reference/interactionservice
reference/options

Expand Down
16 changes: 12 additions & 4 deletions docs/reference/client.rst
Expand Up @@ -34,16 +34,22 @@ Basics
This is useful to harden flows that allow multiple response types
(e.g. by disallowing a hybrid flow client that is supposed to use `code id_token` to add the `token` response type
and thus leaking the token to the browser.
``Properties``
Dictionary to hold any custom client-specific values as needed.

Authentication/Logout
^^^^^^^^^^^^^^^^^^^^^

``PostLogoutRedirectUris``
Specifies allowed URIs to redirect to after logout. See the `OIDC Connect Session Management spec <https://openid.net/specs/openid-connect-session-1_0.html>`_ for more details.
``LogoutUri``
Specifies logout URI at client for HTTP based logout. See the `OIDC Front-Channel spec <https://openid.net/specs/openid-connect-frontchannel-1_0.html>`_ for more details.
``LogoutSessionRequired``
Specifies if the user's session id should be sent to the LogoutUri. Defaults to true.
``FrontChannelLogoutUri``
Specifies logout URI at client for HTTP based front-channel logout. See the `OIDC Front-Channel spec <https://openid.net/specs/openid-connect-frontchannel-1_0.html>`_ for more details.
``FrontChannelLogoutSessionRequired``
Specifies if the user's session id should be sent to the FrontChannelLogoutUri. Defaults to true.
``BackChannelLogoutUri``
Specifies logout URI at client for HTTP based back-channel logout. See the `OIDC Back-Channel spec <https://openid.net/specs/openid-connect-backchannel-1_0.html>`_ for more details.
``BackChannelLogoutSessionRequired``
Specifies if the user's session id should be sent in the request to the BackChannelLogoutUri. Defaults to true.
``EnableLocalLogin``
Specifies if this client can use local accounts, or external IdPs only. Defaults to `true`.
``IdentityProviderRestrictions``
Expand Down Expand Up @@ -94,6 +100,8 @@ Consent Screen
Specifies whether a consent screen is required. Defaults to `true`.
``AllowRememberConsent``
Specifies whether user can choose to store consent decisions. Defaults to `true`.
``ConsentLifetime``
Lifetime of a user consent in seconds. Defaults to null (no expiration).
``ClientName``
Client display name (used for logging and consent screen)
``ClientUri``
Expand Down
20 changes: 11 additions & 9 deletions docs/reference/options.rst
Expand Up @@ -6,6 +6,9 @@ IdentityServer Options
Set the issuer name that will appear in the discovery document and the issued JWT tokens.
It is recommended to not set this property, which infers the issuer name from the host name that is used by the clients.

* ``PublicOrigin``
The origin of this server instance, e.g. https://myorigin.com. If not set, the origin name is inferred from the request.

Endpoints
^^^^^^^^^
Allows enabling/disabling individual endpoints, e.g. token, authorize, userinfo etc.
Expand All @@ -20,18 +23,17 @@ The ``CustomEntries`` dictionary allows adding custom elements to the discovery

Authentication
^^^^^^^^^^^^^^
* ``AuthenticationScheme``
If set, specifies the cookie middleware you want to use. If not set, IdentityServer will use a built-in cookie middleware with default values.
* ``CookieLifetime``
The authentication cookie lifetime (only effective if the IdentityServer-provided cookie handler is used).

* ``RequireAuthenticatedUserForSignOutMessage``
Indicates if user must be authenticated to accept parameters to end session endpoint. Defaults to ``false``.
* ``CookieSlidingExpiration``
Specified if the cookie should be sliding or not (only effective if the IdentityServer-provided cookie handler is used).

* ``FederatedSignOutPaths``
Collection of paths that match ``SignedOutCallbackPath`` on any middleware being used to support external identity providers (such as AzureAD, or ADFS).
``SignedOutCallbackPath`` is used as the "signout cleanup" endpoint called from upstream identity providers when the user signs out of that upstream provider.
This ``SignedOutCallbackPath`` is typically invoked in an ``<iframe>`` from the upstream identity provider, and is intended to sign the user out of the application.
Given that IdentityServer should notify all of its client applications when a user signs out, IdentityServer must extend the behavior at these ``SignedOutCallbackPath`` endpoints to sign the user our of any client applictions of IdentityServer.
* ``RequireAuthenticatedUserForSignOutMessage``
Indicates if user must be authenticated to accept parameters to end session endpoint. Defaults to false.

* ``CheckSessionCookieName``
The name of the cookie used for the check session endpoint.

Events
^^^^^^
Expand Down
50 changes: 50 additions & 0 deletions docs/reference/profileservice.rst
@@ -0,0 +1,50 @@
.. _refProfileService:
Profile Service
===============

Often IdentityServer requires identity information about users when creating tokens or when handling requests to the userinfo or introspection endpoints.
By default, IdentityServer only has the claims in the authentication cookie to draw upon for this identity data.

It is impractical to put all of the possible claims needed for users into the cookie, so IdentityServer defines an extensibility point for allowing claims to be dynamically loaded as needed for a user.
This extensibility point is the ``IProfileService`` and it is common for a developer to implement this interface to access a custom database or API that contains the identity data for users.

IProfileService APIs
^^^^^^^^^^^^^^^^^^^^

``GetProfileDataAsync``
The API that is expected to load claims for a user. It is passed an instance of ``ProfileDataRequestContext``.

``IsActiveAsync``
The API that is expected to indicate if a user is currently allowed to obtain tokens. It is passed an instance of ``IsActiveContext``.

ProfileDataRequestContext
^^^^^^^^^^^^^^^^^^^^^^^^^

Models the request for user claims and is the vehicle to return those claims. It contains these properties:

``Subject``
The ``ClaimsPrincipal`` modeling the user. If the request The claims from the user's cooke will be in the ``ClaimsPrincipal``.
``Client``
The ``Client`` for which the claims are being requested.
``RequestedClaimTypes``
The collection of claim types being requested.
``Caller``
An identifier for the context in which the claims are being requested (e.g. an identity token, an access token, or the user info endpoint). The constant ``IdentityServerConstants.ProfileDataCallers`` contains the different constant values.
``IssuedClaims``
The list of ``Claim``s that will be returned. This is expected to be populated by the custom ``IProfileService`` implementation.
``AddRequestedClaims``
Extension method on the ``ProfileDataRequestContext`` to populate the ``IssuedClaims``, but first filters the claims based on ``RequestedClaimTypes``.

IsActiveContext
^^^^^^^^^^^^^^^

Models the request to determine is the user is currently allowed to obtain tokens. It contains these properties:

``Subject``
The ``ClaimsPrincipal`` modeling the user. If the request The claims from the user's cooke will be in the ``ClaimsPrincipal``.
``Client``
The ``Client`` for which the claims are being requested.
``Caller``
An identifier for the context in which the claims are being requested (e.g. an identity token, an access token, or the user info endpoint). The constant ``IdentityServerConstants.ProfileDataCallers`` contains the different constant values.
``IsActive``
The flag indicating if the user is allowed to obtain tokens. This is expected to be assigned by the custom ``IProfileService`` implementation.
123 changes: 67 additions & 56 deletions docs/topics/apis.rst
Expand Up @@ -6,96 +6,106 @@ IdentityServer issues access tokens in the `JWT <https://tools.ietf.org/html/rfc
Every relevant platform today has support for validating JWT tokens, a good list of JWT libraries can be found `here <https://jwt.io>`_.
Popular libraries are e.g.:

* `JWT bearer authentication middleware <https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.JwtBearer/>`_ for ASP.NET Core
* `JWT bearer authentication handler <https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.JwtBearer/>`_ for ASP.NET Core
* `JWT bearer authentication middleware <https://www.nuget.org/packages/Microsoft.Owin.Security.Jwt>`_ for Katana
* `jsonwebtoken <https://www.npmjs.com/package/jsonwebtoken>`_ for nodejs

Protecting an MVC Core-based API is only a matter of adding the nuget package *(Microsoft.AspNetCore.Authentication.JwtBearer)* to your project
and adding the middleware to the ASP.NET Core pipeline::
Protecting a ASP.NET Core-based API is only a matter of configuring the JWT bearer authentication handler in DI, and adding the authentication middleware to the pipeline::

public class Startup
{
public void Configure(IApplicationBuilder app)
public void ConfigureServices(IServiceCollection services)
{
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
// base-address of your identityserver
Authority = "https://demo.identityserver.io",
// name of the API resource
Audience = "api1",

AutomaticAuthenticate = true,
AutomaticChallenge = true
});
services.AddMvc();

services.AddAuthentication("Bearer")
.AddJwtBearer(options =>
{
// base-address of your identityserver
options.Authority = "https://demo.identityserver.io";

// name of the API resource
options.Audience = "api1";
});
}

public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
app.UseAuthentication();
app.UseMvc();
}
}

The IdentityServer authentication middleware
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Our authentication middleware serves the same purpose as the above middleware
(in fact it uses the Microsoft JWT middleware internally), but adds a couple of additional features:
The IdentityServer authentication handler
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Our authentication handler serves the same purpose as the above handler
(in fact it uses the Microsoft JWT library internally), but adds a couple of additional features:

* support for both JWTs and reference tokens
* extensible caching for reference tokens
* unified configuration model
* scope validation

For the simplest case, our middleware looks very similar to the above snippet::
For the simplest case, our handler configuration looks very similar to the above snippet::

public class Startup
{
public void Configure(IApplicationBuilder app)
public void ConfigureServices(IServiceCollection services)
{
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
Authority = "https://demo.identityserver.io",
ApiName = "api1"
services.AddMvc();

AutomaticAuthenticate = true,
AutomaticChallenge = true
});
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
// base-address of your identityserver
options.Authority = "https://demo.identityserver.io";

// name of the API resource
options.ApiName = "api1";
});
}

public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
app.UseAuthentication();
app.UseMvc();
}
}

You can get the middleware from `nuget <https://www.nuget.org/packages/IdentityServer4.AccessTokenValidation/>`_
You can get the package from `nuget <https://www.nuget.org/packages/IdentityServer4.AccessTokenValidation/>`_
or `github <https://github.com/IdentityServer/IdentityServer4.AccessTokenValidation>`_.

Supporting reference tokens
^^^^^^^^^^^^^^^^^^^^^^^^^^^
If the incoming token is not a JWT, our middleware will contact the introspection endpoint found in the discovery document to validate the token.
Since the introspection endpoint requires authentication, you need to supply the configured API secret, e.g.::

app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
.AddIdentityServerAuthentication(options =>
{
Authority = "https://demo.identityserver.io",
ApiName = "api1",
ApiSecret = "secret",
// base-address of your identityserver
options.Authority = "https://demo.identityserver.io";

AutomaticAuthenticate = true,
AutomaticChallenge = true
});
// name of the API resource
options.ApiName = "api1";
options.ApiSecret = "secret";
})

Typically, you don't want to do a roundtrip to the introspection endpoint for each incoming request. The middleware has a built-in cache that you can enable like this::

app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
.AddIdentityServerAuthentication(options =>
{
Authority = "https://demo.identityserver.io",
ApiName = "api1",
ApiSecret = "secret",
// base-address of your identityserver
options.Authority = "https://demo.identityserver.io";

EnableCaching = true,
CacheDuration = TimeSpan.FromMinutes(10), // that's the default
// name of the API resource
options.ApiName = "api1";
options.ApiSecret = "secret";

AutomaticAuthenticate = true,
AutomaticChallenge = true
});
options.EnableCaching = true;
options.CacheDuration = TimeSpan.FromMinutes(10); // that's the default
})

The middleware will use whatever `IDistributedCache` implementation is registered in the DI container (e.g. the standad `IDistributedInMemoryCache`).
The handler will use whatever `IDistributedCache` implementation is registered in the DI container (e.g. the standad `IDistributedInMemoryCache`).

Validating scopes
^^^^^^^^^^^^^^^^^
Expand All @@ -104,16 +114,17 @@ The `ApiName` property checks if the token has a matching audience (or short ``a
In IdentityServer you can also sub-divide APIs into multiple scopes. If you need that granularity and want to check those scopes at the middleware level,
you can add the ``AllowedScopes`` property::

app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
.AddIdentityServerAuthentication(options =>
{
Authority = "https://demo.identityserver.io",
ApiName = "api1",
AllowedScopes = { "api1.read", "api1.write" }

AutomaticAuthenticate = true,
AutomaticChallenge = true
});
// base-address of your identityserver
options.Authority = "https://demo.identityserver.io";

// name of the API resource
options.ApiName = "api1";
options.ApiSecret = "secret";

options.AllowedScopes = { "api1.read", "api1.write" };
})


**Note on Targeting Earlier .NET Frameworks**
Expand Down
2 changes: 1 addition & 1 deletion docs/topics/clients.rst
Expand Up @@ -81,7 +81,7 @@ This flow gives you the best security because the access tokens are transmitted
RedirectUris = { "http://localhost:21402/signin-oidc" },
PostLogoutRedirectUris = { "http://localhost:21402/" },
LogoutUri = "http://localhost:21402/signout-oidc",
FrontChannelLogoutUri = "http://localhost:21402/signout-oidc",

AllowedScopes =
{
Expand Down
3 changes: 2 additions & 1 deletion docs/topics/deployment.rst
Expand Up @@ -2,8 +2,9 @@ Deployment
==========
Your identity server is `just` a standard ASP.NET Core appplication including the IdentityServer middleware.
Read the official Microsoft `documenatation <https://docs.microsoft.com/en-us/aspnet/core/publishing>`_ on publishing and deployment first.
You will also most likely need to configure the `ASP.NET Core data protection <https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview?tabs=aspnetcore2x>`_ for a load-balanced environment.

One common question is how to configure ASP.NET Core correctly behind a load-balancer or a reverse proxy. Check this github `issue <https://github.com/aspnet/Docs/issues/2384>`_ for more info.
.. note:: One common question is how to configure ASP.NET Core correctly behind a load-balancer or a reverse proxy. Check this github `issue <https://github.com/aspnet/Docs/issues/2384>`_ for more info.

Configuration data
^^^^^^^^^^^^^^^^^^
Expand Down
47 changes: 27 additions & 20 deletions docs/topics/logging.rst
Expand Up @@ -25,31 +25,38 @@ From Package Manager Console verify that Default Project drop-down has your proj
install-package Serilog.Sinks.File
install-package Serilog.Sinks.Literate

You want to setup logging as early as possible in your application host, e.g. in the constructor of your startup class, e.g::
You want to setup logging as early as possible in your application host, e.g. in ``Main``::

public class Startup
public class Program
{
public Startup(ILoggerFactory loggerFactory, IHostingEnvironment environment)
public static void Main(string[] args)
{
var serilog = new LoggerConfiguration()
.MinimumLevel.Verbose()
Console.Title = "IdentityServer4";

Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.MinimumLevel.Override("System", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.AspNetCore.Authentication", LogEventLevel.Information)
.Enrich.FromLogContext()
.WriteTo.File(@"identityserver4_log.txt");

if (environment.IsDevelopment())
{
serilog.WriteTo.LiterateConsole(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message}{NewLine}{Exception}{NewLine}");
}

loggerFactory
.WithFilter(new FilterLoggerSettings
{
{ "IdentityServer", LogLevel.Debug },
{ "Microsoft", LogLevel.Information },
{ "System", LogLevel.Error },
})
.AddSerilog(serilog.CreateLogger());
.WriteTo.File(@"identityserver4_log.txt")
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme: AnsiConsoleTheme.Literate)
.CreateLogger();

BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging(builder =>
{
builder.ClearProviders();
builder.AddSerilog();
})
.Build();
}
}

Further reading
Expand Down

0 comments on commit 09cd44f

Please sign in to comment.