0

我正在尝试在 NestJS 中设置响应标头,但不断收到以下错误:

跨域请求被阻止:同源策略不允许读取位于https://companyName.okta.com/app/companyName_imentorlocalhost_1/exk1hp5ht4vrEzqGg0h8/sso/saml?SAMLRequest=nVPLct..的远程资源。(原因:缺少 CORS 标头“Access-Control-Allow-Origin”)。

我尝试在控制器中设置标题,但这不起作用:

auth.controller

@UseGuards(SamlAuthGuard)
@Header('Access-Control-Allow-Origin', '*')
@Get('box-utility-service/auth/login')
login(@Request() req): any {}

@UseGuards(SamlAuthGuard)
@Header('Access-Control-Allow-Origin', '*')
@Post('imentor-service/login/callback')
oktaCallback (@Request() req, @Response() res: Response): any {
    return this.authService.login(req);
}

还尝试在拦截器中设置标题。也没有用:

header.interceptor.ts

@Injectable()
export class HeaderInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      tap(() => {
        const res = context.switchToHttp().getResponse();

        res.setHeader('Access-Control-Allow-Origin', '*');
      })
    )
  }
}

这是我的main.ts,我在其中启用了 CORS:

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  app.use(
    session({
      secret: 'my-secret',
      resave: false,
      saveUninitialized: false
    }),
  );

  app.enableCors({
    allowedHeaders: [ 'Accept', 'Accept-Version', 'Content-Type', 'Api-Version', 'Origin', 'X-Requested-With',
      'Authorization' ],
    origin: [ 'https://companyName.okta.com', 'http://localhost:4200', 'http://localhost' ],
    credentials: true,
    exposedHeaders: [ 'API-Token-Expiry' ]
  });

  app.useGlobalInterceptors(new HeaderInterceptor());

  await app.listen(3000);
}
bootstrap();

这是我的saml-strategy.ts文件,我将Passport策略定义为 SAML:

import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { AuthService } from './auth.service';
const nconf = require('nconf');
import { get } from 'lodash';
const SamlStrategy = require('passport-saml').Strategy;

import { UsersService } from '../users/users.service';

@Injectable()
export class Saml2Strategy extends PassportStrategy(SamlStrategy, 'saml') {
  users = [];

  constructor(
    private authService: AuthService,
    private usersService: UsersService
  ) {
    super({
      issuer: nconf.get('saml:issuer'),
      path: nconf.get('saml:path'),
      entryPoint: nconf.get('saml:entryPoint'),
      cert: nconf.get('saml:cert')
    });
  }

  async validate(payload: any) {
    const oeid = payload.nameID;
    let user;

    if (oeid) {
      try {
        let userADData = await this.authService.validateUser(oeid);
        userADData = get(userADData, 'data.data[0]');

        if (userADData) {
          user = await this.usersService.findOrCreate(userADData);
        }

        return user;
      } catch (err) {
        return err;
      }
    }
  }
}

知道发生了什么吗?谢谢。

4

1 回答 1

0

原来这是我处理 OKTA 登录工作流程的方式有问题。我正在重定向一个 XHR 请求(OKTA 不喜欢它,因为它缺少这样做所需的标头),并且收到了错误代码。

于 2021-07-09T17:04:12.060 回答