Dangl.Identity Client Libraries
Default Configuration
By default, the identity servers are expected to be reachable at https://identity.dangl-it.com
and https://identity.dangl-it.de
. Fallback happens automatically to the latter on if the former is unreachable.
Dangl.Identity.Client
This project includes the DanglIdentityLoginHandler
that offers JWT / OAuth2 login and refresh functionalities.
Dangl.Identity.OAuth
This project includes utilities for integrating Dangl.Identity in Asp.Net Core web applications.
Dangl.Identity.Client.App
This is a generated client to be used in apps to connect with web services that use Dangl.Identity. The code is generated via nSwag.
Asp.Net Core Identity Server Side Integration
Add the following to the ConfigureServices
method in your Startup
:
services.AddDbContext<IntegrationTestsContext>(o => o.UseSqlite(sqliteConnectionString));
var danglIdentityServerConfig = new DanglIdentityServerConfiguration()
.SetClientId(_clientId)
.SetClientSecret(_clientSecret)
.SetRequiredScope(_requiredScopes)
.SetBaseUri(_baseUri)
.SetFallbackBaseUri(_fallbackBaseUri);
services.AddMvcWithDanglIdentity<IntegrationTestsContext, IntegrationTestsUser, IntegrationTestsRole>(danglIdentityServerConfig);
With clientId
, clientSecret
and requiredScopes
being the respective values as registered
with Dangl.Identity
.
There are more optional parameters present. Use relativeLoginUrl
to communicate the apps specific login path.
This is used to generate correct links for users when they confirm their emails or reset passwords.
By default, the option UseMemoryCacheUserInfoUpdater
is set to true
. This means that the configuration automatically
adds the default Asp.Net Core IMemoryCache
implementation and uses it in the default MemoryCacheUserInfoUpdaterCache : IUserInfoUpdaterCache
.
This is required, because Jwt tokens are checked for user profile data which is then persisted to the local database, e.g. for creating UserId references
in foreign keys. To not have to do database roundtrips, each single Jwt token is only checked once, then only again after it has expired and was refreshed.
Additionally, if Jwt tokens are used for authentication and you want to synchronize user data to a local database, add app.UseDanglIdentityJwtTokenUserInfoUpdater()
after UseAuthentication
, like in the following example:
app.UseAuthentication();
app.UseDanglIdentityJwtTokenUserInfoUpdater();
app.UseMvc();
The DanglIdentityUserInfoUpdater
will evaluate requests that contain a Jwt token and create or update the user data in the database. Tokens are cached in the
provided IUserInfoUpdaterCache
, meaning there should only be a single database hit for every token. With a default expiration time of one hour, most requests
will not hit the database while still providing relatively up-to-date user data. If the token changes, the database will be hit again.
IUserInfoService
Dangl.Identity.OAuth provides an IUserInfoService
:
namespace Dangl.Identity.OAuth.Services
{
public interface IUserInfoService
{
Task<bool> UserIsAuthenticatedAsync();
Task<bool> ClientIsAuthenticatedAsync();
Task<Guid> GetCurrentUserIdAsync();
Task<Guid> GetCurrentClientIdAsync();
Task<string> GetUserIpAddressAsync();
Task<List<Claim>> GetUserClaimsAsync();
Task<List<Claim>> GetClientClaimsAsync();
}
}
Notes:
UserIsAuthenticatedAsync
returns onlytrue
if an actual user is authenticated, it isfalse
for client credential grantsGetUserClaimsAsync
returns all claimsGetClientClaimsAsync
returns only claims whosetype
starts withclient_
Integration with Dangl.Identity.TestHost
When you have multiple TestHost
instances, there might be problems with AuthorizationPolicy
.
The Dangl.Identity server / test host defines a policy that is somehow shared across
all TestServer
instances.
Add this to your Setup
for the integration tests:
var danglIdentityServerConfig = new DanglIdentityServerConfiguration()
.SetAuthorizationSetupAction(o =>
{
o.AddPolicy("scope01", builder => builder.RequireScope("integration_tests"));
o.AddPolicy("scope02", builder => builder.RequireScope("different_scope"));
o.AddPolicy("DelegatedAccountAccess", builder => builder.RequireAssertion(c => { return true; }));
});
Login Method in Your Controllers
Use dependency injection to get a service of type IDanglIdentitySignInManager
to perform
a cookie-backed sign in attemtp via identifier (username or email) and password.
Included DanglIdentityController
There are custom endpoints for the following actions available:
Login with Cookie
POST /identity/login
Body:
{
"identifier": <username or email>,
"password": <password",
"staySignedIn": <boolean>
}
This accepts an optional redirectUrl
query parameter, e.g.
POST /identity/login?redirectUrl=home
Logout with Cookie
DELETE /identity/login
Login and Return Jwt Bearer Token
POST /identity/token-login
Body:
{
"identifier": <username or email>,
"password": <password"
}
Response
{
"accessToken": string
"identityToken": string
"tokenType": string
"refreshToken": string
"errorDescription": string
"expiresIn": number
}
Refresh Jwt Bearer Token
POST /identity/token-refresh
Body:
{
"refreshToken": <refresh token>
}
Response
{
"accessToken": string
"identityToken": string
"tokenType": string
"refreshToken": string
"errorDescription": string
"expiresIn": number
}