reference_token 授予值:[object Object] 在商店中找不到
reference_token grant with value: [object Object] not found in store
我使用 NestJs 和 identityserver 的 oidc 护照策略如下。
import { UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy, Client, UserinfoResponse, TokenSet, Issuer } from 'openid-client';
import { AuthService } from './auth.service';
export const buildOpenIdClient = async () => {
const TrustIssuer = await Issuer.discover(`http://localhost:5001/.well-known/openid-configuration`);
const client = new TrustIssuer.Client({
client_id: 'mvc',
//client_secret: 'K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols=',
client_secret: 'secret',
redirect_uris: ['http://localhost:3100/api/callback'],
post_logout_redirect_uris: ['http://localhost:3100/signout-callback-oidc'],
token_endpoint_auth_method: 'client_secret_post',
});
return client;
};
export class OidcStrategy extends PassportStrategy(Strategy, 'oidc') {
client: Client;
constructor(private readonly authService: AuthService, client: Client) {
super({
client: client,
params: {
redirect_uri: 'http://localhost:3100/api/callback',
scope: 'openid profile api1',
},
passReqToCallback: true,
usePKCE: false,
});
this.client = client;
}
async validate(tokenset: TokenSet): Promise<any> {
const userinfo: UserinfoResponse = await this.client.userinfo(tokenset); // HERE IT THROWS ERROR
try {
const id_token = tokenset.id_token
const access_token = tokenset.access_token
const refresh_token = tokenset.refresh_token
const user = {
id_token,
access_token,
refresh_token,
userinfo,
}
return user;
} catch (err) {
throw new UnauthorizedException();
}
}
}
我的授权模块如下所示。
// src/auth/auth.module.ts
import { Module } from '@nestjs/common';
import { PassportModule } from '@nestjs/passport';
import { OidcStrategy, buildOpenIdClient } from './oidc.strategy';
import { SessionSerializer } from './session.serializer';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
const OidcStrategyFactory = {
provide: 'OidcStrategy',
useFactory: async (authService: AuthService) => {
const client = await buildOpenIdClient(); // secret sauce! build the dynamic client before injecting it into the strategy for use in the constructor super call.
const strategy = new OidcStrategy(authService, client);
return strategy;
},
inject: [AuthService]
};
@Module({
imports: [
PassportModule.register({ session: true, defaultStrategy: 'oidc' }),
],
controllers: [AuthController],
providers: [OidcStrategyFactory, SessionSerializer, AuthService],
})
export class AuthModule {}
因此它重定向到 identityserver 并且还使用令牌获取回调但是在 this.client.userinfo(tokenset)
上给出以下错误。
在 Identityserver 上,它记录了以下 2 个错误。
1) reference_token grant with value: [object Object] not found in store.
2) Invalid reference token.
{"ClientId": null, "ClientName": null, "ValidateLifetime": true, "AccessTokenType": "Reference", "ExpectedScope": "openid", "TokenHandle": "[object Object]", "JwtId": null, "Claims": null, "$type": "TokenValidationLog"}
在 NestJs 上它会记录以下内容。
OPError {error: 'invalid_token', message: 'invalid_token', name: 'OPError', stack: 'OPError: invalid_token
以下是我用作参考的文章。
https://sdoxsee.github.io/blog/2020/02/05/cats-nest-nestjs-mongo-oidc.html
以下是我的身份服务器客户端。
new Client
{
ClientId = "mvc",
ClientSecrets = { new Secret("secret") },
RequirePkce = false,
AccessTokenType = AccessTokenType.Reference,
RequireClientSecret = false,
AllowedGrantTypes = GrantTypes.Code,
// where to redirect to after login
RedirectUris = { "http://localhost:3100/api/callback" },
// where to redirect to after logout
PostLogoutRedirectUris = { "http://localhost:3100/signout-callback-oidc" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api1"
}
}
好的,我能够调试开源代码并发现我提到的那篇文章使用了不同的验证方法定义。
似乎验证方法的定义已更改。
所以我检索的 tokenset 作为第二个参数而不是第一个(在文章中它是第一个参数)。
所以不要关注。
async validate(tokenset: TokenSet): Promise<any> {
我不得不使用以下内容。
async validate(incomingMessage: IncomingMessage, tokenset: TokenSet): Promise<any> {
似乎 Typescript 在这种情况下没有帮助...
我使用 NestJs 和 identityserver 的 oidc 护照策略如下。
import { UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy, Client, UserinfoResponse, TokenSet, Issuer } from 'openid-client';
import { AuthService } from './auth.service';
export const buildOpenIdClient = async () => {
const TrustIssuer = await Issuer.discover(`http://localhost:5001/.well-known/openid-configuration`);
const client = new TrustIssuer.Client({
client_id: 'mvc',
//client_secret: 'K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols=',
client_secret: 'secret',
redirect_uris: ['http://localhost:3100/api/callback'],
post_logout_redirect_uris: ['http://localhost:3100/signout-callback-oidc'],
token_endpoint_auth_method: 'client_secret_post',
});
return client;
};
export class OidcStrategy extends PassportStrategy(Strategy, 'oidc') {
client: Client;
constructor(private readonly authService: AuthService, client: Client) {
super({
client: client,
params: {
redirect_uri: 'http://localhost:3100/api/callback',
scope: 'openid profile api1',
},
passReqToCallback: true,
usePKCE: false,
});
this.client = client;
}
async validate(tokenset: TokenSet): Promise<any> {
const userinfo: UserinfoResponse = await this.client.userinfo(tokenset); // HERE IT THROWS ERROR
try {
const id_token = tokenset.id_token
const access_token = tokenset.access_token
const refresh_token = tokenset.refresh_token
const user = {
id_token,
access_token,
refresh_token,
userinfo,
}
return user;
} catch (err) {
throw new UnauthorizedException();
}
}
}
我的授权模块如下所示。
// src/auth/auth.module.ts
import { Module } from '@nestjs/common';
import { PassportModule } from '@nestjs/passport';
import { OidcStrategy, buildOpenIdClient } from './oidc.strategy';
import { SessionSerializer } from './session.serializer';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
const OidcStrategyFactory = {
provide: 'OidcStrategy',
useFactory: async (authService: AuthService) => {
const client = await buildOpenIdClient(); // secret sauce! build the dynamic client before injecting it into the strategy for use in the constructor super call.
const strategy = new OidcStrategy(authService, client);
return strategy;
},
inject: [AuthService]
};
@Module({
imports: [
PassportModule.register({ session: true, defaultStrategy: 'oidc' }),
],
controllers: [AuthController],
providers: [OidcStrategyFactory, SessionSerializer, AuthService],
})
export class AuthModule {}
因此它重定向到 identityserver 并且还使用令牌获取回调但是在 this.client.userinfo(tokenset)
上给出以下错误。
在 Identityserver 上,它记录了以下 2 个错误。
1) reference_token grant with value: [object Object] not found in store.
2) Invalid reference token.
{"ClientId": null, "ClientName": null, "ValidateLifetime": true, "AccessTokenType": "Reference", "ExpectedScope": "openid", "TokenHandle": "[object Object]", "JwtId": null, "Claims": null, "$type": "TokenValidationLog"}
在 NestJs 上它会记录以下内容。
OPError {error: 'invalid_token', message: 'invalid_token', name: 'OPError', stack: 'OPError: invalid_token
以下是我用作参考的文章。 https://sdoxsee.github.io/blog/2020/02/05/cats-nest-nestjs-mongo-oidc.html
以下是我的身份服务器客户端。
new Client
{
ClientId = "mvc",
ClientSecrets = { new Secret("secret") },
RequirePkce = false,
AccessTokenType = AccessTokenType.Reference,
RequireClientSecret = false,
AllowedGrantTypes = GrantTypes.Code,
// where to redirect to after login
RedirectUris = { "http://localhost:3100/api/callback" },
// where to redirect to after logout
PostLogoutRedirectUris = { "http://localhost:3100/signout-callback-oidc" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api1"
}
}
好的,我能够调试开源代码并发现我提到的那篇文章使用了不同的验证方法定义。
似乎验证方法的定义已更改。
所以我检索的 tokenset 作为第二个参数而不是第一个(在文章中它是第一个参数)。
所以不要关注。
async validate(tokenset: TokenSet): Promise<any> {
我不得不使用以下内容。
async validate(incomingMessage: IncomingMessage, tokenset: TokenSet): Promise<any> {
似乎 Typescript 在这种情况下没有帮助...