I am fairly new to Geoserver REST API and security settings, so please excuse me if I am missing the absolute obvious here. I am running Geoserver 2.11.2 running on Tomcat 7 on a Win7 64bit system. I have written a web client to manipulate styles via REST API to enable users without admin rights to edit/upload styles.
Basically I'm using jquery $.ajax-Functions to HTTP GET a template style from Geoserver, edit it locally and upload it via HTTP PUT or create new one via HTTP POST. Base URL is
http://ip:8080/geoserver/rest/styles/style_name
Using the default settings in file rest.properties ($geoserver_home/data/security) everything works as intended when using admin credentials after authentication is prompted (Status Code 200 OK). Style is being fetched/edited/created successfully. Default ANT patterns in rest.properties:
/**;GET=ADMIN
/**;POST,DELETE,PUT=ADMIN
I then introduced a new user called 'chief' and assigned two new roles called ROLE_REST_READ and ROLE_REST_WRITE to it. Following the Geoserver docs for changing REST security I changed rest.properties to:
/**;GET=ROLE_REST_READ
/**;POST,DELETE,PUT=ROLE_REST_WRITE
Now when entering the new 'chief' credentials when prompted, the same HTTP PUT results in
Status Code: 405 Method not allowed
[...]
Response Headers Allow: DELETE,GET
and the same HTTP POST results in
Status Code: 405 Method not allowed
[...]
Response Headers Allow: GET
However HTTP GET still works as before. I then tried to changed the ANT pattern to
/rest/**;GET=ROLE_REST_READ
/rest/**;POST,PUT,DELETE=ROLE_REST_WRITE
with no effect.
Geoserver Logs (debug mode) for HTTP GET (still successful)
2017-09-18 11:38:22,796 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/styleTemplate.sld, QueryString: null'; against '/web/**'
2017-09-18 11:38:22,796 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/styleTemplate.sld, QueryString: null'; against '/gwc/rest/web/**'
2017-09-18 11:38:22,796 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/styleTemplate.sld, QueryString: null'; against '/'
2017-09-18 11:38:22,796 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/styleTemplate.sld, QueryString: null'; against '/j_spring_security_check'
2017-09-18 11:38:22,796 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/styleTemplate.sld, QueryString: null'; against '/j_spring_security_check/'
2017-09-18 11:38:22,796 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/styleTemplate.sld, QueryString: null'; against '/j_spring_security_logout'
2017-09-18 11:38:22,796 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/styleTemplate.sld, QueryString: null'; against '/j_spring_security_logout/'
2017-09-18 11:38:22,796 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/styleTemplate.sld, QueryString: null'; against '/rest/**'
2017-09-18 11:38:22,800 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Matched Path: /rest/styles/styleTemplate.sld, QueryString: null with /rest/**
2017-09-18 11:38:22,801 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - Converted URL to lowercase, from: '/rest/styles/styleTemplate.sld'; to: '/rest/styles/styleTemplate.sld' and httpMethod= GET
2017-09-18 11:38:22,801 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - ~~~~~~~~~~ antPath= /** methodList= [GET]
2017-09-18 11:38:22,801 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - Candidate is: '/rest/styles/styleTemplate.sld'; antPath is /**; matchedPath=true; matchedMethods=true
2017-09-18 11:38:22,801 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - returning ROLE_REST_READ
2017-09-18 11:38:22,802 DEBUG [org.geoserver.security.filter.GeoServerSecurityContextPersistenceFilter$1] - SecurityContextHolder now cleared, as request processing completed
2017-09-18 11:38:30,457 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/styleTemplate.sld, QueryString: null'; against '/web/**'
2017-09-18 11:38:30,457 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/styleTemplate.sld, QueryString: null'; against '/gwc/rest/web/**'
2017-09-18 11:38:30,457 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/styleTemplate.sld, QueryString: null'; against '/'
2017-09-18 11:38:30,457 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/styleTemplate.sld, QueryString: null'; against '/j_spring_security_check'
2017-09-18 11:38:30,457 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/styleTemplate.sld, QueryString: null'; against '/j_spring_security_check/'
2017-09-18 11:38:30,457 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/styleTemplate.sld, QueryString: null'; against '/j_spring_security_logout'
2017-09-18 11:38:30,457 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/styleTemplate.sld, QueryString: null'; against '/j_spring_security_logout/'
2017-09-18 11:38:30,457 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/styleTemplate.sld, QueryString: null'; against '/rest/**'
2017-09-18 11:38:30,457 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Matched Path: /rest/styles/styleTemplate.sld, QueryString: null with /rest/**
2017-09-18 11:38:30,457 DEBUG [org.geoserver.security] - AuthenticationCache has no entry for basic, chief:6c4820b1f41dbfffe754a886365ef4b2
2017-09-18 11:38:30,552 DEBUG [org.geoserver.security.rememberme.GeoServerTokenBasedRememberMeServices] - Did not send remember-me cookie (principal did not set parameter '_spring_security_remember_me')
2017-09-18 11:38:30,552 DEBUG [org.geoserver.security.rememberme.GeoServerTokenBasedRememberMeServices] - Remember-me login not requested.
2017-09-18 11:38:30,552 DEBUG [org.geoserver.security] - AuthenticationCache adding new entry for basic, chief:6c4820b1f41dbfffe754a886365ef4b2
2017-09-18 11:38:30,552 DEBUG [org.geoserver.security] - Cache entries #: 0
2017-09-18 11:38:30,552 DEBUG [org.geoserver.security] - AuthenticationCache added new entry for basic, chief:6c4820b1f41dbfffe754a886365ef4b2
2017-09-18 11:38:30,552 DEBUG [org.geoserver.security] - Cache entries #: 1
2017-09-18 11:38:30,553 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - Converted URL to lowercase, from: '/rest/styles/styleTemplate.sld'; to: '/rest/styles/styleTemplate.sld' and httpMethod= GET
2017-09-18 11:38:30,553 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - ~~~~~~~~~~ antPath= /** methodList= [GET]
2017-09-18 11:38:30,553 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - Candidate is: '/rest/styles/styleTemplate.sld'; antPath is /**; matchedPath=true; matchedMethods=true
2017-09-18 11:38:30,553 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - returning ROLE_REST_READ
2017-09-18 11:38:30,553 DEBUG [org.geoserver.ows] - Could not a layer group named rest
2017-09-18 11:38:30,553 TRACE [org.geoserver.ows.OWSHandlerMapping] - No handler mapping found for [/rest/styles/styleTemplate.sld]
2017-09-18 11:38:30,553 DEBUG [org.geoserver.ows] - Could not a layer group named rest
2017-09-18 11:38:30,553 TRACE [org.geoserver.ows.OWSHandlerMapping] - No handler mapping found for [/rest/styles/styleTemplate.sld]
2017-09-18 11:38:30,553 DEBUG [org.geoserver.ows] - Could not a layer group named rest
2017-09-18 11:38:30,553 TRACE [org.geoserver.ows.OWSHandlerMapping] - No handler mapping found for [/rest/styles/styleTemplate.sld]
2017-09-18 11:38:30,554 DEBUG [org.geoserver] - Thread 56 locking in mode READ
2017-09-18 11:38:30,554 DEBUG [org.geoserver] - Thread 56 got the lock in mode READ
2017-09-18 11:38:30,592 DEBUG [org.geoserver.catalog.rest] - GET style styleTemplate
2017-09-18 11:38:30,592 DEBUG [org.geoserver] - Thread 56 locking in mode READ
2017-09-18 11:38:30,592 DEBUG [org.geoserver] - Thread 56 releasing the lock in mode READ
2017-09-18 11:38:30,592 DEBUG [org.geoserver.filters] - Compressing output for mimetype: application/vnd.ogc.sld+xml
2017-09-18 11:38:30,593 DEBUG [org.geoserver.security.filter.GeoServerSecurityContextPersistenceFilter$1] - SecurityContextHolder now cleared, as request processing completed
Geoserver Logs (debug mode) for HTTP PUT/POST (unsuccessful)
2017-09-18 11:38:30,608 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/stylename, QueryString: null'; against '/web/**'
2017-09-18 11:38:30,608 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/stylename, QueryString: null'; against '/gwc/rest/web/**'
2017-09-18 11:38:30,608 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/stylename, QueryString: null'; against '/'
2017-09-18 11:38:30,608 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/stylename, QueryString: null'; against '/j_spring_security_check'
2017-09-18 11:38:30,608 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/stylename, QueryString: null'; against '/j_spring_security_check/'
2017-09-18 11:38:30,608 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/stylename, QueryString: null'; against '/j_spring_security_logout'
2017-09-18 11:38:30,608 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/stylename, QueryString: null'; against '/j_spring_security_logout/'
2017-09-18 11:38:30,608 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles/stylename, QueryString: null'; against '/rest/**'
2017-09-18 11:38:30,608 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Matched Path: /rest/styles/stylename, QueryString: null with /rest/**
2017-09-18 11:38:30,608 DEBUG [org.geoserver.security] - AuthenticationCache found an entry for basic, chief:6c4820b1f41dbfffe754a886365ef4b2
2017-09-18 11:38:30,609 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - Converted URL to lowercase, from: '/rest/styles/stylename'; to: '/rest/styles/stylename' and httpMethod= PUT
2017-09-18 11:38:30,609 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - ~~~~~~~~~~ antPath= /** methodList= [GET]
2017-09-18 11:38:30,609 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - Candidate is: '/rest/styles/stylename'; antPath is /**; matchedPath=true; matchedMethods=false
2017-09-18 11:38:30,609 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - ~~~~~~~~~~ antPath= /** methodList= [POST, DELETE, PUT]
2017-09-18 11:38:30,609 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - Candidate is: '/rest/styles/stylename'; antPath is /**; matchedPath=true; matchedMethods=true
2017-09-18 11:38:30,609 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - returning ROLE_REST_WRITE
2017-09-18 11:38:30,609 DEBUG [org.geoserver.ows] - Could not a layer group named rest
2017-09-18 11:38:30,609 TRACE [org.geoserver.ows.OWSHandlerMapping] - No handler mapping found for [/rest/styles/stylename]
2017-09-18 11:38:30,609 DEBUG [org.geoserver.ows] - Could not a layer group named rest
2017-09-18 11:38:30,609 TRACE [org.geoserver.ows.OWSHandlerMapping] - No handler mapping found for [/rest/styles/stylename]
2017-09-18 11:38:30,609 DEBUG [org.geoserver.ows] - Could not a layer group named rest
2017-09-18 11:38:30,609 TRACE [org.geoserver.ows.OWSHandlerMapping] - No handler mapping found for [/rest/styles/stylename]
2017-09-18 11:38:30,610 DEBUG [org.geoserver] - Thread 56 locking in mode WRITE
2017-09-18 11:38:30,610 DEBUG [org.geoserver] - Thread 56 got the lock in mode WRITE
2017-09-18 11:38:30,611 DEBUG [org.geoserver] - Thread 56 locking in mode WRITE
2017-09-18 11:38:30,611 DEBUG [org.geoserver] - Thread 56 releasing the lock in mode WRITE
2017-09-18 11:38:30,611 DEBUG [org.geoserver.security.filter.GeoServerSecurityContextPersistenceFilter$1] - SecurityContextHolder now cleared, as request processing completed
2017-09-18 11:38:30,623 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles, QueryString: null'; against '/web/**'
2017-09-18 11:38:30,623 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles, QueryString: null'; against '/gwc/rest/web/**'
2017-09-18 11:38:30,623 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles, QueryString: null'; against '/'
2017-09-18 11:38:30,623 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles, QueryString: null'; against '/j_spring_security_check'
2017-09-18 11:38:30,623 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles, QueryString: null'; against '/j_spring_security_check/'
2017-09-18 11:38:30,623 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles, QueryString: null'; against '/j_spring_security_logout'
2017-09-18 11:38:30,623 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles, QueryString: null'; against '/j_spring_security_logout/'
2017-09-18 11:38:30,623 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles, QueryString: null'; against '/rest/**'
2017-09-18 11:38:30,623 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Matched Path: /rest/styles, QueryString: null with /rest/**
2017-09-18 11:38:30,623 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - Converted URL to lowercase, from: '/rest/styles'; to: '/rest/styles' and httpMethod= POST
2017-09-18 11:38:30,623 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - ~~~~~~~~~~ antPath= /** methodList= [GET]
2017-09-18 11:38:30,623 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - Candidate is: '/rest/styles'; antPath is /**; matchedPath=true; matchedMethods=false
2017-09-18 11:38:30,623 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - ~~~~~~~~~~ antPath= /** methodList= [POST, DELETE, PUT]
2017-09-18 11:38:30,623 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - Candidate is: '/rest/styles'; antPath is /**; matchedPath=true; matchedMethods=true
2017-09-18 11:38:30,623 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - returning ROLE_REST_WRITE
2017-09-18 11:38:30,624 DEBUG [org.geoserver.security.filter.GeoServerSecurityContextPersistenceFilter$1] - SecurityContextHolder now cleared, as request processing completed
2017-09-18 11:38:30,625 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles, QueryString: null'; against '/web/**'
2017-09-18 11:38:30,625 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles, QueryString: null'; against '/gwc/rest/web/**'
2017-09-18 11:38:30,625 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles, QueryString: null'; against '/'
2017-09-18 11:38:30,625 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles, QueryString: null'; against '/j_spring_security_check'
2017-09-18 11:38:30,625 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles, QueryString: null'; against '/j_spring_security_check/'
2017-09-18 11:38:30,625 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles, QueryString: null'; against '/j_spring_security_logout'
2017-09-18 11:38:30,625 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles, QueryString: null'; against '/j_spring_security_logout/'
2017-09-18 11:38:30,626 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Checking match of request : 'Path: /rest/styles, QueryString: null'; against '/rest/**'
2017-09-18 11:38:30,626 DEBUG [org.geoserver.security.IncludeQueryStringAntPathRequestMatcher] - Matched Path: /rest/styles, QueryString: null with /rest/**
2017-09-18 11:38:30,627 DEBUG [org.geoserver.security] - AuthenticationCache found an entry for basic, chief:6c4820b1f41dbfffe754a886365ef4b2
2017-09-18 11:38:30,627 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - Converted URL to lowercase, from: '/rest/styles'; to: '/rest/styles' and httpMethod= POST
2017-09-18 11:38:30,627 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - ~~~~~~~~~~ antPath= /** methodList= [GET]
2017-09-18 11:38:30,627 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - Candidate is: '/rest/styles'; antPath is /**; matchedPath=true; matchedMethods=false
2017-09-18 11:38:30,627 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - ~~~~~~~~~~ antPath= /** methodList= [POST, DELETE, PUT]
2017-09-18 11:38:30,627 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - Candidate is: '/rest/styles'; antPath is /**; matchedPath=true; matchedMethods=true
2017-09-18 11:38:30,627 DEBUG [org.geoserver.security.RESTfulPathBasedFilterInvocationDefinitionMap] - returning ROLE_REST_WRITE
2017-09-18 11:38:30,627 DEBUG [org.geoserver.ows] - Could not a layer group named rest
2017-09-18 11:38:30,627 TRACE [org.geoserver.ows.OWSHandlerMapping] - No handler mapping found for [/rest/styles]
2017-09-18 11:38:30,627 DEBUG [org.geoserver.ows] - Could not a layer group named rest
2017-09-18 11:38:30,627 TRACE [org.geoserver.ows.OWSHandlerMapping] - No handler mapping found for [/rest/styles]
2017-09-18 11:38:30,627 DEBUG [org.geoserver.ows] - Could not a layer group named rest
2017-09-18 11:38:30,627 TRACE [org.geoserver.ows.OWSHandlerMapping] - No handler mapping found for [/rest/styles]
2017-09-18 11:38:30,628 DEBUG [org.geoserver] - Thread 56 locking in mode WRITE
2017-09-18 11:38:30,628 DEBUG [org.geoserver] - Thread 56 got the lock in mode WRITE
2017-09-18 11:38:30,629 DEBUG [org.geoserver] - Thread 56 locking in mode WRITE
2017-09-18 11:38:30,629 DEBUG [org.geoserver] - Thread 56 releasing the lock in mode WRITE
2017-09-18 11:38:30,629 DEBUG [org.geoserver.security.filter.GeoServerSecurityContextPersistenceFilter$1] - SecurityContextHolder now cleared, as request processing completed
From what I can see the Logs of a successful PUT/POST attempt using admin credentials do not differ in any way regarding the REST function outputs. What is it I am missing here? Does the user really needs to be assigned an admin role? Is there maybe something wrong with my authentication chain?