Merge pull request #969 from Sapd/sso-redirect-ri

SSO: Add redirect_uri to oAuth auth request
This commit is contained in:
advplyr
2023-12-07 16:08:19 -06:00
committed by GitHub
+20 -9
View File
@@ -95,6 +95,7 @@ export default {
processing: false, processing: false,
serverConfig: { serverConfig: {
address: null, address: null,
version: null,
username: null, username: null,
customHeaders: null customHeaders: null
}, },
@@ -107,7 +108,8 @@ export default {
state: null, state: null,
verifier: null, verifier: null,
challenge: null, challenge: null,
buttonText: 'Login with OpenID' buttonText: 'Login with OpenID',
enforceHTTPs: true // RFC 6749, Section 10.9 requires https
} }
} }
}, },
@@ -155,7 +157,7 @@ export default {
*/ */
async clickLoginWithOpenId() { async clickLoginWithOpenId() {
// oauth standard requires https explicitly // oauth standard requires https explicitly
if (!this.serverConfig.address.startsWith('https')) { if (!this.serverConfig.address.startsWith('https') && this.oauth.enforceHTTPs) {
console.warn(`[SSO] Oauth2 requires HTTPS`) console.warn(`[SSO] Oauth2 requires HTTPS`)
this.$toast.error(`SSO: The URL to the server must be https:// secured`) this.$toast.error(`SSO: The URL to the server must be https:// secured`)
return return
@@ -179,14 +181,19 @@ export default {
const client_id = redirectUrl.searchParams.get('client_id') const client_id = redirectUrl.searchParams.get('client_id')
const scope = redirectUrl.searchParams.get('scope') const scope = redirectUrl.searchParams.get('scope')
const state = redirectUrl.searchParams.get('state') const state = redirectUrl.searchParams.get('state')
let redirect_uri_param = redirectUrl.searchParams.get('redirect_uri')
// Backwards compatability with 2.6.0
if (this.serverConfig.version === '2.6.0') {
redirect_uri_param = 'audiobookshelf://oauth'
}
if (!client_id || !scope || !state) { if (!client_id || !scope || !state || !redirect_uri_param) {
console.warn(`[SSO] Invalid OpenID URL - client_id scope or state missing: ${redirectUrl}`) console.warn(`[SSO] Invalid OpenID URL - client_id scope state or redirect_uri missing: ${redirectUrl}`)
this.$toast.error(`SSO: Invalid answer`) this.$toast.error(`SSO: Invalid answer`)
return return
} }
if (redirectUrl.protocol !== 'https:') { if (redirectUrl.protocol !== 'https:' && this.oauth.enforceHTTPs) {
console.warn(`[SSO] Insecure Redirection by SSO provider: ${redirectUrl.protocol} is not allowed. Use HTTPS`) console.warn(`[SSO] Insecure Redirection by SSO provider: ${redirectUrl.protocol} is not allowed. Use HTTPS`)
this.$toast.error(`SSO: The SSO provider must return a HTTPS secured URL`) this.$toast.error(`SSO: The SSO provider must return a HTTPS secured URL`)
return return
@@ -195,8 +202,8 @@ export default {
// We need to verify if the state is the same later // We need to verify if the state is the same later
this.oauth.state = state this.oauth.state = state
const host = `https://${redirectUrl.host}` const host = `${redirectUrl.protocol}//${redirectUrl.host}`
const buildUrl = `${host}${redirectUrl.pathname}?response_type=code` + `&client_id=${encodeURIComponent(client_id)}&scope=${encodeURIComponent(scope)}&state=${encodeURIComponent(state)}` + `&redirect_uri=${encodeURIComponent('audiobookshelf://oauth')}` + `&code_challenge=${encodeURIComponent(this.oauth.challenge)}&code_challenge_method=S256` const buildUrl = `${host}${redirectUrl.pathname}?response_type=code` + `&client_id=${encodeURIComponent(client_id)}&scope=${encodeURIComponent(scope)}&state=${encodeURIComponent(state)}` + `&redirect_uri=${encodeURIComponent(redirect_uri_param)}` + `&code_challenge=${encodeURIComponent(this.oauth.challenge)}&code_challenge_method=S256`
// example url for authentik // example url for authentik
// const authURL = "https://authentik/application/o/authorize/?response_type=code&client_id=41cd96f...&redirect_uri=audiobookshelf%3A%2F%2Foauth&scope=openid%20openid%20email%20profile&state=asdds..." // const authURL = "https://authentik/application/o/authorize/?response_type=code&client_id=41cd96f...&redirect_uri=audiobookshelf%3A%2F%2Foauth&scope=openid%20openid%20email%20profile&state=asdds..."
@@ -243,8 +250,11 @@ export default {
this.oauth.verifier = verifier this.oauth.verifier = verifier
this.oauth.challenge = challenge this.oauth.challenge = challenge
// set parameter isRest to true, so the backend wont attempt a redirect after we call backend:/callback in exchangeCodeForToken let backendEndpoint = `${url}/auth/openid?code_challenge=${challenge}&code_challenge_method=S256&redirect_uri=${encodeURIComponent('audiobookshelf://oauth')}&client_id=${encodeURIComponent('Audiobookshelf-App')}&response_type=code`
const backendEndpoint = `${url}/auth/openid?code_challenge=${challenge}&code_challenge_method=S256&isRest=true` // Backwards compatability with 2.6.0
if (this.serverConfig.version === '2.6.0') {
backendEndpoint += '&isRest=true'
}
try { try {
const response = await CapacitorHttp.get({ const response = await CapacitorHttp.get({
@@ -608,6 +618,7 @@ export default {
this.showAuth = true this.showAuth = true
this.authMethods = statusData.data.authMethods || [] this.authMethods = statusData.data.authMethods || []
this.oauth.buttonText = statusData.data.authFormData?.authOpenIDButtonText || 'Login with OpenID' this.oauth.buttonText = statusData.data.authFormData?.authOpenIDButtonText || 'Login with OpenID'
this.serverConfig.version = statusData.data.serverVersion
if (statusData.data.authFormData?.authOpenIDAutoLaunch) { if (statusData.data.authFormData?.authOpenIDAutoLaunch) {
this.clickLoginWithOpenId() this.clickLoginWithOpenId()