我在 NestJS 中偶然发现了 azure AD 身份验证和授权,问题是我正在使用具有 PKCE 配置的公共客户端应用程序,但应用程序不断要求
client_assertion
或 client_secret
这是我的代码
PublicAuthService.ts
import { Injectable, Logger } from '@nestjs/common';
import { PublicClientApplication, AuthenticationResult } from '@azure/msal-node';
import * as crypto from 'crypto';
@Injectable()
export class PublicAuthService {
public pca: PublicClientApplication;
private readonly logger = new Logger(PublicAuthService.name);
private codeVerifier: string; // Temporarily store the code verifier
constructor() {
this.pca = new PublicClientApplication({
auth: {
clientId: process.env.CLIENT_ID,
authority: `https://login.microsoftonline.com/${process.env.TENANT_ID}`,
},
});
}
// Helper function to generate a code verifier
private generateCodeVerifier(): string {
return crypto.randomBytes(32).toString('base64url');
}
// Helper function to generate a code challenge
private generateCodeChallenge(verifier: string): string {
return crypto.createHash('sha256').update(verifier).digest('base64url');
}
async getAuthUrl(): Promise<string> {
this.codeVerifier = this.generateCodeVerifier(); // Store the code verifier
const codeChallenge = this.generateCodeChallenge(this.codeVerifier);
return this.pca.getAuthCodeUrl({
scopes: ['User.Read'],
redirectUri: process.env.REDIRECT_URI,
codeChallenge: codeChallenge,
codeChallengeMethod: 'S256',
});
}
async acquireTokenByCode(code: string): Promise<AuthenticationResult> {
return this.pca.acquireTokenByCode({
code,
scopes: ['User.Read'],
redirectUri: process.env.REDIRECT_URI,
codeVerifier: this.codeVerifier, // Use the stored code verifier
});
}
}
PublicAuthController.ts
import { Controller, Get, Query, Res, HttpStatus } from '@nestjs/common';
import { PublicAuthService } from './public_auth.service';
@Controller('public-auth')
export class PublicAuthController {
constructor(private readonly publicAuthService: PublicAuthService) {}
@Get('login')
async login(@Res() res) {
const authUrl = await this.publicAuthService.pca.getAuthCodeUrl({
scopes: ['User.Read'],
redirectUri: process.env.REDIRECT_URI,
});
res.redirect(authUrl);
}
@Get('redirect')
async handleRedirect(@Query('code') code: string, @Res() res) {
try {
const result = await this.publicAuthService.acquireTokenByCode(code);
res.status(HttpStatus.OK).json({
accessToken: result.accessToken,
user: result.account,
});
} catch (error) {
res.status(HttpStatus.UNAUTHORIZED).json({ message: error.message });
}
}
}
当我打开http://localhost:3000/api/v1/public-auth/login时,应用程序成功打开Azure AD登录页面并提示用户输入用户名和密码,但在身份验证过程之后它返回:
{"message":"invalid_client: Error(s): 7000218 - Timestamp: 2024-10-21 02:49:19Z - Description: AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'. Trace ID: e76ee3c8-d591-43f5-b939-1a5188441000 Correlation ID: 3711a68c-a1c7-4ddf-a524-0fbd0d68feb2 Timestamp: 2024-10-21 02:49:19Z - Correlation ID: 3711a68c-a1c7-4ddf-a524-0fbd0d68feb2 - Trace ID: e76ee3c8-d591-43f5-b939-1a5188441000"}
据我所知,client_assertion和client_secret仅在机密客户端应用程序中使用,对此有何指导?