OpenSprinkler Forums OpenSprinkler Mobile and Web App After Android Update 2.3.2 Problems

Viewing 2 posts - 26 through 27 (of 27 total)
  • Author
    Posts
  • #83509

    Shane Pike
    Participant

    No, sorry. I was referencing a different issue in this thread, which I realize now wasn’t the original issue in this thread. Sorry about that. My app works now but doesn’t use SSL or Auth.

    #83578

    ipilcher
    Participant

    I have finally gotten this to work.

    The previous suggestion of using Access-Control-Allow-Origin: * does not work, because the wildcard value does not work when authentication is used. It is necessary to specify the correct origin. The Android app is built on Apache Cordova, which uses http://localhost as its origin. (The iOS version of Apache Cordova apparently uses something different.)

    When the web app is used with a browser, the origin will be the site from which the web app is served, https://ui.opensprinkler.com by default. Thus, if one wishes to use both the Android app and the web app (from its default location), one would need to specify both origins (http://localhost and https://ui.opensprinkler.com) in the Access-Control-Allow-Origin header. Unfortunately, that header cannot contain multiple values (nor can it appear more than once in a response). The best solution to this problem seems to be to copy the value of the Origin header in the request and send it back in the Access-Control-Allow-Origin response header. Ideally, this should only be done for the origins that are actually trusted.

    A couple of additional steps are also required.

    • Two additional CORS-related headers must be sent — Access-Control-Allow-Credentials: true and Access-Control-Allow-Headers: Authorization
    • Authorization must be disabled for OPTIONS requests. These are CORS preflight requests, and they must succeed (return a 200 or 204 status) before the client will proceed with an actual GET request.

    Putting this all together gives me something like this.

    <VirtualHost 172.31.255.2:443>
        ServerName sprinklers.penurio.us
        ErrorLog /etc/httpd/logs/sprinklers_error.log
        TransferLog /etc/httpd/logs/sprinklers_access.log
        LogLevel info
        SSLEngine on
        SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
        SSLHonorCipherOrder on
        SSLCipherSuite PROFILE=SYSTEM
        SSLProxyCipherSuite PROFILE=SYSTEM
        SSLCertificateFile /etc/pki/tls/certs/sprinklers.penurio.us.crt
        SSLCertificateKeyFile /etc/pki/tls/private/sprinklers.penurio.us/sprinklers.penurio.us.key
        # OPTIONS requests must succeed (return 200 or 204) for CORS to work,
        # so don't require authentication for those requests
        <If "%{REQUEST_METHOD} != 'OPTIONS'">
            AuthType Basic
            AuthBasicProvider ldap
            AuthName OpenSprinkler
            AuthLDAPUrl ldap://127.0.0.1/cn=users,cn=accounts,dc=penurio,dc=us?uid
            AuthLDAPCompareAsUser on
            Require ldap-group cn=sprinklers,cn=groups,cn=accounts,dc=penurio,dc=us
        </If>
        ProxyPass http://172.31.252.3 timeout=1200
        ProxyPassReverse http://172.31.252.3
        # The OpenSprinkler controller sets Access-Control-Allow-Origin: *
        # but that won't work with authentication, so remove that header and
        # just copy the Origin from the request into the ACAO header
        Header onsuccess unset Access-Control-Allow-Origin
        SetEnvIf Origin "^(http://localhost)|(https://ui.opensprinkler.com)$" ORIGIN=$1
        Header always set Access-Control-Allow-Origin %{ORIGIN}e env=ORIGIN
        Header always set Access-Control-Allow-Credentials: true
        Header always set Access-Control-Allow-Headers: Authorization
    </VirtualHost>
    

    Note that a regular expression is used to accept only the default web app location (https://ui.opensprinkler.com and the Android app http://localhost) as origins. If the web app content is hosted elsewhere, replace https://ui.opensprinkler.com with the URL at which the content is hosted.

    In fact, it is possible to eliminate browser-based CORS issues entirely by hosting the web app content and the OpenSprinkler controller within the same domain. The configuration below puts the web app content at https://sprinklers.penurio.us/api/, and it puts the web app content at https://sprinklers.penurio.us/ui/. Since the only client that will need CORS headers is the Android app, it simply sets Access-Control-Allow-Origin: http://localhost.

    <VirtualHost 172.31.255.2:443>
        ServerName sprinklers.penurio.us
        DocumentRoot /var/www/opensprinkler
        DirectoryIndex /api/
        ErrorLog /etc/httpd/logs/sprinklers_error.log
        TransferLog /etc/httpd/logs/sprinklers_access.log
        LogLevel info
        SSLEngine on
        SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
        SSLHonorCipherOrder on
        SSLCipherSuite PROFILE=SYSTEM
        SSLProxyCipherSuite PROFILE=SYSTEM
        SSLCertificateFile /etc/pki/tls/certs/sprinklers.penurio.us.crt
        SSLCertificateKeyFile /etc/pki/tls/private/sprinklers.penurio.us/sprinklers.penurio.us.key
        <Location "/api/">
            # OPTIONS requests must succeed (return 200 or 204) for CORS to work,
            # so don't require authentication for those requests
            <If "%{REQUEST_METHOD} != 'OPTIONS'">
                AuthType Basic
                AuthBasicProvider ldap
                AuthName OpenSprinkler
                AuthLDAPUrl ldap://127.0.0.1/cn=users,cn=accounts,dc=penurio,dc=us?uid
                AuthLDAPCompareAsUser on
                Require ldap-group cn=sprinklers,cn=groups,cn=accounts,dc=penurio,dc=us
            </If>
            ProxyPass http://172.31.252.3/ timeout=1200
            ProxyPassReverse http://172.31.252.3/
            # The OpenSprinkler controller sets Access-Control-Allow-Origin: *
            # but that won't work with authentication, so remove that header and
            # send the Origin used by the Android app
            Header onsuccess unset Access-Control-Allow-Origin
            Header always set Access-Control-Allow-Origin http://localhost
            Header always set Access-Control-Allow-Credentials: true
            Header always set Access-Control-Allow-Headers: Authorization
        </Location>
    </VirtualHost>
    

    A few notes about this configuration.

    • Authentication is required only for paths under /api/, because there's no particular reason that the web app content needs to be protected.
    • DirectoryIndex /api/ means that I can simply point my browser at https://sprinklers.penurio.us to access the web app.
    • When adding my controller to the Android app, I set the Open Sprinkler IP to sprinklers.penurio.us/api.

    Finally, note that Firefox is still partially broken, even without CORS.

Viewing 2 posts - 26 through 27 (of 27 total)
  • You must be logged in to reply to this topic.

OpenSprinkler Forums OpenSprinkler Mobile and Web App After Android Update 2.3.2 Problems