johannes-schliephake / nextcloud-passwords-ios

An iOS client for the Nextcloud Passwords app
GNU Affero General Public License v3.0
81 stars 9 forks source link

Access Forbidden - Invalid request #47

Closed gonzalo- closed 3 years ago

gonzalo- commented 3 years ago

Hi,

I am having this error when I try to connect with the server and I try to "grant" the access, the original nextcloud app has the same issue, but it has a workaround clicking on “Revert to old login method”, but your app has not this option.

Thanks.

johannes-schliephake commented 3 years ago

Getting errors after granting access is an indicator that there might be an issue with your Nextcloud server setup.

Which version of Nextcloud are you running? Are you using a reverse proxy?

gonzalo- commented 3 years ago

NC server is 20.0.7, I am running a reverse proxy with the recommended headers, with the App-token works just fine, but I wonder why this is not working with a regular setup.

johannes-schliephake commented 3 years ago

Ok, i guess reverse proxy is the main issue here.

As you said, the old login method bypasses the login problem because it uses a different method of getting the necessary credentials/tokens. I think the login flow (which this app uses) might not work with reverse proxies as it relies on the nc:// "protocol". Luckily, there is also the v2 login flow which should work through a proxy.

So I will look into implementing an alternative method (probably flow v2).

flo-mic commented 3 years ago

@johannes-schliephake just as information, your app supports reverse proxies 😉. I'm running nextcloud behind a nginx reverse proxy without any issues in the login flow. I just made a logout and performed anew authentication flow without any issues.

gonzalo- commented 3 years ago

@johannes-schliephake just as information, your app supports reverse proxies 😉. I'm running nextcloud behind a nginx reverse proxy without any issues in the login flow. I just made a logout and performed anew authentication flow without any issues.

With iOS?

gonzalo- commented 3 years ago

Ok, i guess reverse proxy is the main issue here.

As you said, the old login method bypasses the login problem because it uses a different method of getting the necessary credentials/tokens. I think the login flow (which this app uses) might not work with reverse proxies as it relies on the nc:// "protocol". Luckily, there is also the v2 login flow which should work through a proxy.

So I will look into implementing an alternative method (probably flow v2).

Cool! I mean, it works with tokens, but I think it's nice to have all the possibilities.

thanks!

johannes-schliephake commented 3 years ago

@flo-mic Interesting, maybe nginx can handle the login flow and Apache can't? @gonzalo- Are you using Apache or nginx for your reverse proxy?

gonzalo- commented 3 years ago

@flo-mic Interesting, maybe nginx can handle the login flow and Apache can't? @gonzalo- Are you using Apache or nginx for your reverse proxy?

I am using relayd and httpd from OpenBSD.

flo-mic commented 3 years ago

@johannes-schliephake just as information, your app supports reverse proxies 😉. I'm running nextcloud behind a nginx reverse proxy without any issues in the login flow. I just made a logout and performed anew authentication flow without any issues.

With iOS?

Yes with iOS 14.4.1, Nextcloud 20.0.7 and App 1.2.1

flo-mic commented 3 years ago

@gonzalo- can you read nginx config files? I can share my config and you can compare if some settings are missing on your relayd config

gonzalo- commented 3 years ago

@gonzalo- can you read nginx config files? I can share my config and you can compare if some settings are missing on your relayd config

Sure, I followed the official ones for Nextcloud, and everything works just fine on a regular browser, the only problem is with iOS.

flo-mic commented 3 years ago

This is my reverse proxy config:

server {
    listen 80;
    listen [::]:80;
    server_name nextcloud.example.com;
    return 301 https://nextcloud.example.com$request_uri;
}

