Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Web auth #27

Open
Jipok opened this issue Feb 11, 2024 · 4 comments
Open

Feature request: Web auth #27

Jipok opened this issue Feb 11, 2024 · 4 comments
Labels
enhancement New feature or request

Comments

@Jipok
Copy link

Jipok commented Feb 11, 2024

I tried many different self-hosted applications and over time I came to the idea that passwords are very inconvenient and unsafe. Fortunately, it turned out that various popular reverse proxies(together with authorizing middleware) transmit the Remote-User header(Sometimes X-Forwarded-User). And some applications(example: grist) can be configured for this authentication method. Even more can be configured for public access(i.e. disabling authentication) and work perfectly behind authorizing reverse proxies.
Over time, I wrote a minimalistic and convenient(for me) authorizing reverse proxy Jauth. Hosting various applications has become very convenient and safe. Overall, I don't remember encountering any problems during normal use.

However, some services offer the use of their applications. And this is where the problems begin, since they use some kind of http basic auth and do not connect with any authorizing reverse proxy at all. I was thinking how to fix this. There seems to be no common way to interact between an authorizing proxy and a client(not a browser). I thought about it and decided that no special method was needed. After all, there are applications on the phone that open the browser for OAuth so that the user can log in, and then return to the application. Therefore, I added sending the WWW-Authenticate: Bearer realm="JAuth" header to Jauth. And answering with 401 code. It seems that browsers normally perceive this and display everything correctly. And mobile applications can, based on this header, understand that the user needs to display the page via WebView. I'm not an Android developer, but it seems that such a change is not difficult and does not bloat project. I decided to try to write to you to find out your opinion. Your application is one of the options that I am considering for simple and convenient synchronization of my phone with self-hosted services with WebDav support.

For your convenience, I hosted a simple webdav server https://j.ateam.undo.it/public/ and gave you access(over ssh) using https://github.com/phpbg.keys. You can go in and try it from a browser. If it also works through your application, then this will be a big step forward in the distribution of convenient passwordless access.
If you are interested, I can also give access via telegram. For this I need a username or id.

P.S. I did not read the authorization standards(rfc6750, rfc2617, scheme) and therefore could have done something incorrectly. Open for discussion.

@Jipok Jipok changed the title Web auth Feature request: Web auth Feb 11, 2024
@phpbg
Copy link
Owner

phpbg commented Feb 13, 2024

I think it is not very difficult to intercept a 401 with a www-authenticate header, but then i don't where to redirect (which url?), and how to get the token from the browser back to the app...

If there is enough demand maybe we can dig deeper...

@Jipok
Copy link
Author

Jipok commented Feb 13, 2024

but then i don't where to redirect (which url?)

Jauth simply sees that you do not have a token(or an incorrect one) and shows the authorization page(with code 401). After successful authentication, js script will update the page and the request will pass through jauth. Further, as I understand it, any webdav server willl answer you with code 200. Or another, well, obviously not 401 with WWW-Authenticate: Bearer....
You can offer your options and I can implement it.

and how to get the token from the browser back to the app

Well, I have very little experience in Android development. I asked to chatgpt and he suggested this code, which looks like a working option:

import android.content.Context;
import android.graphics.Bitmap;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

public class MyWebViewActivity extends AppCompatActivity {

    private WebView webView;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_webview);

        webView = findViewById(R.id.webView);

        // Enable JavaScript
        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);

        // Set WebViewClient to handle page loading and custom behavior
        webView.setWebViewClient(new WebViewClient() {

            // Store cookies if the response is not 401 or header is not "WWW-Authenticate: Bearer"
            private boolean shouldStoreCookies = true;

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                // Reset the flag when a new page starts loading
                shouldStoreCookies = true;
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                // Check if the response is 401 or the header is "WWW-Authenticate: Bearer"
                WebResourceResponse response = view.getLastWebResourceResponse();
                if (response != null && response.getStatusCode() == 401
                        && response.getResponseHeaders().containsKey("WWW-Authenticate")
                        && response.getResponseHeaders().get("WWW-Authenticate").equals("Bearer")) {
                    // Don't store cookies if the response is 401 or the header is "WWW-Authenticate: Bearer"
                    shouldStoreCookies = false;
                }

                if (shouldStoreCookies) {
                    // Retrieve cookies from the WebView
                    String cookies = CookieManager.getInstance().getCookie(url);
                    // Process the cookies (e.g., save them for future use)
                }
            }
        });

        // Load the URL in the WebView
        String url = "https://example.com";
        webView.loadUrl(url);
    }
}

@Jipok
Copy link
Author

Jipok commented Feb 13, 2024

Now it seems to me that it is not correct to use the header with Bearer. As I understand it, webdav servers indicate Basic or Digest. So the proxy can not send this header at all(just 401), or come up with its own name.

@Jipok
Copy link
Author

Jipok commented Feb 25, 2024

@phpbg
Since the webview implementation may not be desirable, can you at least add following redirects and saving cookies? Then I can just paste the session link into the application and everything will work fine.
Link looks like this:

изображение

@phpbg phpbg added the enhancement New feature or request label Mar 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants