Passport-Azure-Ad seems to run asynchronously

前端 未结 1 1446
甜味超标
甜味超标 2021-01-25 13:13

I am using TSED - TypeScript Express Decorators (https://tsed.io) and it replaces express code like:

   server.get(\'/api/tasks\', passport.authenticate(\'oauth-         


        
1条回答
  •  余生分开走
    2021-01-25 13:45

    This is a solution to work around what I believe is a problem with passport-azure-ad being async but with no way to control this. It is not the answer I'd like - to confirm what I've said or to deny what I've said and to provide a solution that works.

    The following is a solution for the https://tsed.io framework. In https://github.com/TypedProject/ts-express-decorators/issues/559 they suggest not using @OverrideMiddleware(AuthenticatedMiddleware) but to use a @UseAuth middleware. It works so for illustration purposes that is not important here (I will work through the feedback shortly).

    @OverrideMiddleware(AuthenticatedMiddleware)
    export class UserAuthMiddleware implements IMiddleware {
        constructor(@Inject() private authService: AuthService) {
        }
    
        // NO THIS VERSION DOES NOT WORK.  I even removed checkForAuthentication() and
        // inlined the setInterval() but it made no difference
        // Before the 200 is sent WITH content, a 204 NO CONTENT is
    
        // HAD TO CHANGE to the setTimeout() version
        // async checkForAuthentication(request: express.Request): Promise {
        //     return new Promise(resolve => {
    
        //         let iterations = 30;
        //        const id = setInterval(() => {
        //             if (request.isAuthenticated() || iterations-- <= 0) {
        //                 clearInterval(id);
        //                 resolve();
        //             }
        //         }, 50);
        //     });
        // }
    
        // @async
        public use(
            @EndpointInfo() endpoint: EndpointMetadata,
            @Request() request: express.Request,
            @Response() response: express.Response,
            @Next() next: express.NextFunction
        ) {
            const options = endpoint.get(AuthenticatedMiddleware) || {};
            this.authService.authenticate(request, response, next);
    
            // AS DISCUSSED above this doesn't work
            // await this.checkForAuthentication(request);
            // TODO - check roles in options against AD scopes
            // if (!request.isAuthenticated()) {
            //     throw new Forbidden('Forbidden');
            // }
            // next();
    
            // HAD TO USE setTimeout()
            setTimeout(() => {
                if (!request.isAuthenticated()) {
                    console.log(`throw forbidden`);
                    throw new Forbidden('Forbidden');
                }
                next();
            }, 1500);
    }
    

    Edit - I had a version that used setInterval() but I found it didn't work. I even tried inlining the code in to the one method so I could remove the async. It seemed to cause the @Post the UserAuthMiddleware is attached to, to complete immediately and return a 204 "No Content". The sequence would complete after this and a 200 with the desired content would be returned but it was too late. I don't understand why.

    0 讨论(0)
提交回复
热议问题