feat: do not ask for client secret when using auth code with PKCE (#7438)
Co-authored-by: Ignacio Lozano <nacholozano@gmail.com> Co-authored-by: Vladimir Gorej <vladimir.gorej@gmail.com> Refs #6290
This commit is contained in:
@@ -130,7 +130,11 @@ export default class Oauth2 extends React.Component {
|
|||||||
const AUTH_FLOW_ACCESS_CODE = isOAS3() ? (oidcUrl ? "authorization_code" : "authorizationCode") : "accessCode"
|
const AUTH_FLOW_ACCESS_CODE = isOAS3() ? (oidcUrl ? "authorization_code" : "authorizationCode") : "accessCode"
|
||||||
const AUTH_FLOW_APPLICATION = isOAS3() ? (oidcUrl ? "client_credentials" : "clientCredentials") : "application"
|
const AUTH_FLOW_APPLICATION = isOAS3() ? (oidcUrl ? "client_credentials" : "clientCredentials") : "application"
|
||||||
|
|
||||||
|
let authConfigs = authSelectors.getConfigs()
|
||||||
|
let isPkceCodeGrant = authConfigs.usePkceWithAuthorizationCodeGrant === "true" || authConfigs.usePkceWithAuthorizationCodeGrant === true
|
||||||
|
|
||||||
let flow = schema.get("flow")
|
let flow = schema.get("flow")
|
||||||
|
let flowToDisplay = flow === AUTH_FLOW_ACCESS_CODE && isPkceCodeGrant ? flow + " with PKCE" : flow
|
||||||
let scopes = schema.get("allowedScopes") || schema.get("scopes")
|
let scopes = schema.get("allowedScopes") || schema.get("scopes")
|
||||||
let authorizedAuth = authSelectors.authorized().get(name)
|
let authorizedAuth = authSelectors.authorized().get(name)
|
||||||
let isAuthorized = !!authorizedAuth
|
let isAuthorized = !!authorizedAuth
|
||||||
@@ -140,7 +144,7 @@ export default class Oauth2 extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h4>{name} (OAuth2, { schema.get("flow") }) <JumpToPath path={[ "securityDefinitions", name ]} /></h4>
|
<h4>{name} (OAuth2, { flowToDisplay }) <JumpToPath path={[ "securityDefinitions", name ]} /></h4>
|
||||||
{ !this.state.appName ? null : <h5>Application: { this.state.appName } </h5> }
|
{ !this.state.appName ? null : <h5>Application: { this.state.appName } </h5> }
|
||||||
{ description && <Markdown source={ schema.get("description") } /> }
|
{ description && <Markdown source={ schema.get("description") } /> }
|
||||||
|
|
||||||
@@ -149,7 +153,7 @@ export default class Oauth2 extends React.Component {
|
|||||||
{ oidcUrl && <p>OpenID Connect URL: <code>{ oidcUrl }</code></p> }
|
{ oidcUrl && <p>OpenID Connect URL: <code>{ oidcUrl }</code></p> }
|
||||||
{ ( flow === AUTH_FLOW_IMPLICIT || flow === AUTH_FLOW_ACCESS_CODE ) && <p>Authorization URL: <code>{ schema.get("authorizationUrl") }</code></p> }
|
{ ( flow === AUTH_FLOW_IMPLICIT || flow === AUTH_FLOW_ACCESS_CODE ) && <p>Authorization URL: <code>{ schema.get("authorizationUrl") }</code></p> }
|
||||||
{ ( flow === AUTH_FLOW_PASSWORD || flow === AUTH_FLOW_ACCESS_CODE || flow === AUTH_FLOW_APPLICATION ) && <p>Token URL:<code> { schema.get("tokenUrl") }</code></p> }
|
{ ( flow === AUTH_FLOW_PASSWORD || flow === AUTH_FLOW_ACCESS_CODE || flow === AUTH_FLOW_APPLICATION ) && <p>Token URL:<code> { schema.get("tokenUrl") }</code></p> }
|
||||||
<p className="flow">Flow: <code>{ schema.get("flow") }</code></p>
|
<p className="flow">Flow: <code>{ flowToDisplay }</code></p>
|
||||||
|
|
||||||
{
|
{
|
||||||
flow !== AUTH_FLOW_PASSWORD ? null
|
flow !== AUTH_FLOW_PASSWORD ? null
|
||||||
@@ -208,7 +212,7 @@ export default class Oauth2 extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
( (flow === AUTH_FLOW_APPLICATION || flow === AUTH_FLOW_ACCESS_CODE || flow === AUTH_FLOW_PASSWORD) && <Row>
|
( (flow === AUTH_FLOW_APPLICATION || flow === AUTH_FLOW_ACCESS_CODE || flow === AUTH_FLOW_PASSWORD) && !isPkceCodeGrant && <Row>
|
||||||
<label htmlFor="client_secret">client_secret:</label>
|
<label htmlFor="client_secret">client_secret:</label>
|
||||||
{
|
{
|
||||||
isAuthorized ? <code> ****** </code>
|
isAuthorized ? <code> ****** </code>
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
openapi: 3.0.0
|
||||||
|
|
||||||
|
info:
|
||||||
|
version: "1.0"
|
||||||
|
title: PKCE Flow
|
||||||
|
|
||||||
|
paths:
|
||||||
|
/:
|
||||||
|
get:
|
||||||
|
summary: dummy operation
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
|
||||||
|
components:
|
||||||
|
securitySchemes:
|
||||||
|
testAuthCodeFlow:
|
||||||
|
type: oauth2
|
||||||
|
flows:
|
||||||
|
authorizationCode:
|
||||||
|
authorizationUrl: /oauth/authorize
|
||||||
|
tokenUrl: /oauth/token
|
||||||
|
scopes:
|
||||||
|
read: read whatever you want
|
||||||
|
write: write whatever you want
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
describe("Check client_secret for OAuth2 Authorization Code flow with and without PKCE (#6290)", () => {
|
||||||
|
it("should not display client_secret field for authorization code flow with PKCE", () => {
|
||||||
|
cy.visit(
|
||||||
|
"/?url=/documents/features/auth-code-flow-pkce-without-secret.yaml"
|
||||||
|
)
|
||||||
|
.window()
|
||||||
|
.then(win => {
|
||||||
|
// set auth config to use PKCE
|
||||||
|
let authConfigs = win.ui.authSelectors.getConfigs()
|
||||||
|
win.ui.authActions.configureAuth({
|
||||||
|
...authConfigs,
|
||||||
|
usePkceWithAuthorizationCodeGrant: true,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.get("button.authorize")
|
||||||
|
.click()
|
||||||
|
.get("h4")
|
||||||
|
.contains("authorizationCode with PKCE")
|
||||||
|
.get(".flow")
|
||||||
|
.contains("authorizationCode with PKCE")
|
||||||
|
.get("#client_secret")
|
||||||
|
.should("not.exist")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should display client_secret field for authorization code flow without PKCE", () => {
|
||||||
|
cy.visit(
|
||||||
|
"/?url=/documents/features/auth-code-flow-pkce-without-secret.yaml"
|
||||||
|
)
|
||||||
|
.window()
|
||||||
|
.then(win => {
|
||||||
|
// set auth config to not use PKCE
|
||||||
|
let authConfigs = win.ui.authSelectors.getConfigs()
|
||||||
|
win.ui.authActions.configureAuth({
|
||||||
|
...authConfigs,
|
||||||
|
usePkceWithAuthorizationCodeGrant: false,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.get("button.authorize")
|
||||||
|
.click()
|
||||||
|
.get("h4")
|
||||||
|
.contains("authorizationCode")
|
||||||
|
.get(".flow")
|
||||||
|
.contains("authorizationCode")
|
||||||
|
.get("#client_secret")
|
||||||
|
.should("exist")
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user