[GeoNode-devel] oauth2 - Issue managing layer access

Paolo Corti pcorti at gmail.com
Thu Jan 4 09:36:38 PST 2018


Hi
GeoNode users will only be able to authenticate via oauth.
As far as I can remember, you will need to replicate the user as a
GeoServer user if you want to authenticate with basic authentication.
Paolo

On Thu, Jan 4, 2018 at 4:36 PM, Peter Marlow <Peter.Marlow at scisys.co.uk> wrote:
> Hi,
>
>
>
> I’m trying to manage access to a layer through a combination of geonode,
> geofence and geoserver. So for example if a user does a GetCapabilities
> request for a WMS in geoserver they will only be shown layers which they
> have access to.
>
>
>
> I’ve setup geonode, geoserver and geofence as described in this tutorial -
> http://docs.geonode.org/en/master/tutorials/admin/geoserver_geonode_security/
>
>
>
> The link between geonode and geoserver appears to be working – that is to
> say that the geonode login button in geoserver works correctly and if I edit
> permissions for a layer in geonode then geofence is updated with the correct
> data rules.
>
>
>
> The problem I encounter is when I do a request such as:
>
>
>
> http://localhost/geoserver/geonode/wms?request=getcapabilities
>
>
>
> via postman and provide basic authentication details (username/password) of
> a geonode user I get a 401 error returned and the following exception in the
> geoserver logs:
>
>
>
> 2018-01-04 15:16:05,659 DEBUG
> [security.IncludeQueryStringAntPathRequestMatcher] - Request matched by
> universal pattern '/**'
>
> 2018-01-04 15:16:05,659 DEBUG
> [security.IncludeQueryStringAntPathRequestMatcher] - Matched Path:
> /geonode/wms, QueryString: request=getcapabilities with /**
>
> 2018-01-04 15:16:05,659 DEBUG [geoserver.security] - AuthenticationCache has
> no entry for basic, testuser:f67c8204540f095070dd7a462cb44948
>
> 2018-01-04 15:16:05,660 DEBUG [geoserver.security] - Bad credentials
>
> org.springframework.security.authentication.BadCredentialsException: Bad
> credentials
>
>             at
> org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:150)
>
>             at
> org.geoserver.security.auth.UsernamePasswordAuthenticationProvider.authenticate(UsernamePasswordAuthenticationProvider.java:82)
>
>             at
> org.geoserver.security.GeoServerAuthenticationProvider.authenticate(GeoServerAuthenticationProvider.java:58)
>
>             at
> org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:167)
>
>             at
> org.geoserver.security.GeoServerSecurityManager$1.authenticate(GeoServerSecurityManager.java:323)
>
>             at
> org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:178)
>
>             at
> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
>
>             at
> org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:73)
>
>             at
> org.geoserver.security.filter.GeoServerCompositeFilter.doFilter(GeoServerCompositeFilter.java:92)
>
>             at
> org.geoserver.security.filter.GeoServerBasicAuthenticationFilter.doFilter(GeoServerBasicAuthenticationFilter.java:84)
>
>             at
> org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
>
>             at
> org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:69)
>
>             at
> org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
>
>             at
> org.geoserver.security.filter.GeoServerSecurityContextPersistenceFilter$1.doFilter(GeoServerSecurityContextPersistenceFilter.java:53)
>
>             at
> org.geoserver.security.filter.GeoServerCompositeFilter$NestedFilterChain.doFilter(GeoServerCompositeFilter.java:73)
>
>             at
> org.geoserver.security.filter.GeoServerCompositeFilter.doFilter(GeoServerCompositeFilter.java:92)
>
>             at
> org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
>
>             at
> org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
>
>             at
> org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
>
>             at
> org.geoserver.security.GeoServerSecurityFilterChainProxy.doFilter(GeoServerSecurityFilterChainProxy.java:152)
>
>             at
> org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
>
>             at
> org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
>
>             at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
>
>             at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
>
>             at
> org.geoserver.filters.LoggingFilter.doFilter(LoggingFilter.java:87)
>
>             at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
>
>             at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
>
>             at org.geoserver.filters.GZIPFilter.doFilter(GZIPFilter.java:42)
>
>             at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
>
>             at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
>
>             at
> org.geoserver.filters.SessionDebugFilter.doFilter(SessionDebugFilter.java:48)
>
>             at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
>
>             at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
>
>             at
> org.geoserver.filters.FlushSafeFilter.doFilter(FlushSafeFilter.java:44)
>
>             at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
>
>             at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
>
>             at
> org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
>
>             at
> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
>
>             at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
>
>             at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
>
>             at
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
>
>             at
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
>
>             at
> org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
>
>             at
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
>
>             at
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
>
>             at
> org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
>
>             at
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
>
>             at
> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522)
>
>             at
> org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095)
>
>             at
> org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672)
>
>             at
> org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1504)
>
>             at
> org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1460)
>
>             at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
>
>             at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
>
>             at
> org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
>
>             at java.lang.Thread.run(Thread.java:748)
>
> 2018-01-04 15:16:05,661 DEBUG [auth.GeoFenceAuthenticationProvider] - Auth
> request with
> org.springframework.security.authentication.UsernamePasswordAuthenticationToken at f33db8a7:
> Principal: testuser; Credentials: [PROTECTED]; Authenticated: false;
> Details:
> org.geoserver.security.filter.GeoServerWebAuthenticationDetails at 957e:
> RemoteIpAddress: 127.0.0.1; SessionId: null; Not granted any authorities
>
> 2018-01-04 15:16:05,661 DEBUG [geofence.cache] - Loading user 'testuser'
>
> 2018-01-04 15:16:05,666 WARN [geofence.cache] -
> org.geoserver.geofence.cache.CachedRuleReader$NoAuthException: Can't auth
> user [testuser]
>
> 2018-01-04 15:16:05,670 INFO [auth.GeoFenceAuthenticationProvider] - User
> testuser NOT authenticated
>
>
>
> Now I think this is because the filter chain for the /** is configured as:
>
>
>
> basic
>
> geonode-oauth2
>
>
>
> So it is doing the first basic filter and failing because this checks
> against geoserver users and I provided a geonode user. My understanding of
> these filters is that upon failure it should progress to the next one, in
> this case the geonode-oauth2 filter which will call into geonode and
> authenticate the user. So my first question is why isn’t that happening?
>
>
>
> If I update the order of the default /** filter to place geonode-oauth2
> first I get a capabilities document returned but it does not contain the
> layer that I have granted access to for the geonode user, the geoserver logs
> show the following:
>
>
>
> 2018-01-04 15:21:52,163 DEBUG
> [security.IncludeQueryStringAntPathRequestMatcher] - Request matched by
> universal pattern '/**'
>
> 2018-01-04 15:21:52,163 DEBUG
> [security.IncludeQueryStringAntPathRequestMatcher] - Matched Path:
> /geonode/wms, QueryString: request=getcapabilities with /**
>
> 2018-01-04 15:21:52,226 DEBUG [geoserver.security] - Inspecting the http
> request looking for the GeoNode Session ID.
>
> 2018-01-04 15:21:52,226 DEBUG [geoserver.security] - Found no cookies!
>
> 2018-01-04 15:21:52,226 DEBUG [geoserver.security] -
> preAuthenticatedPrincipal = null, trying to authenticate
>
> 2018-01-04 15:21:52,227 DEBUG [geoserver.geofence] - Getting access limits
> for workspace geonode
>
> 2018-01-04 15:21:52,227 DEBUG [geoserver.geofence] - Getting admin auth for
> Workspace geonode
>
> 2018-01-04 15:21:52,227 DEBUG [geoserver.geofence] - AdminAuth filter:
> RuleFilter[user:(empty)+ role:ANY inst:name+:default-gs ip:"10.0.2.2"+
> serv:ANY req:ANY ws:"geonode"+ layer:ANY]
>
> 2018-01-04 15:21:52,227 DEBUG [geofence.cache] - AdminAuth Request for
> RuleFilter[user:(empty)+ role:ANY inst:name+:default-gs ip:"10.0.2.2"+
> serv:ANY req:ANY ws:"geonode"+ layer:ANY]
>
> 2018-01-04 15:21:52,228 DEBUG [geofence.cache] - Loading
> RuleFilter[user:(empty)+ role:ANY inst:name+:default-gs ip:"10.0.2.2"+
> serv:ANY req:ANY ws:"geonode"+ layer:ANY]
>
> 2018-01-04 15:21:52,228 DEBUG [geofence.internal] - Getting Roles for User
> []
>
> 2018-01-04 15:21:52,228 DEBUG [geofence.internal] - Checking
> UserGroupService [default]
>
> 2018-01-04 15:21:52,228 DEBUG [geofence.internal] - Checking RoleService
> [default]
>
> 2018-01-04 15:21:52,228 DEBUG [geofence.internal] - Checking RoleService
> [geonode REST role service]
>
> 2018-01-04 15:21:52,319 DEBUG [geoserver.security] - Setting ROLES for User
> [] to [ROLE_ANONYMOUS]
>
> 2018-01-04 15:21:52,392 DEBUG [geoserver.security] - Setting ROLES for User
> [] to [ROLE_ANONYMOUS]
>
> 2018-01-04 15:21:52,392 DEBUG [geofence.internal] - RoleService [geonode
> REST role service] matching for User []
>
> 2018-01-04 15:21:52,446 DEBUG [geoserver.security] - Setting ROLES for User
> [] to [ROLE_ANONYMOUS]
>
> 2018-01-04 15:21:52,447 DEBUG [geofence.internal] - Checking Role
> [ROLE_ANONYMOUS] on ActiveRoleService
> [org.geoserver.security.GeoServerRestRoleService at 1491bfb5]
>
> 2018-01-04 15:21:52,447 DEBUG [geofence.internal] - Checking
> UserGroupService [default]
>
> 2018-01-04 15:21:52,447 DEBUG [geofence.internal] - Matching Roles
> [[ROLE_ANONYMOUS]] for User []
>
> 2018-01-04 15:21:52,494 DEBUG [geoserver.security] - Setting ROLES for User
> [] to [ROLE_ANONYMOUS]
>
> 2018-01-04 15:21:52,494 DEBUG [geofence.internal] - Checking Role
> [ROLE_ANONYMOUS] on ActiveRoleService
> [org.geoserver.security.GeoServerRestRoleService at 1491bfb5]
>
> 2018-01-04 15:21:52,494 DEBUG [geofence.internal] - Checking
> UserGroupService [default]
>
> 2018-01-04 15:21:52,494 DEBUG [geofence.internal] - Matching Roles
> [[ROLE_ANONYMOUS]] for User []
>
> 2018-01-04 15:21:52,495 DEBUG [geoserver.geofence] - Admin auth for User:
> Workspace:geonode: false
>
>
>
> I think the above is showing that the user failed authentication because the
> RuleFilter for geofence is being passed an empty username, which is why the
> layer isn’t being shown.
>
>
>
> My second question is why didn’t the authentication process throw any
> errors? I’ve taken a look at the GeoServerOAuthAuthenticationFilter class
> (https://github.com/geoserver/geoserver/blob/master/src/community/security/oauth2/src/main/java/org/geoserver/security/oauth2/GeoServerOAuthAuthenticationFilter.java)
> and I wonder whether when it calls this line:
>
>
>
> authentication = filter.attemptAuthentication(req, null);
>
>
>
> it is swallowing any IOException or ServletException that are thrown by the
> base Spring class?
>
>
>
>
>
> I’m also wondering whether I’ve just misunderstood how the security between
> geonode and geoserver should work. My high-level view is that when a geonode
> user requests to access a resource directly via geoserver (for example a WMS
> service) then geoserver will call into geonode to check that the user is
> valid, retrieve the users’ roles and then pass these to geofence which will
> check the data rules to ensure the user has access to the targeted resource.
>
>
>
> Thanks,
> Pete
>
>
>
>
>
> SCISYS UK Limited. Registered in England and Wales No. 4373530.
> Registered Office: Methuen Park, Chippenham, Wiltshire SN14 0GB, UK.
>
> Before printing, please think about the environment.
>
>
> _______________________________________________
> geonode-devel mailing list
> geonode-devel at lists.osgeo.org
> https://lists.osgeo.org/mailman/listinfo/geonode-devel
>



-- 
Paolo Corti
Geospatial software developer
web: http://www.paolocorti.net
twitter: @capooti
skype: capooti


More information about the geonode-devel mailing list