I'm learning angular and I find a problem that I didn't see anywhere else. To the point, when I'm trying to login to my client angular app with oidc-client via identityserver, It's working great up to a point. I'm redirecting to a identityserver, logged in, goes back to the login-callback, in server-side i'm authorized, but if I want to check if I'm authorized in client-side, I got a null user. If i want to logout, I got redirect to sign out in identityserver where I can see my token:
Server-side config.cs:
public class Config
{
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Email(),
new IdentityResources.Profile(),
new IdentityResource("RedDot.API.read", new[] { JwtClaimTypes.Name, JwtClaimTypes.Email, "location" })
};
}
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("RedDot.API.read", "Resource API")
{
ApiSecrets =
{
new Secret("secret".Sha256())
},
UserClaims =
{
JwtClaimTypes.Name,
JwtClaimTypes.Email
},
Scopes = new List<string> { "RedDot.API.read" }
}
};
}
public static IEnumerable<Client> GetClients()
{
return new[]
{
new Client {
RequireConsent = false,
ClientId = "reddot_ui",
ClientName = "RedDot",
AllowedGrantTypes = GrantTypes.Code,
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"RedDot.API.read"
},
RedirectUris = {"https://localhost:4200/login-callback"},
PostLogoutRedirectUris = {"https://localhost:4200/"},
AllowedCorsOrigins = {"https://localhost:4200"},
AllowAccessTokensViaBrowser = true,
AccessTokenLifetime = 3600,
ClientSecrets =
{
new Secret("rwebv832hvegfh49--l-w".Sha256())
},
}
};
}
}
Program.cs:
builder.Services.AddDbContext<AppIdentityDbContext>(options => options.UseSqlServer(dataConnectionString, conf => conf.MigrationsAssembly(assembly)));
builder.Services.AddIdentity<AppUser, IdentityRole>()
.AddEntityFrameworkStores<AppIdentityDbContext>()
.AddDefaultTokenProviders();
builder.Services.AddIdentityServer().AddDeveloperSigningCredential()
.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder => builder.UseSqlServer(dataConnectionString, conf => conf.MigrationsAssembly(assembly));
})
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
.AddAspNetIdentity<AppUser>();
Client-side angular config:
private getUserManager() {
if (!this._userManager) {
const userManagerSettings: UserManagerSettings =
new UserManagerSettings();
userManagerSettings.authority = 'https://localhost:5443';
userManagerSettings.client_id = 'reddot_ui';
userManagerSettings.response_type = 'code';
userManagerSettings.scope = 'openid profile RedDot.API.read';
userManagerSettings.redirect_uri = 'https://localhost:4200/login-callback';
userManagerSettings.post_logout_redirect_uri = 'https://localhost:4200/logout-callback';
userManagerSettings.automaticSilentRenew = true;
userManagerSettings.silent_redirect_uri = 'https://localhost:4200/silent-callback';
userManagerSettings.userStore = new WebStorageStateStore({
store: window.localStorage,
}); // store information about Authentication in localStorage
this._userManager = new UserManager(userManagerSettings);
this._userManager.getUser().then((user) => {
this._user = user;
this.isUserDefined = true;
});
}
}
Rest of authorize class in angular:
import { Injectable } from "@angular/core";
import { User, UserManager, WebStorageStateStore } from "oidc-client";
import { UserManagerSettings } from "../_models/usermanager.settings";
@Injectable()
export class AuthenticationService {
isUserDefined = false;
private _user: User | null;
private _userManager: UserManager;
isLoggedIn() {
return this._user != null && !this._user.expired;
}
getName() {
return this._user?.profile.nickname;
}
getAccessToken() {
return this._user ? this._user.access_token : "";
}
getClaims() {
return this._user?.profile;
}
startAuthentication() : Promise<void> {
this.getUserManager();
return this._userManager.signinRedirect();
}
completeAuthentication() {
this.getUserManager();
return this._userManager.signinRedirectCallback().then((user) => {
this._user = user;
this.isUserDefined = true;
});
}
startLogout(): Promise<void> {
this.getUserManager();
return this._userManager.signoutRedirect();
}
completeLogout() {
this.getUserManager();
this._user = null;
return this._userManager.signoutRedirectCallback();
}
silentSignInAuthentication() {
this.getUserManager();
return this._userManager.signinSilentCallback();
}
}
Dunno where the problem can be and why I'm not authorized on client-side.
I've tried to change response type and protocol from http to https and conversely with no effect. Maybe somebody had the same problem.