我正在尝试使用 Okta 作为身份提供者和 passport-saml 库在我的 Nest.js 应用程序中创建 SSO。我阅读了 Nest authentication 和 passport-saml 的文档。我对示例的理解没有问题,但是我确实需要使用具有不同配置的 SAML 策略,这取决于 POST 的请求正文值api/auth/saml
。换句话说,我有一个策略,但我的自定义LoginSSOStrategy 类具有不同的入口点、颁发者、证书参数,该类扩展了 Nest.js 的PassportStrategy 类。任何想法我该如何处理?
2 回答
我不太确定这是否是一个好方法,但是如果您愿意,您可以将类请求限定为范围并通过构造函数注入请求,然后可以访问请求对象并能够使用的新实例您的护照策略每个请求。您可以使用请求传递req.whatever
给super()
类的构造函数。
@Injectable({ scope: Scope.REQUEST })
export class LoginSSOStrategy exends PassportStrategy(Strategy) {
constructor(@Inject(REQUEST) request: Request, ...) {
super({/* options matching to request.field */});
}
validate(/* validate params*/) {
/* validate functionality */
}
}
这似乎是您需要进行大量测试并确保它适用于并发请求的事情,但总的来说它至少在理论上是可行的。
我认为这个问题类似于这个GitHub 问题。由于 Passport.js 的全局特性以及 Nest 无法确定哪些路由使用 Passport 护照策略这一事实,因此无法使用@Injectable({ scope: Scope.REQUEST })
.
最近,我不得不根据来自传入请求的一些数据使用动态重定向 URL 实现 Azure Active Directory 登录。根据您使用的策略,您可以在调用authenticate
Passport 策略的方法时使用(未记录的)extraAuthReqQueryParams
属性覆盖某些选项。了解您是否能够覆盖某些选项的一种方法是检查文档,如果您感到幸运,您可以查看您正在使用的 Passport 策略的源代码。在阅读了未记录的功能并在 Azure AD Passport 策略的源代码中看到了这些行(特别是 #1355 和 #1374 行)后,我能够redirectUrl
通过使用更改我之前在属性中指定的值redirect_uri
属性(注意这里的细微差别)。
@Injectable()
export class AzureOIDCStrategy extends PassportStrategy(OIDCStrategy,'AzureOIDC') {
constructor() {
super({
// Even though it is overwritten in the 'authenticate' method the Passport Strategy expects this to be set to a valid URL.
redirectUrl: `https://your-backend-domain.com/auth/azure/callback`,
// This ensures we have access to the request in the `authenticate` method
passReqToCallback: true,
});
}
authenticate(req: Request, options: Record<string, any>): void {
return super.authenticate(req, {
// `options` may contain more options for the `authenticate` method in Passport.
...options,
extraAuthReqQueryParams: {
// This overwrites the `redirectUrl` specified in the constructor
redirect_uri: `https://${req.headers.host}/auth/callback`,
},
});
}
}
我希望您能够应用此“策略”来更新entryPoint
,issuer
和cert
params。
在 Express 应用程序中,您可以执行以下操作:
app.get('/login',
(req, res, next) =>
passport.authenticate('azure-ad', {
extraAuthReqQueryParams: {
redirect_uri: `https://${req.headers.host}/auth/callback`,
},
})(req, res, next)
);