From 04ad43a62e70264e26a2071f2d506ad9788e1897 Mon Sep 17 00:00:00 2001 From: ivo-k <27406085+ivo-k@users.noreply.github.com> Date: Mon, 29 Jan 2024 09:29:35 +0100 Subject: [PATCH] make url validation configurable --- .../SpringSecurityOAuth2Controller.groovy | 8 +++++- .../SpringSecurityOAuth2ControllerSpec.groovy | 28 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/grails-app/controllers/grails/plugin/springsecurity/oauth2/SpringSecurityOAuth2Controller.groovy b/grails-app/controllers/grails/plugin/springsecurity/oauth2/SpringSecurityOAuth2Controller.groovy index f525f8c..1bc2dc6 100644 --- a/grails-app/controllers/grails/plugin/springsecurity/oauth2/SpringSecurityOAuth2Controller.groovy +++ b/grails-app/controllers/grails/plugin/springsecurity/oauth2/SpringSecurityOAuth2Controller.groovy @@ -25,6 +25,7 @@ import groovy.util.logging.Slf4j import org.apache.commons.lang.StringUtils import org.apache.commons.lang.exception.ExceptionUtils import org.apache.commons.validator.routines.UrlValidator +import org.springframework.beans.factory.annotation.Value import org.springframework.security.core.context.SecurityContextHolder import org.springframework.web.servlet.ModelAndView @@ -43,6 +44,9 @@ class SpringSecurityOAuth2Controller { SpringSecurityOauth2BaseService springSecurityOauth2BaseService SpringSecurityService springSecurityService + @Value('${security.oauth2.controller.validateAuthorizationUrl:true}') + boolean validateAuthorizationUrl = true + UrlValidator urlValidator = UrlValidator.instance /** * Authenticate */ @@ -54,9 +58,11 @@ class SpringSecurityOAuth2Controller { log.debug "authenticate ${providerName}" String url = springSecurityOauth2BaseService.getAuthorizationUrl(providerName) log.debug "redirect url from s2oauthservice=${url}" - if (!UrlValidator.instance.isValid(url)) { + if (validateAuthorizationUrl && !urlValidator.isValid(url)) { + log.error("Authorization url for provider '${providerName}' is invalid: ${url}") flash.message = "Authorization url for provider '${providerName}' is invalid." redirect(controller: 'login', action: 'index') + return } redirect(url: url) } diff --git a/src/integration-test/groovy/grails/plugin/springsecurity/oauth2/SpringSecurityOAuth2ControllerSpec.groovy b/src/integration-test/groovy/grails/plugin/springsecurity/oauth2/SpringSecurityOAuth2ControllerSpec.groovy index 1eedf7c..c2df0da 100644 --- a/src/integration-test/groovy/grails/plugin/springsecurity/oauth2/SpringSecurityOAuth2ControllerSpec.groovy +++ b/src/integration-test/groovy/grails/plugin/springsecurity/oauth2/SpringSecurityOAuth2ControllerSpec.groovy @@ -6,6 +6,7 @@ import grails.plugin.springsecurity.oauth2.exception.OAuth2Exception import grails.plugin.springsecurity.oauth2.token.OAuth2SpringToken import grails.testing.mixin.integration.Integration import grails.testing.web.controllers.ControllerUnitTest +import org.apache.commons.validator.routines.UrlValidator import spock.lang.Specification import spock.lang.Unroll @@ -200,6 +201,33 @@ class SpringSecurityOAuth2ControllerSpec extends Specification implements Contro response view == '/springSecurityOAuth2/ask' } + + void "authenticate use custom url validator"() { + given: + params.provider = 'somewhat' + def springSecurityOauth2BaseService = Mock(SpringSecurityOauth2BaseService) + springSecurityOauth2BaseService.getAuthorizationUrl(_) >> {url} + controller.springSecurityOauth2BaseService = springSecurityOauth2BaseService + if (validator == 'null') { controller.validateAuthorizationUrl = false } + if (validator == 'custom') { + def v = Mock(UrlValidator) + v.isValid(_) >> { true } + controller.urlValidator = v + } + + when: + controller.authenticate() + + then: + response.redirectUrl == shouldFail ? '/login/index' : url + where: + url | validator | shouldFail + 'https://www.google.com' | 'default' | false + 'https://intranet.local' | 'default' | true + 'https://intranet.local' | 'null' | false + 'https://intranet.local' | 'custom' | false + } + }