improvement: oauth "scopes" improvements (#6037)
* improvement: oauth "scopes" init parameter * improvement: add "select all" and "select none" to oauth scopes popup
This commit is contained in:
committed by
GitHub
parent
4497387d62
commit
275c8f2ccf
@@ -62,6 +62,7 @@
|
|||||||
realm: "your-realms",
|
realm: "your-realms",
|
||||||
appName: "your-app-name",
|
appName: "your-app-name",
|
||||||
scopeSeparator: " ",
|
scopeSeparator: " ",
|
||||||
|
scopes: "openid profile email phone address",
|
||||||
additionalQueryStringParams: {},
|
additionalQueryStringParams: {},
|
||||||
usePkceWithAuthorizationCodeGrant: false
|
usePkceWithAuthorizationCodeGrant: false
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ const oauthBlockSchema = {
|
|||||||
type: "string",
|
type: "string",
|
||||||
name: "scopeSeparator"
|
name: "scopeSeparator"
|
||||||
},
|
},
|
||||||
|
OAUTH_SCOPES: {
|
||||||
|
type: "string",
|
||||||
|
name: "scopes"
|
||||||
|
},
|
||||||
OAUTH_ADDITIONAL_PARAMS: {
|
OAUTH_ADDITIONAL_PARAMS: {
|
||||||
type: "object",
|
type: "object",
|
||||||
name: "additionalQueryStringParams"
|
name: "additionalQueryStringParams"
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ clientSecret | `OAUTH_CLIENT_SECRET` | **🚨 Never use this parameter in your p
|
|||||||
realm | `OAUTH_REALM` |realm query parameter (for oauth1) added to `authorizationUrl` and `tokenUrl`. MUST be a string
|
realm | `OAUTH_REALM` |realm query parameter (for oauth1) added to `authorizationUrl` and `tokenUrl`. MUST be a string
|
||||||
appName | `OAUTH_APP_NAME` |application name, displayed in authorization popup. MUST be a string
|
appName | `OAUTH_APP_NAME` |application name, displayed in authorization popup. MUST be a string
|
||||||
scopeSeparator | `OAUTH_SCOPE_SEPARATOR` |scope separator for passing scopes, encoded before calling, default value is a space (encoded value `%20`). MUST be a string
|
scopeSeparator | `OAUTH_SCOPE_SEPARATOR` |scope separator for passing scopes, encoded before calling, default value is a space (encoded value `%20`). MUST be a string
|
||||||
|
scopes | `OAUTH_SCOPES` |string array or scope separator (i.e. space) separated string of initially selected oauth scopes, default is empty array
|
||||||
additionalQueryStringParams | `OAUTH_ADDITIONAL_PARAMS` |Additional query parameters added to `authorizationUrl` and `tokenUrl`. MUST be an object
|
additionalQueryStringParams | `OAUTH_ADDITIONAL_PARAMS` |Additional query parameters added to `authorizationUrl` and `tokenUrl`. MUST be an object
|
||||||
useBasicAuthenticationWithAccessCodeGrant | _Unavailable_ |Only activated for the `accessCode` flow. During the `authorization_code` request to the `tokenUrl`, pass the [Client Password](https://tools.ietf.org/html/rfc6749#section-2.3.1) using the HTTP Basic Authentication scheme (`Authorization` header with `Basic base64encode(client_id + client_secret)`). The default is `false`
|
useBasicAuthenticationWithAccessCodeGrant | _Unavailable_ |Only activated for the `accessCode` flow. During the `authorization_code` request to the `tokenUrl`, pass the [Client Password](https://tools.ietf.org/html/rfc6749#section-2.3.1) using the HTTP Basic Authentication scheme (`Authorization` header with `Basic base64encode(client_id + client_secret)`). The default is `false`
|
||||||
usePkceWithAuthorizationCodeGrant | `OAUTH_USE_PKCE` | Only applies to `authorizatonCode` flows. [Proof Key for Code Exchange](https://tools.ietf.org/html/rfc7636) brings enhanced security for OAuth public clients. The default is `false`
|
usePkceWithAuthorizationCodeGrant | `OAUTH_USE_PKCE` | Only applies to `authorizatonCode` flows. [Proof Key for Code Exchange](https://tools.ietf.org/html/rfc7636) brings enhanced security for OAuth public clients. The default is `false`
|
||||||
@@ -22,6 +23,7 @@ ui.initOAuth({
|
|||||||
realm: "your-realms",
|
realm: "your-realms",
|
||||||
appName: "your-app-name",
|
appName: "your-app-name",
|
||||||
scopeSeparator: " ",
|
scopeSeparator: " ",
|
||||||
|
scopes: "openid profile",
|
||||||
additionalQueryStringParams: {test: "hello"},
|
additionalQueryStringParams: {test: "hello"},
|
||||||
usePkceWithAuthorizationCodeGrant: true
|
usePkceWithAuthorizationCodeGrant: true
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -25,12 +25,16 @@ export default class Oauth2 extends React.Component {
|
|||||||
let clientId = auth && auth.get("clientId") || authConfigs.clientId || ""
|
let clientId = auth && auth.get("clientId") || authConfigs.clientId || ""
|
||||||
let clientSecret = auth && auth.get("clientSecret") || authConfigs.clientSecret || ""
|
let clientSecret = auth && auth.get("clientSecret") || authConfigs.clientSecret || ""
|
||||||
let passwordType = auth && auth.get("passwordType") || "basic"
|
let passwordType = auth && auth.get("passwordType") || "basic"
|
||||||
|
let scopes = auth && auth.get("scopes") || authConfigs.scopes || []
|
||||||
|
if (typeof scopes === "string") {
|
||||||
|
scopes = scopes.split(authConfigs.scopeSeparator || " ")
|
||||||
|
}
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
appName: authConfigs.appName,
|
appName: authConfigs.appName,
|
||||||
name: name,
|
name: name,
|
||||||
schema: schema,
|
schema: schema,
|
||||||
scopes: [],
|
scopes: scopes,
|
||||||
clientId: clientId,
|
clientId: clientId,
|
||||||
clientSecret: clientSecret,
|
clientSecret: clientSecret,
|
||||||
username: username,
|
username: username,
|
||||||
@@ -77,6 +81,16 @@ export default class Oauth2 extends React.Component {
|
|||||||
this.setState(state)
|
this.setState(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selectScopes =(e) => {
|
||||||
|
if (e.target.dataset.all) {
|
||||||
|
this.setState({
|
||||||
|
scopes: Array.from((this.props.schema.get("allowedScopes") || this.props.schema.get("scopes")).keys())
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.setState({ scopes: [] })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
logout =(e) => {
|
logout =(e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
let { authActions, errActions, name } = this.props
|
let { authActions, errActions, name } = this.props
|
||||||
@@ -201,7 +215,11 @@ export default class Oauth2 extends React.Component {
|
|||||||
|
|
||||||
{
|
{
|
||||||
!isAuthorized && scopes && scopes.size ? <div className="scopes">
|
!isAuthorized && scopes && scopes.size ? <div className="scopes">
|
||||||
<h2>Scopes:</h2>
|
<h2>
|
||||||
|
Scopes:
|
||||||
|
<a onClick={this.selectScopes} data-all={true}>select all</a>
|
||||||
|
<a onClick={this.selectScopes}>select none</a>
|
||||||
|
</h2>
|
||||||
{ scopes.map((description, name) => {
|
{ scopes.map((description, name) => {
|
||||||
return (
|
return (
|
||||||
<Row key={ name }>
|
<Row key={ name }>
|
||||||
@@ -209,6 +227,7 @@ export default class Oauth2 extends React.Component {
|
|||||||
<Input data-value={ name }
|
<Input data-value={ name }
|
||||||
id={`${name}-${flow}-checkbox-${this.state.name}`}
|
id={`${name}-${flow}-checkbox-${this.state.name}`}
|
||||||
disabled={ isAuthorized }
|
disabled={ isAuthorized }
|
||||||
|
checked={ this.state.scopes.includes(name) }
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
onChange={ this.onScopeChange }/>
|
onChange={ this.onScopeChange }/>
|
||||||
<label htmlFor={`${name}-${flow}-checkbox-${this.state.name}`}>
|
<label htmlFor={`${name}-${flow}-checkbox-${this.state.name}`}>
|
||||||
|
|||||||
@@ -76,6 +76,15 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
|
||||||
@include text_headline();
|
@include text_headline();
|
||||||
|
|
||||||
|
a
|
||||||
|
{
|
||||||
|
font-size: 12px;
|
||||||
|
color: $auth-select-all-none-link-font-color;
|
||||||
|
cursor: pointer;
|
||||||
|
padding-left: 10px;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ $_color-options: #0d5aa7 !default;
|
|||||||
// Authorize
|
// Authorize
|
||||||
|
|
||||||
$auth-container-border-color: $gray-50 !default;
|
$auth-container-border-color: $gray-50 !default;
|
||||||
|
$auth-select-all-none-link-font-color: $color-info !default;
|
||||||
// Buttons
|
// Buttons
|
||||||
|
|
||||||
$btn-background-color: transparent !default;
|
$btn-background-color: transparent !default;
|
||||||
|
|||||||
@@ -70,6 +70,18 @@ module.exports = {
|
|||||||
authorizationUrl: {
|
authorizationUrl: {
|
||||||
selector: ".auth-container code"
|
selector: ".auth-container code"
|
||||||
},
|
},
|
||||||
|
readPetsScope: {
|
||||||
|
selector: "input[data-value='read:pets']"
|
||||||
|
},
|
||||||
|
writePetsScope: {
|
||||||
|
selector: "input[data-value='write:pets']"
|
||||||
|
},
|
||||||
|
selectAllScopes: {
|
||||||
|
selector: ".auth-container h2 a[data-all]"
|
||||||
|
},
|
||||||
|
selectNoneScopes: {
|
||||||
|
selector: ".auth-container h2 a:not([data-all])"
|
||||||
|
},
|
||||||
flow: {
|
flow: {
|
||||||
selector: ".flow code"
|
selector: ".flow code"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -45,6 +45,16 @@ describe("Render scheme", function () {
|
|||||||
.assert.containsText("@authorizationUrl", "http://petstore.swagger.io/oauth/dialog")
|
.assert.containsText("@authorizationUrl", "http://petstore.swagger.io/oauth/dialog")
|
||||||
.assert.containsText("@flow", "implicit")
|
.assert.containsText("@flow", "implicit")
|
||||||
.assert.value("@inputClientID", "your-client-id")
|
.assert.value("@inputClientID", "your-client-id")
|
||||||
|
schemeContainer.expect.element("@readPetsScope").to.be.selected
|
||||||
|
schemeContainer.expect.element("@writePetsScope").to.not.be.selected
|
||||||
|
|
||||||
|
schemeContainer.click("@selectAllScopes")
|
||||||
|
schemeContainer.expect.element("@readPetsScope").to.be.selected
|
||||||
|
schemeContainer.expect.element("@writePetsScope").to.be.selected
|
||||||
|
|
||||||
|
schemeContainer.click("@selectNoneScopes")
|
||||||
|
schemeContainer.expect.element("@readPetsScope").to.not.be.selected
|
||||||
|
schemeContainer.expect.element("@writePetsScope").to.not.be.selected
|
||||||
|
|
||||||
client.end()
|
client.end()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -101,6 +101,7 @@
|
|||||||
realm: "your-realms",
|
realm: "your-realms",
|
||||||
appName: "your-app-name",
|
appName: "your-app-name",
|
||||||
scopeSeparator: " ",
|
scopeSeparator: " ",
|
||||||
|
scopes: "read:pets profile openid",
|
||||||
additionalQueryStringParams: {}
|
additionalQueryStringParams: {}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user