Hi,
My application is not being logged in. I am using the following source code.
https://github.com/emonney/QuickApp
and then upgraded the same source in angular 6, install angular material 6 and tried to use its components.
The problem is actually the app is not being logged in. Method is unable to call. Sometimes function is being called properly and sometimes throwing errors.
Error is this :
Failed to load resource: the server responded with a status of 404 (Not Found)
alert.service.ts:154 Severity: "error", Summary: "Unable to login", Detail: "An error occured whilst logging in, please try again later.
Error: Not Found", Error: "{"headers":{"normalizedNames":{},"lazyUpdate":null},"status":404,"statusText":"Not Found","url":"http://localhost:4200/connect/token","ok":false,"name":"HttpErrorResponse","message":"Http failure response for http://localhost:4200/connect/token:
404 Not Found","error":"<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot POST /connect/token</pre>\n</body>\n</html>\n"}"
// add identity services.AddIdentity<ApplicationUser, ApplicationRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders(); // Configure Identity options and password complexity here services.Configure<IdentityOptions>(options => { // User settings options.User.RequireUniqueEmail = true; options.ClaimsIdentity.UserNameClaimType = OpenIdConnectConstants.Claims.Name; options.ClaimsIdentity.UserIdClaimType = OpenIdConnectConstants.Claims.Subject; options.ClaimsIdentity.RoleClaimType = OpenIdConnectConstants.Claims.Role; }); // Register the OpenIddict services. services.AddOpenIddict(options => { options.AddEntityFrameworkCoreStores<ApplicationDbContext>(); options.AddMvcBinders(); options.EnableTokenEndpoint("/connect/token"); options.AllowPasswordFlow(); options.AllowRefreshTokenFlow(); options.DisableHttpsRequirement(); }); services.AddAuthentication(options => { options.DefaultAuthenticateScheme = OAuthValidationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OAuthValidationDefaults.AuthenticationScheme; }).AddOAuthValidation(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Title = "SaleStoreAppUI API", Version = "v1" }); c.AddSecurityDefinition("OpenID Connect", new OAuth2Scheme { Type = "oauth2", Flow = "password", TokenUrl = "/connect/token" }); }); services.AddAuthorization(options => { options.AddPolicy(Authorization.Policies.ViewAllUsersPolicy, policy => policy.RequireClaim(CustomClaimTypes.Permission, AppPermissions.ViewUsers)); options.AddPolicy(Authorization.Policies.ManageAllUsersPolicy, policy => policy.RequireClaim(CustomClaimTypes.Permission, AppPermissions.ManageUsers)); options.AddPolicy(Authorization.Policies.ViewAllRolesPolicy, policy => policy.RequireClaim(CustomClaimTypes.Permission, AppPermissions.ViewRoles)); options.AddPolicy(Authorization.Policies.ViewRoleByRoleNamePolicy, policy => policy.Requirements.Add(new ViewRoleAuthorizationRequirement())); options.AddPolicy(Authorization.Policies.ManageAllRolesPolicy, policy => policy.RequireClaim(CustomClaimTypes.Permission, AppPermissions.ManageRoles)); options.AddPolicy(Authorization.Policies.AssignAllowedRolesPolicy, policy => policy.Requirements.Add(new AssignRolesAuthorizationRequirement())); }); Mapper.Initialize(cfg => { cfg.AddProfile<AutoMapperProfile>(); });
-------------------------------Authorization Controller----------------------------------------
[HttpPost("~/connect/token")]
[Produces("application/json")]
public async Task<IActionResult> Exchange(OpenIdConnectRequest request)
{
if (request.IsPasswordGrantType())
{
var user = await _userManager.FindByEmailAsync(request.Username) ?? await _userManager.FindByNameAsync(request.Username);
if (user == null)
{
return BadRequest(new OpenIdConnectResponse
{
Error = OpenIdConnectConstants.Errors.InvalidGrant,
ErrorDescription = "Please check that your email and password is correct"
});
}
// Ensure the user is enabled.
if (!user.IsEnabled)
{
return BadRequest(new OpenIdConnectResponse
{
Error = OpenIdConnectConstants.Errors.InvalidGrant,
ErrorDescription = "The specified user account is disabled"
});
}
// Validate the username/password parameters and ensure the account is not locked out.
var result = await _signInManager.CheckPasswordSignInAsync(user, request.Password, true);
// Ensure the user is not already locked out.
if (result.IsLockedOut)
{
return BadRequest(new OpenIdConnectResponse
{
Error = OpenIdConnectConstants.Errors.InvalidGrant,
ErrorDescription = "The specified user account has been suspended"
});
}
// Reject the token request if two-factor authentication has been enabled by the user.
if (result.RequiresTwoFactor)
{
return BadRequest(new OpenIdConnectResponse
{
Error = OpenIdConnectConstants.Errors.InvalidGrant,
ErrorDescription = "Invalid login procedure"
});
}
// Ensure the user is allowed to sign in.
if (result.IsNotAllowed)
{
return BadRequest(new OpenIdConnectResponse
{
Error = OpenIdConnectConstants.Errors.InvalidGrant,
ErrorDescription = "The specified user is not allowed to sign in"
});
}
if (!result.Succeeded)
{
return BadRequest(new OpenIdConnectResponse
{
Error = OpenIdConnectConstants.Errors.InvalidGrant,
ErrorDescription = "Please check that your email and password is correct"
});
}
// Create a new authentication ticket.
var ticket = await CreateTicketAsync(request, user);
return SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme);
}
else if (request.IsRefreshTokenGrantType())
{
// Retrieve the claims principal stored in the refresh token.
var info = await HttpContext.AuthenticateAsync(OpenIdConnectServerDefaults.AuthenticationScheme);
// Retrieve the user profile corresponding to the refresh token.
// Note: if you want to automatically invalidate the refresh token
// when the user password/roles change, use the following line instead:
// var user = _signInManager.ValidateSecurityStampAsync(info.Principal);
var user = await _userManager.GetUserAsync(info.Principal);
if (user == null)
{
return BadRequest(new OpenIdConnectResponse
{
Error = OpenIdConnectConstants.Errors.InvalidGrant,
ErrorDescription = "The refresh token is no longer valid"
});
}
// Ensure the user is still allowed to sign in.
if (!await _signInManager.CanSignInAsync(user))
{
return BadRequest(new OpenIdConnectResponse
{
Error = OpenIdConnectConstants.Errors.InvalidGrant,
ErrorDescription = "The user is no longer allowed to sign in"
});
}
// Create a new authentication ticket, but reuse the properties stored
// in the refresh token, including the scopes originally granted.
var ticket = await CreateTicketAsync(request, user);
return SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme);
}
return BadRequest(new OpenIdConnectResponse
{
Error = OpenIdConnectConstants.Errors.UnsupportedGrantType,
ErrorDescription = "The specified grant type is not supported"
});
}
-----------------------------auth.service.ts--------------------------------------------------------------------
// ====================================================
// More Templates: https://www.ebenmonney.com/templates
// Email: support@ebenmonney.com
// ====================================================
import { Injectable } from '@angular/core';
import { Router, NavigationExtras } from "@angular/router";
import { Observable , Subject } from 'rxjs';
import { LocalStoreManager } from './local-store-manager.service';
import { EndpointFactory } from './endpoint-factory.service';
import { ConfigurationService } from './configuration.service';
import { DBkeys } from './db-Keys';
import { JwtHelper } from './jwt-helper';
import { Utilities } from './utilities';
import { LoginResponse, IdToken } from '../models/login-response.model';
import { User } from '../models/user.model';
import { Permission, PermissionNames, PermissionValues } from '../models/permission.model';
@Injectable()
export class AuthService {
public get loginUrl() { return this.configurations.loginUrl; }
public get homeUrl() { return this.configurations.homeUrl; }
public loginRedirectUrl: string;
public logoutRedirectUrl: string;
public reLoginDelegate: () => void;
private previousIsLoggedInCheck = false;
private _loginStatus = new Subject<boolean>();
constructor(private router: Router, private configurations: ConfigurationService, private endpointFactory: EndpointFactory, private localStorage: LocalStoreManager) {
this.initializeLoginStatus();
}
private initializeLoginStatus() {
this.localStorage.getInitEvent().subscribe(() => {
this.reevaluateLoginStatus();
});
}
gotoPage(page: string, preserveParams = true) {
let navigationExtras: NavigationExtras = {
queryParamsHandling: preserveParams ? "merge" : "", preserveFragment: preserveParams
};
this.router.navigate([page], navigationExtras);
}
redirectLoginUser() {
let redirect = this.loginRedirectUrl && this.loginRedirectUrl != '/' && this.loginRedirectUrl != ConfigurationService.defaultHomeUrl ? this.loginRedirectUrl : this.homeUrl;
this.loginRedirectUrl = null;
let urlParamsAndFragment = Utilities.splitInTwo(redirect, '#');
let urlAndParams = Utilities.splitInTwo(urlParamsAndFragment.firstPart, '?');
let navigationExtras: NavigationExtras = {
fragment: urlParamsAndFragment.secondPart,
queryParams: Utilities.getQueryParamsFromString(urlAndParams.secondPart),
queryParamsHandling: "merge"
};
this.router.navigate([urlAndParams.firstPart], navigationExtras);
}
redirectLogoutUser() {
let redirect = this.logoutRedirectUrl ? this.logoutRedirectUrl : this.loginUrl;
this.logoutRedirectUrl = null;
this.router.navigate([redirect]);
}
redirectForLogin() {
this.loginRedirectUrl = this.router.url;
this.router.navigate([this.loginUrl]);
}
reLogin() {
this.localStorage.deleteData(DBkeys.TOKEN_EXPIRES_IN);
if (this.reLoginDelegate) {
this.reLoginDelegate();
}
else {
this.redirectForLogin();
}
}
refreshLogin() {
return this.endpointFactory.getRefreshLoginEndpoint<LoginResponse>()
.map(response => this.processLoginResponse(response, this.rememberMe));
}
login(userName: string, password: string, rememberMe?: boolean) {
if (this.isLoggedIn)
this.logout();
return this.endpointFactory.getLoginEndpoint<LoginResponse>(userName, password)
.map(
response =>
this.processLoginResponse(response, rememberMe)
);
}
private processLoginResponse(response: LoginResponse, rememberMe: boolean) {
debugger;
let accessToken = response.access_token;
if (accessToken == null)
throw new Error("Received accessToken was empty");
let idToken = response.id_token;
let refreshToken = response.refresh_token || this.refreshToken;
let expiresIn = response.expires_in;
let tokenExpiryDate = new Date();
tokenExpiryDate.setSeconds(tokenExpiryDate.getSeconds() + expiresIn);
let accessTokenExpiry = tokenExpiryDate;
let jwtHelper = new JwtHelper();
let decodedIdToken = <IdToken>jwtHelper.decodeToken(response.id_token);
let permissions: PermissionValues[] = Array.isArray(decodedIdToken.permission) ? decodedIdToken.permission : [decodedIdToken.permission];
if (!this.isLoggedIn)
this.configurations.import(decodedIdToken.configuration);
let user = new User(
decodedIdToken.sub,
decodedIdToken.name,
decodedIdToken.fullname,
decodedIdToken.email,
decodedIdToken.jobtitle,
decodedIdToken.phone,
Array.isArray(decodedIdToken.role) ? decodedIdToken.role : [decodedIdToken.role]);
user.isEnabled = true;
this.saveUserDetails(user, permissions, accessToken, idToken, refreshToken, accessTokenExpiry, rememberMe);
this.reevaluateLoginStatus(user);
return user;
}
private saveUserDetails(user: User, permissions: PermissionValues[], accessToken: string, idToken: string, refreshToken: string, expiresIn: Date, rememberMe: boolean) {
if (rememberMe) {
this.localStorage.savePermanentData(accessToken, DBkeys.ACCESS_TOKEN);
this.localStorage.savePermanentData(idToken, DBkeys.ID_TOKEN);
this.localStorage.savePermanentData(refreshToken, DBkeys.REFRESH_TOKEN);
this.localStorage.savePermanentData(expiresIn, DBkeys.TOKEN_EXPIRES_IN);
this.localStorage.savePermanentData(permissions, DBkeys.USER_PERMISSIONS);
this.localStorage.savePermanentData(user, DBkeys.CURRENT_USER);
}
else {
this.localStorage.saveSyncedSessionData(accessToken, DBkeys.ACCESS_TOKEN);
this.localStorage.saveSyncedSessionData(idToken, DBkeys.ID_TOKEN);
this.localStorage.saveSyncedSessionData(refreshToken, DBkeys.REFRESH_TOKEN);
this.localStorage.saveSyncedSessionData(expiresIn, DBkeys.TOKEN_EXPIRES_IN);
this.localStorage.saveSyncedSessionData(permissions, DBkeys.USER_PERMISSIONS);
this.localStorage.saveSyncedSessionData(user, DBkeys.CURRENT_USER);
}
this.localStorage.savePermanentData(rememberMe, DBkeys.REMEMBER_ME);
}
logout(): void {
this.localStorage.deleteData(DBkeys.ACCESS_TOKEN);
this.localStorage.deleteData(DBkeys.ID_TOKEN);
this.localStorage.deleteData(DBkeys.REFRESH_TOKEN);
this.localStorage.deleteData(DBkeys.TOKEN_EXPIRES_IN);
this.localStorage.deleteData(DBkeys.USER_PERMISSIONS);
this.localStorage.deleteData(DBkeys.CURRENT_USER);
this.configurations.clearLocalChanges();
this.reevaluateLoginStatus();
}
private reevaluateLoginStatus(currentUser?: User) {
let user = currentUser || this.localStorage.getDataObject<User>(DBkeys.CURRENT_USER);
let isLoggedIn = user != null;
if (this.previousIsLoggedInCheck != isLoggedIn) {
setTimeout(() => {
this._loginStatus.next(isLoggedIn);
});
}
this.previousIsLoggedInCheck = isLoggedIn;
}
getLoginStatusEvent(): Observable<boolean> {
return this._loginStatus.asObservable();
}
get currentUser(): User {
let user = this.localStorage.getDataObject<User>(DBkeys.CURRENT_USER);
this.reevaluateLoginStatus(user);
return user;
}
get userPermissions(): PermissionValues[] {
return this.localStorage.getDataObject<PermissionValues[]>(DBkeys.USER_PERMISSIONS) || [];
}
get accessToken(): string {
this.reevaluateLoginStatus();
return this.localStorage.getData(DBkeys.ACCESS_TOKEN);
}
get accessTokenExpiryDate(): Date {
this.reevaluateLoginStatus();
return this.localStorage.getDataObject<Date>(DBkeys.TOKEN_EXPIRES_IN, true);
}
get isSessionExpired(): boolean {
if (this.accessTokenExpiryDate == null) {
return true;
}
return !(this.accessTokenExpiryDate.valueOf() > new Date().valueOf());
}
get idToken(): string {
this.reevaluateLoginStatus();
return this.localStorage.getData(DBkeys.ID_TOKEN);
}
get refreshToken(): string {
this.reevaluateLoginStatus();
return this.localStorage.getData(DBkeys.REFRESH_TOKEN);
}
get isLoggedIn(): boolean {
return this.currentUser != null;
}
get rememberMe(): boolean {
return this.localStorage.getDataObject<boolean>(DBkeys.REMEMBER_ME) == true;
}
}
Authorization controller----------------------------------------------------------------