fix(auth): support pkce when using basic auth header (#7038)
* support pkce when using basic auth header * test(auth): useBasicAuthenticationWithAccessCodeGrant + usePkceWithAuthorizationCodeGrant
This commit is contained in:
@@ -152,7 +152,7 @@ export const authorizeAccessCodeWithFormParams = ( { auth, redirectUrl } ) => (
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const authorizeAccessCodeWithBasicAuthentication = ( { auth, redirectUrl } ) => ( { authActions } ) => {
|
export const authorizeAccessCodeWithBasicAuthentication = ( { auth, redirectUrl } ) => ( { authActions } ) => {
|
||||||
let { schema, name, clientId, clientSecret } = auth
|
let { schema, name, clientId, clientSecret, codeVerifier } = auth
|
||||||
let headers = {
|
let headers = {
|
||||||
Authorization: "Basic " + btoa(clientId + ":" + clientSecret)
|
Authorization: "Basic " + btoa(clientId + ":" + clientSecret)
|
||||||
}
|
}
|
||||||
@@ -160,7 +160,8 @@ export const authorizeAccessCodeWithBasicAuthentication = ( { auth, redirectUrl
|
|||||||
grant_type: "authorization_code",
|
grant_type: "authorization_code",
|
||||||
code: auth.code,
|
code: auth.code,
|
||||||
client_id: clientId,
|
client_id: clientId,
|
||||||
redirect_uri: redirectUrl
|
redirect_uri: redirectUrl,
|
||||||
|
code_verifier: codeVerifier
|
||||||
}
|
}
|
||||||
|
|
||||||
return authActions.authorizeRequest({body: buildFormData(form), name, url: schema.get("tokenUrl"), auth, headers})
|
return authActions.authorizeRequest({body: buildFormData(form), name, url: schema.get("tokenUrl"), auth, headers})
|
||||||
|
|||||||
@@ -112,6 +112,40 @@ describe("oauth2", () => {
|
|||||||
createCodeChallengeSpy.mockReset()
|
createCodeChallengeSpy.mockReset()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
it("should send code_challenge when using accessCode flow with usePkceWithAuthorizationCodeGrant enabled", () => {
|
||||||
|
const windowOpenSpy = jest.spyOn(win, "open")
|
||||||
|
mockSchema.flow = "accessCode"
|
||||||
|
|
||||||
|
const expectedCodeVerifier = "mock_code_verifier"
|
||||||
|
const expectedCodeChallenge = "mock_code_challenge"
|
||||||
|
|
||||||
|
const generateCodeVerifierSpy = jest.spyOn(utils, "generateCodeVerifier").mockImplementation(() => expectedCodeVerifier)
|
||||||
|
const createCodeChallengeSpy = jest.spyOn(utils, "createCodeChallenge").mockImplementation(() => expectedCodeChallenge)
|
||||||
|
|
||||||
|
authConfig.authConfigs.useBasicAuthenticationWithAccessCodeGrant = true
|
||||||
|
authConfig.authConfigs.usePkceWithAuthorizationCodeGrant = true
|
||||||
|
|
||||||
|
oauth2Authorize(authConfig)
|
||||||
|
expect(win.open.mock.calls.length).toEqual(1)
|
||||||
|
|
||||||
|
const actualUrl = new URLSearchParams(win.open.mock.calls[0][0])
|
||||||
|
expect(actualUrl.get("code_challenge")).toBe(expectedCodeChallenge)
|
||||||
|
expect(actualUrl.get("code_challenge_method")).toBe("S256")
|
||||||
|
|
||||||
|
expect(createCodeChallengeSpy.mock.calls.length).toEqual(1)
|
||||||
|
expect(createCodeChallengeSpy.mock.calls[0][0]).toBe(expectedCodeVerifier)
|
||||||
|
|
||||||
|
// The code_verifier should be stored to be able to send in
|
||||||
|
// on the TokenUrl call
|
||||||
|
expect(authConfig.auth.codeVerifier).toBe(expectedCodeVerifier)
|
||||||
|
|
||||||
|
// Restore spies
|
||||||
|
windowOpenSpy.mockReset()
|
||||||
|
generateCodeVerifierSpy.mockReset()
|
||||||
|
createCodeChallengeSpy.mockReset()
|
||||||
|
})
|
||||||
|
|
||||||
it("should send code_challenge when using authorization_code flow with usePkceWithAuthorizationCodeGrant enabled", () => {
|
it("should send code_challenge when using authorization_code flow with usePkceWithAuthorizationCodeGrant enabled", () => {
|
||||||
const windowOpenSpy = jest.spyOn(win, "open")
|
const windowOpenSpy = jest.spyOn(win, "open")
|
||||||
mockSchema.flow = "authorization_code"
|
mockSchema.flow = "authorization_code"
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
logoutWithPersistOption,
|
logoutWithPersistOption,
|
||||||
persistAuthorizationIfNeeded
|
persistAuthorizationIfNeeded
|
||||||
} from "corePlugins/auth/actions"
|
} from "corePlugins/auth/actions"
|
||||||
|
import { authorizeAccessCodeWithBasicAuthentication } from "../../../../../src/core/plugins/auth/actions"
|
||||||
|
|
||||||
describe("auth plugin - actions", () => {
|
describe("auth plugin - actions", () => {
|
||||||
|
|
||||||
@@ -178,26 +179,31 @@ describe("auth plugin - actions", () => {
|
|||||||
|
|
||||||
describe("tokenRequest", function () {
|
describe("tokenRequest", function () {
|
||||||
it("should send the code verifier when set", () => {
|
it("should send the code verifier when set", () => {
|
||||||
const data = {
|
const testCodeVerifierForAuthorizationCodeFlows = (flowAction) => {
|
||||||
auth: {
|
const data = {
|
||||||
schema: {
|
auth: {
|
||||||
get: () => "http://tokenUrl"
|
schema: {
|
||||||
|
get: () => "http://tokenUrl",
|
||||||
|
},
|
||||||
|
codeVerifier: "mock_code_verifier",
|
||||||
},
|
},
|
||||||
codeVerifier: "mock_code_verifier"
|
redirectUrl: "http://google.com",
|
||||||
},
|
}
|
||||||
redirectUrl: "http://google.com"
|
|
||||||
|
const authActions = {
|
||||||
|
authorizeRequest: jest.fn(),
|
||||||
|
}
|
||||||
|
|
||||||
|
flowAction(data)({ authActions })
|
||||||
|
|
||||||
|
expect(authActions.authorizeRequest.mock.calls.length).toEqual(1)
|
||||||
|
const actualArgument = authActions.authorizeRequest.mock.calls[0][0]
|
||||||
|
expect(actualArgument.body).toContain("code_verifier=" + data.auth.codeVerifier)
|
||||||
|
expect(actualArgument.body).toContain("grant_type=authorization_code")
|
||||||
}
|
}
|
||||||
|
|
||||||
const authActions = {
|
testCodeVerifierForAuthorizationCodeFlows(authorizeAccessCodeWithFormParams)
|
||||||
authorizeRequest: jest.fn()
|
testCodeVerifierForAuthorizationCodeFlows(authorizeAccessCodeWithBasicAuthentication)
|
||||||
}
|
|
||||||
|
|
||||||
authorizeAccessCodeWithFormParams(data)({ authActions })
|
|
||||||
|
|
||||||
expect(authActions.authorizeRequest.mock.calls.length).toEqual(1)
|
|
||||||
const actualArgument = authActions.authorizeRequest.mock.calls[0][0]
|
|
||||||
expect(actualArgument.body).toContain("code_verifier=" + data.auth.codeVerifier)
|
|
||||||
expect(actualArgument.body).toContain("grant_type=authorization_code")
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user