server {
    listen 443 ssl http2;
    server_name nextcloud.example.com;
    error_page 497 https://$host:$server_port$request_uri;
    error_log /var/log/nextcloud.example.com.error.log;

    # SSL LetsEncrypt
    ssl_certificate           /certificate/path/fullchain.pem;
    ssl_certificate_key       /certificate/path/privkey.pem;

    client_max_body_size 0;
    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";

    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_intercept_errors on;
        proxy_http_version 1.1;
        proxy_pass https://127.0.0.1:8106;
    }

    # Make a regex exception for `/.well-known` so that clients can still
    # access it despite the existence of the regex rule
    # `location ~ /(\.|autotest|...)` which would otherwise handle requests
    # for `/.well-known`.
    location ^~ /.well-known {

        location = /.well-known/carddav { 
            return 301 $scheme://$host:$server_port/remote.php/dav;
        }

        location = /.well-known/caldav {
            return 301 $scheme://$host:$server_port/remote.php/dav;
        }

        # LetsEncrypt
        location = /.well-known/acme-challenge {
            root /var/lib/letsencrypt;
            default_type text/plain;
        }

        # Anything else is dynamically handled by Nextcloud
        location ^~ /.well-known {
            return 301 /index.php$uri; 
        }

        try_files $uri $uri/ =404;
    }

    location ^~ /sites/ {
        proxy_set_header X-Forwarded-Host $host:$server_port;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Server $host;
        proxy_pass https://127.0.0.1:8106/index.php/apps/cms_pico/pico_proxy/;
        proxy_ssl_server_name on;
    }
}
gonzalo- commented 3 years ago

Yes, I have pretty much the same:

        match header set "X-Client-IP" value "$REMOTE_ADDR:$REMOTE_PORT"
        match header set "X-Forwarded-For" value "$REMOTE_ADDR"
        match request header set "X-Forwarded-Port" value "$REMOTE_PORT"
        match header set "X-Forwarded-By" value "$SERVER_ADDR:$SERVER_PORT"
        match header set "Keep-Alive" value "$TIMEOUT"
        match query hash "sessid"

        match response header remove "Server"
        match response header set "X-Robots-Tag" value "none"
        match response header set "Cache-Control" value "public, no-cache, must-revalidate, max-age=1814400"
        match response header set "Cache-Control" value "public, max-age=31536000"
        match response header set "Strict-Transport-Security" value "max-age=31536000; includeSubDomains"
        match response header set "X-Content-Type-Options" value "nosniff"
        match response header set "X-XSS-Protection" value "1; mode=block"
        match response header set "X-Frame-Options" value "SAMEORIGIN"
        match response header set "Referrer-Policy" value "no-referrer"
        match response header set "Feature-Policy" value "autoplay 'self'; geolocation 'none';payment 'none'"
        match response header set "Content-Security-Policy" value "default-src https:; style-src 'self' 'unsafe-inline';img-src 'self' data: blob:; script-src 'self' 'unsafe-inline' 'unsafe-eval' *;object-src 'none'; frame-ancestors 'self';base-uri 'self';connect-src 'self';media-src 'self'; manifest-src 'self';font-src 'self' data:;worker-src 'self' blob:;form-action 'self';"
flo-mic commented 3 years ago

Yes it looks good in my opinion. But you are setting the "Cache-Control" value two times. Is this working properly? I think you are overwriting the first Cache-Control value with the the second one.

gonzalo- commented 3 years ago

Yes it looks good in my opinion. But you are setting the "Cache-Control" value two times. Is this working properly? I think you are overwriting the first Cache-Control value with the the second one.

Ah good catch, but this doesn't fix the issue :/

johannes-schliephake commented 3 years ago

While I can't really help with configuring the reverse proxy, I can describe the login flow in more detail. Maybe this helps you with finding a solution until I have implented the v2 login flow.

The web view used for logging in only works if the request header "OCS-APIREQUEST" is set to "true". If I understand correctly the web view works for you, so this seems to work. From here, the Nextcloud instance performs everything needed to log you in (e.g. 2FA). If successful, the web view is redirected to this URL: "nc://login/server:&user:&password:". The app will intercept this redirect and parse the credentials.

johannes-schliephake commented 3 years ago

I switched the app over to login flow v2, which should make everything work with your setup. Update will be out on the App Store in the coming days.

gonzalo- commented 3 years ago

Thanks!