NestJS nest-keycloak-connect 401 未经授权

时间:2021-07-14 13:18:39

标签: nestjs keycloak

在尝试使用 nest-keycloak-connect 模块时,我正在努力获得除 401 以外的任何未经授权的信息。

这是我的代码。

main.ts

...
import { APP_GUARD } from '@nestjs/core'
import {
  KeycloakConnectModule,
  ResourceGuard,
  RoleGuard,
  AuthGuard
} from 'nest-keycloak-connect';

@Module({
  imports: [TypeOrmModule.forRoot(config), 
    ...
    KeycloakConnectModule.register({
      authServerUrl: 'https://example.com:10443/auth',
      realm: 'sandpit',
      clientId: 'bn_project_manager',
      secret: '314055b4-882a-4c96-87fa-44e9fdea0f5d',
      // optional if you want to retrieve JWT from cookie
      // cookieKey: 'KEYCLOAK_JWT', 
      // optional loglevels. default is verbose
      logLevels: ['verbose'],
      // optional useNestLogger, uses the logger from app.useLogger() implementation
      useNestLogger: false
    }),
  ],
  controllers: [AppController],
  providers: [
    AppService,
    {
      provide: APP_GUARD,
      useClass: AuthGuard,
    },
    {
      provide: APP_GUARD,
      useClass: ResourceGuard,
    },
    {
      provide: APP_GUARD,
      useClass: RoleGuard,
    }
  ],
})
export class AppModule {}

bn.controller.ts

@Controller('bn')
@ApiTags('Business Needs')
@UsePipes(new ValidationPipe())
@Resource('bn_project_manager')
export class BnController {
  constructor(private readonly bnService: BnService) {}

  @Post()
  @Roles({roles: [ 'bn_manage'] })
  @ApiOkResponse({type: Bn})
  create(@Body() createEstimateLineDto: CreateBnDto) {
    return this.bnService.create(createEstimateLineDto);
  }

  @Get()
  @Roles({roles: ['read'] })
  @ApiOkResponse({type: [Bn]})
  findAll() {
    return this.bnService.findAll();
  }
}

我在 keycloak 中为我的客户端设置了两个角色,并分配给了我用于测试的用户。

这是我向 API 端点发出的请求。

curl --location --request POST 'http://localhost:3000/bn' \
--header 'Authorization: Bearer xxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
  "bn": "BN1234",
  "projectName": "string"
}'

我不想分享 JWT 令牌,但这里有相关内容

"realm_access": {
    "roles": [
      "offline_access",
      "uma_authorization"
    ]
  },
  "resource_access": {
    "bn_project_manager": {
      "roles": [
        "bn_manage"
      ]
    },
    "account": {
      "roles": [
        "manage-account",
        "manage-account-links",
        "view-profile"
      ]
    }

这是我从 Postman 中的 API 得到的响应。

{
    "statusCode": 401,
    "message": "Unauthorized"
}

这是我在 nestjs 应用程序控制台中获得的详细日志记录。

[Nest] 23972  - 14/07/2021, 14:00:26 VERBOSE [Keycloak] User JWT: xxxxxxxxxxxxxxxxxxxxxxxx
[Nest] 23972  - 14/07/2021, 14:00:26 VERBOSE [Keycloak] undefined
[Nest] 23972  - 14/07/2021, 14:00:26 VERBOSE [Keycloak] Using token validation method: ONLINE
[Nest] 23972  - 14/07/2021, 14:00:26 VERBOSE [Keycloak] undefined

有没有我需要做的事情没有记录在 https://www.npmjs.com/package/nest-keycloak-connnect 的 npm README

1 个答案:

答案 0 :(得分:0)

我解决了这个问题。我的 Keycloak 客户端已将 Access Type 设置为公开。我在我的配置中提供了一个秘密,因为 TypeScript 不会接受没有 secret 键的对象。我以为这样没问题,但事实证明,您必须使用 Access Type = Confidential 配置 Keycloak 客户端才能使该模块正常工作。