我的應用程式有以下 Nestjs 全域防護:
import { ExecutionContext, Injectable } from "@nestjs/common";
import { Reflector } from "@nestjs/core";
import { AuthGuard } from "@nestjs/passport";
@Injectable()
export class LoginGuard extends AuthGuard(
["azure-ad"]
) {
public constructor(private readonly reflector: Reflector) {
super();
}
async canActivate(context: ExecutionContext) {
const isPublic = this.reflector.get<boolean>(
"isPublic",
context.getHandler()
);
if (isPublic) {
return true;
}
const result = (await super.canActivate(context)) as boolean;
const request = context.switchToHttp().getRequest();
await super.logIn(request);
return result;
}
}
以及以下身份驗證策略:
import {
BearerStrategy,
IBearerStrategyOption,
ITokenPayload,
VerifyCallback,
} from "passport-azure-ad"
import {
Inject,
Injectable,
OnModuleInit,
UnauthorizedException,
} from "@nestjs/common"
import passport = require("passport")
import env from "../../../config"
import { User } from "modules/users/users.interface"
import { UsersService } from "modules/users/users.service"
const tenantId = env.TENANT_ID
const clientID = env.CLIENT_ID || ""
const azureCredentials: IBearerStrategyOption = {
identityMetadata: `https://login.microsoftonline.com/${tenantId}/v2.0/.well-known/openid-configuration`,
clientID,
validateIssuer: true,
issuer: `https://login.microsoftonline.com/${tenantId}/v2.0`,
audience: clientID,
}
@Injectable()
export class AzureAdStrategy extends BearerStrategy implements OnModuleInit {
onModuleInit() {
passport.use("azure-ad", this)
}
constructor(@Inject(UsersService) private usersService: UsersService) {
super(
azureCredentials,
async (token: ITokenPayload, done: VerifyCallback) => {
if (Date.now() / 1000 > token.exp) {
return done(new UnauthorizedException("access token is expired"))
}
const tokenUsername = token?.preferred_username?.slice(0, 9)
const tokenAppId = !tokenUsername && token?.azp
if (!tokenUsername && !tokenAppId) {
return done(new UnauthorizedException("Missing User"))
}
let user: User
if (tokenUsername) {
try {
user = await this.usersService.getUser(tokenUsername)
if (!user) {
return done(new UnauthorizedException("User is not recognized"))
}
} catch (err) {
return done(err)
}
}
return done(null, user, token)
},
)
}
}
這很好用。我需要為我的應用程式設定后門邏輯,因此如果在請求中發送了某個標頭,它會繞過 azureAD 授權,可以說req.is_bypass
實作這一目標的最佳方法是什么?甚至有可能還是我需要為后門身份驗證使用不同的邏輯?
謝謝!
uj5u.com熱心網友回復:
在您LoginGuard的中,canActivate您可以訪問該ExecutionContext物件,該物件可用于獲取當前請求。檢查isPublic元資料后,您可以添加要執行的檢查
import { ExecutionContext, Injectable } from "@nestjs/common";
import { Reflector } from "@nestjs/core";
import { AuthGuard } from "@nestjs/passport";
@Injectable()
export class LoginGuard extends AuthGuard(
["azure-ad"]
) {
public constructor(private readonly reflector: Reflector) {
super();
}
async canActivate(context: ExecutionContext) {
const isPublic = this.reflector.get<boolean>(
"isPublic",
context.getHandler()
);
if (isPublic) {
return true;
}
const req = context.switchToHttp().getRequest()
if (req.is_bypass) {
return true;
}
const result = (await super.canActivate(context)) as boolean;
const request = context.switchToHttp().getRequest();
await super.logIn(request);
return result;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/532326.html
標籤:验证巢穴护照.js
