diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CallbackUrlSchemeValidator.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CallbackUrlSchemeValidator.java index a75af8dd5e..bdb4a6d4ab 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CallbackUrlSchemeValidator.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CallbackUrlSchemeValidator.java @@ -26,7 +26,8 @@ import java.util.regex.Pattern; @Slf4j public class CallbackUrlSchemeValidator { - private static final Pattern SCHEME_PATTERN = Pattern.compile("[a-zA-Z][a-zA-Z0-9+.-]*"); + // RFC 3986 scheme grammar, plus '_': mobile apps derive the scheme from their package name, which may contain one + private static final Pattern SCHEME_PATTERN = Pattern.compile("[a-zA-Z][a-zA-Z0-9+.\\-_]*"); private static final Set FORBIDDEN_SCHEMES = Set.of("http", "https", "javascript", "data", "file", "vbscript"); private static final int MAX_LOGGED_LENGTH = 128; diff --git a/application/src/test/java/org/thingsboard/server/service/security/auth/oauth2/CallbackUrlSchemeValidatorTest.java b/application/src/test/java/org/thingsboard/server/service/security/auth/oauth2/CallbackUrlSchemeValidatorTest.java index 2ba11324ce..aa2eeb7982 100644 --- a/application/src/test/java/org/thingsboard/server/service/security/auth/oauth2/CallbackUrlSchemeValidatorTest.java +++ b/application/src/test/java/org/thingsboard/server/service/security/auth/oauth2/CallbackUrlSchemeValidatorTest.java @@ -26,7 +26,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class CallbackUrlSchemeValidatorTest { @ParameterizedTest - @ValueSource(strings = {"tbmobile", "tb-mobile.app1", "TbMobile+1"}) + @ValueSource(strings = {"tbmobile", "tb-mobile.app1", "TbMobile+1", "org.mycompany.myapp.auth", "com.my_company.app.auth"}) public void testMobileAppSchemeIsValid(String callbackUrlScheme) { assertThat(CallbackUrlSchemeValidator.isValid(callbackUrlScheme)).isTrue(); }