skip authorization header for server-side auth (#17306)
The backend is responsible for appending a bearer token in these cases. Signed-off-by: Jamie Klassen <jklassen@vmware.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-kubernetes': patch
|
||||
---
|
||||
|
||||
fixes a bug where an empty authorization header was provided to the proxy endpoint when a cluster had a server-side auth provider
|
||||
@@ -291,7 +291,7 @@ export class KubernetesAuthProviders implements KubernetesAuthProvidersApi {
|
||||
): Promise<KubernetesRequestBody>;
|
||||
// (undocumented)
|
||||
getCredentials(authProvider: string): Promise<{
|
||||
token: string;
|
||||
token?: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
@@ -306,7 +306,7 @@ export interface KubernetesAuthProvidersApi {
|
||||
): Promise<KubernetesRequestBody>;
|
||||
// (undocumented)
|
||||
getCredentials(authProvider: string): Promise<{
|
||||
token: string;
|
||||
token?: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
@@ -440,9 +440,7 @@ export class ServerSideKubernetesAuthProvider
|
||||
requestBody: KubernetesRequestBody,
|
||||
): Promise<KubernetesRequestBody>;
|
||||
// (undocumented)
|
||||
getCredentials(): Promise<{
|
||||
token: string;
|
||||
}>;
|
||||
getCredentials(): Promise<{}>;
|
||||
}
|
||||
|
||||
// Warning: (ae-forgotten-export) The symbol "ServicesAccordionsProps" needs to be exported by the entry point index.d.ts
|
||||
|
||||
@@ -395,10 +395,10 @@ describe('KubernetesBackendClient', () => {
|
||||
),
|
||||
),
|
||||
);
|
||||
identityApi.getCredentials.mockResolvedValue({ token: 'idToken' });
|
||||
});
|
||||
|
||||
it('hits the /proxy API', async () => {
|
||||
identityApi.getCredentials.mockResolvedValue({ token: 'idToken' });
|
||||
kubernetesAuthProvidersApi.getCredentials.mockResolvedValue({
|
||||
token: 'k8-token',
|
||||
});
|
||||
@@ -468,7 +468,6 @@ describe('KubernetesBackendClient', () => {
|
||||
});
|
||||
|
||||
it('/proxy API throws a 404 error', async () => {
|
||||
identityApi.getCredentials.mockResolvedValue({ token: 'idToken' });
|
||||
kubernetesAuthProvidersApi.getCredentials.mockResolvedValue({
|
||||
token: 'k8-token',
|
||||
});
|
||||
@@ -490,8 +489,6 @@ describe('KubernetesBackendClient', () => {
|
||||
});
|
||||
|
||||
it('throws a ERROR_NOT_FOUND if the cluster in the request is not found', async () => {
|
||||
identityApi.getCredentials.mockResolvedValue({ token: 'idToken' });
|
||||
|
||||
const request = {
|
||||
clusterName: 'cluster-b',
|
||||
path: '/api/v1/namespaces',
|
||||
@@ -501,8 +498,6 @@ describe('KubernetesBackendClient', () => {
|
||||
});
|
||||
|
||||
it('responds with an 403 error when invalid k8 token is provided', async () => {
|
||||
// when a user is signed in as a guest the result of the getCredentials() method resolves to the {} value.
|
||||
identityApi.getCredentials.mockResolvedValue({});
|
||||
kubernetesAuthProvidersApi.getCredentials.mockResolvedValue({
|
||||
token: 'wrong-token',
|
||||
});
|
||||
@@ -535,5 +530,34 @@ describe('KubernetesBackendClient', () => {
|
||||
const response = await backendClient.proxy(request);
|
||||
expect(response.status).toEqual(403);
|
||||
});
|
||||
|
||||
it('skips authorization header when auth provider returns no creds', async () => {
|
||||
const nsResponse = {
|
||||
kind: 'Namespace',
|
||||
apiVersion: 'v1',
|
||||
metadata: {
|
||||
name: 'new-ns',
|
||||
},
|
||||
};
|
||||
worker.use(
|
||||
rest.get(
|
||||
'http://localhost:1234/api/kubernetes/proxy/api/v1/namespaces/new-ns',
|
||||
(req, res, ctx) =>
|
||||
res(
|
||||
req.headers.get('Backstage-Kubernetes-Authorization')
|
||||
? ctx.status(403)
|
||||
: ctx.json(nsResponse),
|
||||
),
|
||||
),
|
||||
);
|
||||
kubernetesAuthProvidersApi.getCredentials.mockResolvedValue({});
|
||||
|
||||
const response = await backendClient.proxy({
|
||||
clusterName: 'cluster-a',
|
||||
path: '/api/v1/namespaces/new-ns',
|
||||
});
|
||||
|
||||
await expect(response.json()).resolves.toStrictEqual(nsResponse);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -89,7 +89,7 @@ export class KubernetesBackendClient implements KubernetesApi {
|
||||
|
||||
private async getCredentials(
|
||||
authProvider: string,
|
||||
): Promise<{ token: string }> {
|
||||
): Promise<{ token?: string }> {
|
||||
return await this.kubernetesAuthProvidersApi.getCredentials(authProvider);
|
||||
}
|
||||
|
||||
@@ -148,7 +148,9 @@ export class KubernetesBackendClient implements KubernetesApi {
|
||||
const headers = {
|
||||
...options.init?.headers,
|
||||
[`Backstage-Kubernetes-Cluster`]: options.clusterName,
|
||||
[`Backstage-Kubernetes-Authorization`]: `Bearer ${k8sToken}`,
|
||||
...(k8sToken && {
|
||||
[`Backstage-Kubernetes-Authorization`]: `Bearer ${k8sToken}`,
|
||||
}),
|
||||
...(identityResponse.token && {
|
||||
Authorization: `Bearer ${identityResponse.token}`,
|
||||
}),
|
||||
|
||||
@@ -92,7 +92,7 @@ export class KubernetesAuthProviders implements KubernetesAuthProvidersApi {
|
||||
);
|
||||
}
|
||||
|
||||
async getCredentials(authProvider: string): Promise<{ token: string }> {
|
||||
async getCredentials(authProvider: string): Promise<{ token?: string }> {
|
||||
const kubernetesAuthProvider: KubernetesAuthProvider | undefined =
|
||||
this.kubernetesAuthProviderMap.get(authProvider);
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ export class ServerSideKubernetesAuthProvider
|
||||
return requestBody;
|
||||
}
|
||||
|
||||
async getCredentials(): Promise<{ token: string }> {
|
||||
return { token: '' };
|
||||
async getCredentials(): Promise<{}> {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ export interface KubernetesAuthProvider {
|
||||
decorateRequestBodyForAuth(
|
||||
requestBody: KubernetesRequestBody,
|
||||
): Promise<KubernetesRequestBody>;
|
||||
getCredentials(): Promise<{ token: string }>;
|
||||
getCredentials(): Promise<{ token?: string }>;
|
||||
}
|
||||
|
||||
export const kubernetesAuthProvidersApiRef =
|
||||
@@ -34,5 +34,5 @@ export interface KubernetesAuthProvidersApi {
|
||||
authProvider: string,
|
||||
requestBody: KubernetesRequestBody,
|
||||
): Promise<KubernetesRequestBody>;
|
||||
getCredentials(authProvider: string): Promise<{ token: string }>;
|
||||
getCredentials(authProvider: string): Promise<{ token?: string }>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user