Author : MD TAREQ HASSAN | Updated : 2020/06/19
Configurations
Config.cs
Quickstart/AccountOptions.cs
Config
- Ids: Identity Resources list i.e. OpenId, Profile, Address etc. (related to identity user info)
- Apis: ApiResources
- Clients: List of clients that will use (allowed to use) Identity Server
public static class Config
{
public static IEnumerable<IdentityResource> Ids =>
new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
//new IdentityResources.Address()
};
public static IEnumerable<ApiResource> Apis =>
new ApiResource[]
{
new ApiResource("api1", "My API #1")
};
public static IEnumerable<Client> Clients =>
new Client[]
{
// client credentials flow client
new Client
{
ClientId = "client",
ClientName = "Client Credentials Client",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets = { new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256()) },
AllowedScopes = { "api1" }
},
// MVC client using code flow + pkce
new Client
{
ClientId = "mvc",
ClientName = "MVC Client",
AllowedGrantTypes = GrantTypes.CodeAndClientCredentials,
RequirePkce = true,
ClientSecrets = { new Secret("49C1A7E1-0C79-4A89-A3D6-A37998FB86B0".Sha256()) },
RedirectUris = { "http://localhost:5003/signin-oidc" },
FrontChannelLogoutUri = "http://localhost:5003/signout-oidc",
PostLogoutRedirectUris = { "http://localhost:5003/signout-callback-oidc" },
AllowOfflineAccess = true,
AllowedScopes = { "openid", "profile", "api1" }
},
new Client
{
ClientId = "postman",
ClientName = "Postman Client",
AllowedGrantTypes = GrantTypes.CodeAndClientCredentials,
RequirePkce = false,
ClientSecrets = { new Secret("hovermind.postman".Sha256()) },
RedirectUris = { "http://localhost:5003/signin-oidc" },
FrontChannelLogoutUri = "http://localhost:5003/signout-oidc",
PostLogoutRedirectUris = { "http://localhost:5003/signout-callback-oidc" },
AllowOfflineAccess = true,
AllowedScopes = { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile }
},
// SPA client using code flow + pkce
new Client
{
ClientId = "spa",
ClientName = "SPA Client",
ClientUri = "http://identityserver.io",
AllowedGrantTypes = GrantTypes.Code,
RequirePkce = true,
RequireClientSecret = false,
RedirectUris =
{
"http://localhost:5002/index.html",
"http://localhost:5002/callback.html",
"http://localhost:5002/silent.html",
"http://localhost:5002/popup.html",
},
PostLogoutRedirectUris = { "http://localhost:5002/index.html" },
AllowedCorsOrigins = { "http://localhost:5002" },
AllowedScopes = { "openid", "profile", "api1" }
}
};
}
AccountOptions
Account related options i.e. AutomaticRedirectAfterSignOut, AllowRememberLogin etc.
public class AccountOptions
{
public static bool AllowLocalLogin = true;
public static bool AllowRememberLogin = true;
public static TimeSpan RememberMeLoginDuration = TimeSpan.FromDays(30);
public static bool ShowLogoutPrompt = true;
public static bool AutomaticRedirectAfterSignOut = false; // apter logout, user will be signed out of IDP also and redirect to main app
// specify the Windows authentication scheme being used
public static readonly string WindowsAuthenticationSchemeName = Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme;
// if user uses windows auth, should we load the groups from windows
public static bool IncludeWindowsGroups = false;
public static string InvalidCredentialsErrorMessage = "Invalid username or password";
}
Claims in Access Token
Add Identity Resources
public static class Config
{
public static IEnumerable<IdentityResource> Ids =>
new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Address()
new IdentityResources {"a", "This is A"}
new IdentityResources {"b", "This is B"}
new IdentityResources {"c", "This is C"}
new IdentityResources {"d", "This is D"}
};
//
}
Allow Client to use (all or subset of) those Identity Resources
public static class Config
{
public static IEnumerable<IdentityResource> Ids =>
new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Address()
new IdentityResources {"a", "This is A"}
new IdentityResources {"b", "This is B"}
new IdentityResources {"c", "This is C"}
new IdentityResources {"d", "This is D"}
};
// ... ... ...
public static IEnumerable<Client> Clients =>
new Client[]
{
// ... ... ...
new Client
{
ClientId = "postman",
ClientName = "Postman Client",
AllowedGrantTypes = GrantTypes.CodeAndClientCredentials,
RequirePkce = false,
ClientSecrets = { new Secret("hovermind.postman".Sha256()) },
RedirectUris = { "http://localhost:5003/signin-oidc" },
FrontChannelLogoutUri = "http://localhost:5003/signout-oidc",
PostLogoutRedirectUris = { "http://localhost:5003/signout-callback-oidc" },
AllowOfflineAccess = true,
AllowedScopes = {
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile
"a",
"b",
"c",
}
},
// ... ... ...
}
Client (WebApp) is asking for (all or subset of) allowed resources (info. about user) from IDP
public class Startup
{
// ... ... ...
public void ConfigureServices(IServiceCollection services)
{
// ... ... ...
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = "https://localhost:5001/";
options.ClientId = "...";
options.ResponseType = "code";
options.UsePkce = true;
options.SaveTokens = true;
options.ClientSecret = "...";
options.GetClaimsFromUserInfoEndpoint = true;
// claims that (WebApp) client asking from IDP
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("a");
options.Scope.Add("b");
});
}
}
So,
- DP Config => IDP added 4 Identity Resources => a, b, c, d (& openid, profile)
- IDP Config => Client was allowed for 3 Identity Resources => a, b, c (& openid, profile)
- (WebApp) Client => asked for 2 claims (Identity Resources) => a, b (& openid, profile)
Therefore, Access Token returned form IDP => will contain Claim ‘a’ & Claim ‘b’ (+ claim openid, + claim profile)