Skip to content

Make Basic Auth with userinfo working #47

@enricoangelon

Description

@enricoangelon

Hello, thank you for the fix regarding the query parameters not being passed to the non-shortened URL.

After updating to 1.2.9, even though query parameters are now correctly passed, I noticed that Basic Auth using URL userinfo still does not work. (see RFC 3986, section 3.2.1).

After digging deeper into the extension and compiling a modified version, I managed to get it working.
The root cause is that client side redirects do not forward Basic Authentication credentials for security reasons.

How to reproduce:

  1. Try logging to your wiki instance using URL credentials through a shortened URL (e.g. https://username:password@wikiurl.com/short/d7914?basicauth=1)
  2. Try logging into your wiki instance using URL credentials without the shortener: (e.g. https://username:password@wikiurl.com?basicauth=1)

Observed behavior

  • The first case will not work (after the fix for query parameters It will correctly ask for credentials) but the credentials are not automatically passed to the resolved non-short URL.
  • The second case works as expected.

This demonstrates that the issue is on the URL Shortener extension side, not in XWiki itself.

The fix:
src/main/java/com/xwiki/urlshortener/internal/URLShortenerResourceReferenceHandler.java

if (null != documentReference) {
    XWikiContext xcontext = xcontextProvider.get();
    // Preserve query parameters from the shortened URL request.
    String queryString = URLEncodedUtils.format(
        urlResourceReference.getParameters().entrySet().stream()
            .flatMap(entry ->
                entry.getValue().stream()
                    .map(value -> new BasicNameValuePair(entry.getKey(), value)))
            .collect(Collectors.toList()),
        StandardCharsets.UTF_8
    );

    String stringURL = xcontext.getWiki().getURL(
        documentReference, "view", queryString, "", xcontext
    );

    // Check if basicauth parameter is present
    if (urlResourceReference.getParameters().containsKey("basicauth")) {
        HttpServletRequest request =
            ((ServletRequest) this.container.getRequest()).getHttpServletRequest();

        // Use xWiki's built-in auth service to check the request
        try {
            com.xpn.xwiki.XWiki xwiki = xcontext.getWiki();
            com.xpn.xwiki.user.api.XWikiUser xwikiUser =
                xwiki.getAuthService().checkAuth(xcontext);
            if (xwikiUser != null) {
                xcontext.setUser(xwikiUser.getUser());
            }
        } catch (Exception e) {
            // If auth fails, continue anyway, will normally ask for credentials
        }

        // Build the forward path from the URL (need relative path for forward)
        String forwardPath = stringURL;

        // If it's an absolute URL, extract just the path + query
        if (forwardPath.startsWith("http://") || forwardPath.startsWith("https://")) {
            try {
                java.net.URL url = new java.net.URL(forwardPath);
                forwardPath = url.getPath();
                if (url.getQuery() != null && !url.getQuery().isEmpty()) {
                    forwardPath += "?" + url.getQuery();
                }
            } catch (java.net.MalformedURLException e) {
                response.sendRedirect(stringURL);
                return;
            }
        }

        RequestDispatcher dispatcher = request.getRequestDispatcher(forwardPath);
        dispatcher.forward(request, response);
    } else {
        response.sendRedirect(stringURL);
    }
} else {
    response.sendError(
        404,
        String.format(
            "No document is associated to the given ID: [%s]",
            urlResourceReference.getPageId()
        )
    );
}

PS. This is an actual fix that works in our production environment, It may not be the most elegant solution, but it does solve the problem. 😄

Thanks for the support as always!

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions