0

我们的应用程序使用 COGNITO 用户池来启用 oauth2 的 SSO;登录成功后,COGNITO 生成令牌并返回;aAPI 将使用该令牌进行后续调用;我们的 API 受到 NESTJS AuthGuards 的保护;

问题是当我们通过在“授权”标头中传递任何垃圾来测试 API 时,例如“承载 xyz”,它可以工作并且不会抛出任何错误。

oauth2 代码,它与 COGNITO 对话以生成令牌;

 enter code here

    export class OAuth2Strategy extends PassportStrategy(Strategy, 'oauth2') { 
  constructor() {
    const serverURL = config.get('authDetails.SERVER_URL');
    let appRootURL:any = process.env.NODE_ENV === 'localhost' ? 'http://localhost:' + config.get('app.port') : config.get('app.rootUrl');
    if (!appRootURL.endsWith('/')) {
      appRootURL += '/';
    }  
    const appBaseURL = `${appRootURL}${config.get('globalPrefix')}`;
    const loginCallbackURL = `${appBaseURL}/auth/login/callback`;
    super({
      authorizationURL: `${serverURL}oauth2/authorize`,
      tokenURL: `${serverURL}oauth2/token`,
      clientID: config.get('CLIENT_ID'),
      //clientSecret: config.get('CLIENT_SECRET'),
      callbackURL: loginCallbackURL,
      scope: ['openid', 'profile'],
      state: (100000000000).toString(36)
    }, function(accessToken: string, refreshToken: string, params: any, profile: any, done: VerifyCallback) {
      done(null, {
        accessToken: accessToken
      });
    });
  }

NEST JS BearerStrategy 代码

export class BearerStrategy extends PassportStrategy(Strategy, 'bearer') {
    async validate(accessToken: string, done: VerifyCallback) {
      
      const user = {
            accessToken
        }
        done(null, user);
    }
        
    }

export class BearerStrategy extends PassportStrategy(Strategy, 'bearer') {
async validate(accessToken: string, done: VerifyCallback) {
  
  const user = {
        accessToken
    }
    done(null, user);
}
    
}

JWT 策略类

export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
      console.log(config.get('CLIENT_SECRET'))
      console.log(JSON.stringify(ExtractJwt.fromAuthHeaderAsBearerToken()))
    super({
      secretOrKey:  
      passportJwtSecret({
        cache: true,
        rateLimit: true,
        jwksRequestsPerMinute: 5,
        jwksUri: 'https://cognito-idp.us-east-1.amazonaws.com/us-east-XXXX/.well-known/jwks.json',
        
      }), 
      
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      //jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('JWT'),
     // ignoreExpiration: false,  
     // secretOrKey: config.get('CLIENT_SECRET'),
      algorithms:["RS256"],
      issuer : "https://cognito-idp.us-east-1.amazonaws.com/us-east-XXXX",
      audience: "client_id1234"
      
    });
  }
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
      console.log(config.get('CLIENT_SECRET'))
      console.log(JSON.stringify(ExtractJwt.fromAuthHeaderAsBearerToken()))
    super({
      secretOrKey:  
      passportJwtSecret({
        cache: true,
        rateLimit: true,
        jwksRequestsPerMinute: 5,
        jwksUri: 'https://cognito-idp.us-east-1.amazonaws.com/us-east-XXXX/.well-known/jwks.json',
        
      }), 
    
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      //jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('JWT'),
     // ignoreExpiration: false,  
     // secretOrKey: config.get('CLIENT_SECRET'),
      algorithms:["RS256"],
      issuer : "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_XXXX",
      audience: "client_id12344"
      
    });
  }

现在我们正在使用身份验证卫士保护他们

  @ApiTags("Root")
  @Get("/lookup")
  @UseGuards(AuthGuard("bearer"))
  async get() {
  return "got the data.."
  }

@ApiTags("Root")
@Get("/test")
@UseGuards(AuthGuard("jwt"))
async getSample() {
 return "got the data.."
}

不确定为什么 Passport 验证不起作用验证从 Bearer 和 JWT 策略调用的方法。而 Bearer 没有给出错误 JWT 抛出“cb: is not a function” nt 完全理解并且在网络中也没有太多帮助。

4

1 回答 1

0

JwtStrategy应该有效。请用你的替换aws-regioncognito-user-pool-id

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { map } from 'rxjs/operators';
import find from 'lodash/find';
import jwkToPem from 'jwk-to-pem';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(private readonly httpService: HttpService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKeyProvider: (_, token, done) => {
        const jwksUri =
          'https://cognito-idp.<aws-region>.amazonaws.com/<cognito-user-pool-id>/.well-known/jwks.json';
        this.httpService
          .get(jwksUri)
          .pipe(
            map((response) => {
              const {
                data: { keys },
              } = response;
              const tokenSections = (token || '').split('.');
              if (tokenSections.length < 2) {
                throw Error('something went wrong');
              }
              const headerJSON = Buffer.from(
                tokenSections[0],
                'base64',
              ).toString('utf8');
              const header = JSON.parse(headerJSON);
              const jwk = find(keys, (key) => key.kid === header.kid);
              if (!jwk) {
                throw Error('something went wrong');
              }
              return jwkToPem(jwk);
            }),
          )
          .subscribe({
            next(pem) {
              done(null, pem);
            },
            error(err) {
              done(err.message, null);
            },
          });
      },
    });
  }

  async validate(payload: any) {
    return { userId: payload.sub, username: payload.username };
  }
}

于 2021-09-14T03:50:55.857 回答