Skip to content

Conversation

@mhennemeyer
Copy link

Summary

This PR adds first-class handling of HTTP authentication challenges (Basic and Digest) to the Compose WebView Multiplatform library via a single, unified interceptor API. The API lets apps supply credentials or cancel when a site challenges for authentication. The underlying platforms (Android/iOS) negotiate the exact scheme with the server.

  • Platforms: Android and iOS supported in this PR (no changes for Desktop/Web).
  • API: BasicAuthInterceptor (existing name retained) + rememberWebViewNavigator(basicAuthInterceptor = …).
  • Docs: Added/relocated a new “HTTP Authentication (Basic and Digest)” section in README, placed between “Request Interceptor” and “WebSettings.”

Motivation

  • Provide a consistent way to handle HTTP auth challenges across Android and iOS.
  • Align with Android’s least-information model (no scheme provided) while leveraging iOS’s explicit scheme exposure.
  • Keep app code simple: supply credentials or cancel—no scheme-specific logic required.

What’s changed

  • iOS (WKWebView)
    • WKNavigationDelegate.kt: Accepts both NSURLAuthenticationMethodHTTPBasic and NSURLAuthenticationMethodHTTPDigest and forwards the challenge to the interceptor.
    • Uses NSURLCredential constructed from the provided username/password when handler.proceed is called.
  • Android (WebView)
    • AccompanistWebView.kt: Keeps using onReceivedHttpAuthRequest; clarifying comments document that Android funnels all HTTP auth schemes through the same callback and the platform negotiates Basic vs Digest after credentials are supplied.
  • Documentation
    • README: Introduces the “HTTP Authentication (Basic and Digest)” section with usage examples and notes; section positioned between “Request Interceptor” and “WebSettings.”

Public API (unchanged)

  • interface BasicAuthInterceptor with onHttpAuthRequest(challenge, handler, navigator): Boolean
  • interface BasicAuthHandler { proceed(username, password); cancel() }
  • data class BasicAuthChallenge(host, realm, isProxy, previousFailureCount)
  • @Composable fun rememberWebViewNavigator(basicAuthInterceptor = …)

No breaking changes. The interceptor name remains BasicAuthInterceptor to minimize churn; it works for both Basic and Digest.

Usage (excerpt)

class MyBasicAuthInterceptor : BasicAuthInterceptor {
    override fun onHttpAuthRequest(
        challenge: BasicAuthChallenge,
        handler: BasicAuthHandler,
        navigator: WebViewNavigator,
    ): Boolean {
        // Decide whether to handle based on challenge.host / challenge.realm
        val username = "user"
        val password = "pass"
        handler.proceed(username, password) // or handler.cancel()
        return true
    }
}

@Composable
fun MyScreen() {
    val navigator = rememberWebViewNavigator(
        basicAuthInterceptor = MyBasicAuthInterceptor()
    )
    WebView(state = rememberWebViewState("https://example.com"), navigator = navigator)
}

Platform specifics and behavior

  • Android
    • WebView exposes onReceivedHttpAuthRequest(view, handler, host, realm) without scheme details.
    • Calling handler.proceed(username, password) lets the platform choose Basic or Digest per the server’s challenge.
  • iOS
    • WKWebView exposes protectionSpace.authenticationMethod; we forward only when it’s HTTPBasic or HTTPDigest.
    • On proceed, a NSURLCredential is created and returned to the challenge.

Security notes

  • Use HTTPS. HTTP authentication headers and content are otherwise visible to on-path attackers.
  • This feature does not store credentials; apps should manage secure credential storage and prompting policy.

Documentation updates

  • README: New “HTTP Authentication (Basic and Digest)” section with examples and notes. Placed between “Request Interceptor” and “WebSettings.”

Testing and verification

Compatibility

  • No breaking API changes.
  • Desktop/Web paths are unaffected.
  • Minimal risk: iOS paths are gated by explicit method check; Android preserves existing behavior with clearer docs/comments.

Future work (optional)

  • Optional rename to HttpAuthInterceptor with a deprecation shim for BasicAuthInterceptor.
  • Optional examples showing UI credential prompts and per-host/realm caching.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant