احراز هویت و اعتبارسنجی کاربران در برنامههای Angular - قسمت پنجم - محافظت از مسیرها
نویسنده: وحید نصیری
تاریخ: ۱۳۹۶/۰۹/۲۹ ۸:۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
public IActionResult Get()
{
var user = this.User.Identity as ClaimsIdentity;
var config = new
{
userName = user.Name,
roles = user.Claims.Where(x => x.Type == ClaimTypes.Role).Select(x => x.Value).ToList()
};
return Ok(config);
} {
"jti": "d1272eb5-1061-45bd-9209-3ccbc6ddcf0a",
"iss": "http://localhost/",
"iat": 1513070340,
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier": "1",
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name": "Vahid",
"DisplayName": "وحید",
"http://schemas.microsoft.com/ws/2008/06/identity/claims/serialnumber": "709b64868a1d4d108ee58369f5c3c1f3",
"http://schemas.microsoft.com/ws/2008/06/identity/claims/userdata": "1",
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role": [
"Admin",
"User"
],
"nbf": 1513070340,
"exp": 1513070460,
"aud": "Any"
} export interface AuthUser {
userId: string;
userName: string;
displayName: string;
roles: string[];
} getAuthUser(): AuthUser {
if (!this.isLoggedIn()) {
return null;
}
const decodedToken = this.getDecodedAccessToken();
let roles = decodedToken["http://schemas.microsoft.com/ws/2008/06/identity/claims/role"];
if (roles) {
roles = roles.map(role => role.toLowerCase());
}
return Object.freeze({
userId: decodedToken["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"],
userName: decodedToken["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"],
displayName: decodedToken["DisplayName"],
roles: roles
});
} import { ProtectedPageComponent } from "./protected-page/protected-page.component";
import { AuthGuardPermission } from "../core/models/auth-guard-permission";
const routes: Routes = [
{
path: "protectedPage",
component: ProtectedPageComponent,
data: {
permission: {
permittedRoles: ["Admin"],
deniedRoles: null
} as AuthGuardPermission
}
}
]; export interface AuthGuardPermission {
permittedRoles?: string[];
deniedRoles?: string[];
} >ng g c Authentication/AccessDenied
AccessDenied create src/app/Authentication/access-denied/access-denied.component.html (32 bytes) create src/app/Authentication/access-denied/access-denied.component.ts (296 bytes) create src/app/Authentication/access-denied/access-denied.component.css (0 bytes) update src/app/Authentication/authentication.module.ts (550 bytes)
import { LoginComponent } from "./login/login.component";
import { AccessDeniedComponent } from "./access-denied/access-denied.component";
const routes: Routes = [
{ path: "login", component: LoginComponent },
{ path: "accessDenied", component: AccessDeniedComponent }
]; <h1 class="text-danger"> <span class="glyphicon glyphicon-ban-circle"></span> Access Denied </h1> <p>Sorry! You don't have access to this page.</p> <button class="btn btn-default" (click)="goBack()"> <span class="glyphicon glyphicon-arrow-left"></span> Back </button> <button *ngIf="!isAuthenticated" class="btn btn-success" [routerLink]="['/login']" queryParamsHandling="merge"> Login </button>
import { Component, OnInit } from "@angular/core";
import { Location } from "@angular/common";
import { AuthService } from "../../core/services/auth.service";
@Component({
selector: "app-access-denied",
templateUrl: "./access-denied.component.html",
styleUrls: ["./access-denied.component.css"]
})
export class AccessDeniedComponent implements OnInit {
isAuthenticated = false;
constructor(
private location: Location,
private authService: AuthService
) {
}
ngOnInit() {
this.isAuthenticated = this.authService.isLoggedIn();
}
goBack() {
this.location.back(); // <-- go back to previous location on cancel
}
}
isAuthUserInRoles(requiredRoles: string[]): boolean {
const user = this.getAuthUser();
if (!user || !user.roles) {
return false;
}
return requiredRoles.some(requiredRole => user.roles.indexOf(requiredRole.toLowerCase()) >= 0);
}
isAuthUserInRole(requiredRole: string): boolean {
return this.isAuthUserInRoles([requiredRole]);
} import { Injectable } from "@angular/core";
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from "@angular/router";
import { AuthService } from "./auth.service";
import { AuthGuardPermission } from "../models/auth-guard-permission";
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
if (!this.authService.isLoggedIn()) {
this.showAccessDenied(state);
return false;
}
const permissionData = route.data["permission"] as AuthGuardPermission;
if (!permissionData) {
return true;
}
if (Array.isArray(permissionData.deniedRoles) && Array.isArray(permissionData.permittedRoles)) {
throw new Error("Don't set both 'deniedRoles' and 'permittedRoles' in route data.");
}
if (Array.isArray(permissionData.permittedRoles)) {
const isInRole = this.authService.isAuthUserInRoles(permissionData.permittedRoles);
if (isInRole) {
return true;
}
this.showAccessDenied(state);
return false;
}
if (Array.isArray(permissionData.deniedRoles)) {
const isInRole = this.authService.isAuthUserInRoles(permissionData.deniedRoles);
if (!isInRole) {
return true;
}
this.showAccessDenied(state);
return false;
}
}
private showAccessDenied(state: RouterStateSnapshot) {
this.router.navigate(["/accessDenied"], { queryParams: { returnUrl: state.url } });
}
} this.returnUrl = this.route.snapshot.queryParams["returnUrl"];
if (this.returnUrl) {
this.router.navigate([this.returnUrl]);
} else {
this.router.navigate(["/protectedPage"]);
} import { AuthGuard } from "./services/auth.guard";
@NgModule({
providers: [
AuthGuard
]
})
export class CoreModule {} import { ProtectedPageComponent } from "./protected-page/protected-page.component";
import { AuthGuardPermission } from "../core/models/auth-guard-permission";
import { AuthGuard } from "../core/services/auth.guard";
const routes: Routes = [
{
path: "protectedPage",
component: ProtectedPageComponent,
data: {
permission: {
permittedRoles: ["Admin"],
deniedRoles: null
} as AuthGuardPermission
},
canActivate: [AuthGuard]
}
];
data: {
permission: {
permittedRoles: ["Admin", "User"]
} as AuthGuardPermission
},
canActivate: [AuthGuard] core.js:1427 ERROR Error: Uncaught (in promise): Error: StaticInjectorError[Location]:
StaticInjectorError[Location]:
NullInjectorError: No provider for Location!
Error: StaticInjectorError[Location]:
StaticInjectorError[Location]:
NullInjectorError: No provider for Location! import { Location } from "@angular/common"; "http://schemas.microsoft.com/ws/2008/06/identity/claims/role": [
"Admin",
"User"
], "http://schemas.microsoft.com/ws/2008/06/identity/claims/role": "User" ,
const decodedToken = this.getDecodedAccessToken();
let roles = decodedToken["http://schemas.microsoft.com/ws/2008/06/identity/claims/role"];
if (roles) {
roles = roles.map(role => role.toLowerCase()); //error
} const decodedToken = this.getDecodedAccessToken();
let roles = decodedToken["http://schemas.microsoft.com/ws/2008/06/identity/claims/role"];
if (roles){
if (Array.isArray(roles)) {
roles = roles.map(role => role.toLowerCase());
}
else {
roles = roles.toLowerCase();
}
}