domlysz / BlenderGIS

Blender addons to make the bridge between Blender and geographic data
GNU General Public License v3.0
7.64k stars 1.35k forks source link

How to deal with authenticated WMS? #723

Open prayerslayer opened 1 year ago

prayerslayer commented 1 year ago

Blender and OS versions

Describe the bug

I wanted to add Sentinel-2 satellite images through a WMS by mapsforeurope.org. The WMS is not public, i.e., requires authentication. This particular WMS wants a token URL param added to every request. Jugding from servicesDefs.py and the buildUrl function it seems like this is not easily doable without code changes?

So this issue less a particular bug and more a question how/if you think the plugin could handle authenticated WMS's in general (as there are a bunch of other auth methods in use, etc.).

How to Reproduce

  1. Get an access token for WMS "pan european imagery" here
  2. Add this to servicesDefs.py, reinstall BlenderGIS.
"SENTINEL2" : {
        "name" : 'Sentinel2 WMS',
        "description" : 'Maps for Europe',
        "service": 'WMS',
        "grid": 'WM',
        "layers" : {
            "Sentinel2" : {"urlKey" : 'rgb', "name" : 'Sen2Europe', "description" : '', "format" : 'png', "style" : '', "zmin" : 0, "zmax" : 20}
        },
        "urlTemplate": {
            "BASE_URL" : 'https://www.mapsforeurope.org/api/v2/maps/external/wms/pan-european-imagery?token={TOKEN}',
            "SERVICE" : 'WMS',
            "VERSION" : '1.3.0',
            "REQUEST" : 'GetMap',
            "SRS" : '{CRS}', #EPSG:xxxx
            "LAYERS" : '{LAY}',
            "FORMAT" : 'image/{FORMAT}',
            "STYLES" : '{STYLE}',
            "BBOX" : '{BBOX}', #xmin,ymin,xmax,ymax, in "SRS" projection
            "WIDTH" : '{WIDTH}',
            "HEIGHT" : '{HEIGHT}',
            "TRANSPARENT" : "False"
            },
        "referer": "https://www.mapsforeurope.org/"
    },

Then try to use this basemap.

Error message

No tiles visible, logs say Can't download tile x2209 y1431. Error HTTP Error 401: UNAUTHORIZED.

It's actually amazing that a request goes out since the URL seems malformed to me: https://www.mapsforeurope.org/api/v2/maps/external/wms/pan-european-imagery?token={TOKEN}?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&SRS=EPSG:3857&LAYERS=rgb&FORMAT=image/png&STYLES=&BBOX=1506726.7015573941,6007338.926988576,1516510.6411778966,6017122.866609078&WIDTH=256&HEIGHT=256&TRANSPARENT=False. Notice the ?token={TOKEN}?.

With a correct URL I can see this image in Firefox:

image

prayerslayer commented 1 year ago

Of course, there is an easy quick fix for my particular issue:

In mapservice.py, change

if url[-1] != '?' :
    url += '?'

to

if url[-1] != '?' and not '?' in url:
    url += '?'
elif url[-1] != '&':
    url += '&'

in the WMS part of buildUrl. This change does not produce ?token={TOKEN}? URLs anymore and the extended URL template from the service definition works.