Skip to content

Commit 1d03a2f

Browse files
authored
Merge pull request #11454 from GlobalDataverseCommunityConsortium/FilterUpdates
Filter Improvements
2 parents bb99c1a + 5643f51 commit 1d03a2f

File tree

15 files changed

+599
-259
lines changed

15 files changed

+599
-259
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
### Improved efficiency for per-request Filters
2+
3+
This release improves the performance of Dataverse's per-request handling of CORS Headers and API calls
4+
5+
It adds new jvm-options/Microprofile settings replacing the now deprecated database settings.
6+
7+
Additional changes:
8+
9+
- CORS headers can now be configured with a list of desired origins, methods, and allowed and exposed headers.
10+
- An 'X-Dataverse-unblock-key' header has been added that can be used instead of the less secure 'unblock-key' query parameter when the :BlockedApiPolicy is set to 'unblock-key'
11+
- Warnings have been added to the log if the Blocked Api settings are misconfigured or if the key is weak (when the "unblock-key" policy is used)
12+
- The new `dataverse.api.blocked.key` can be configured using Payara password aliases or other secure storage options.
13+
14+
New JvmSettings:
15+
- `dataverse.cors.origin`: Allowed origins for CORS requests
16+
- `dataverse.cors.methods`: Allowed HTTP methods for CORS requests
17+
- `dataverse.cors.headers.allow`: Allowed headers for CORS requests
18+
- `dataverse.cors.headers.expose`: Headers to expose in CORS responses
19+
- `dataverse.api.blocked.policy`: Policy for blocking API endpoints
20+
- `dataverse.api.blocked.endpoints`: List of API endpoints to be blocked (comma-separated)
21+
- `dataverse.api.blocked.key`: Key for unblocking API endpoints
22+
23+
Deprecated database settings:
24+
- `:AllowCors`
25+
- `:BlockedApiPolicy`
26+
- `:BlockedApiEndpoints`
27+
- `:BlockedApiKey`
28+
29+
30+
Upgrade instructions:
31+
32+
The deprecated database settings will continue to work in this version. To use the new settings (which are more efficient),
33+
34+
If :AllowCors is not set or is true:
35+
bin/asadmin create-jvm-options -Ddataverse.cors.origin=*
36+
37+
Optionally set origin to a list of hosts and/or set other CORS JvmSettings
38+
Your currently blocked API endpoints can be found at http://localhost:8080/api/admin/settings/:BlockedApiEndpoints
39+
40+
Copy them into the new setting with the following command. As with the deprecated setting, the endpoints should be comma-separated.
41+
42+
bin/asadmin create-jvm-options '-Ddataverse.api.blocked.endpoints=<current :BlockedApiEndpoints>'
43+
44+
If :BlockedApiPolicy is set and is not 'drop'
45+
bin/asadmin create-jvm-options '-Ddataverse.api.blocked.policy=<current :BlockedApiPolicy>'
46+
47+
If :BlockedApiPolicy is 'unblock-key' and :BlockedApiKey is set
48+
49+
`echo "API_BLOCKED_KEY_ALIAS=<value of :BlockedApiKey>" > /tmp/dataverse.api.blocked.key.txt`
50+
51+
`sudo -u dataverse /usr/local/payara6/bin/asadmin create-password-alias --passwordfile /tmp/dataverse.api.blocked.key.txt`
52+
53+
When you are prompted "Enter the value for the aliasname operand", enter `api_blocked_key_alias`
54+
55+
You should see "Command create-password-alias executed successfully."
56+
57+
bin/asadmin create-jvm-options '-Ddataverse.api.blocked.key=${ALIAS=api_blocked_key_alias}'
58+
59+
Restart Payara:
60+
61+
service payara restart
62+
63+
Check server.log to verify that your new settings are in effect.
64+
65+
Cleanup: delete deprecated settings:
66+
curl -X DELETE http://localhost:8080/api/admin/settings/:AllowCors
67+
curl -X DELETE http://localhost:8080/api/admin/settings/:BlockedApiEndpoints
68+
curl -X DELETE http://localhost:8080/api/admin/settings/:BlockedApiPolicy
69+
curl -X DELETE http://localhost:8080/api/admin/settings/:BlockedApiKey
70+

doc/sphinx-guides/source/installation/config.rst

Lines changed: 181 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,47 @@ The default password for the "dataverseAdmin" superuser account is "admin", as m
2525
Blocking API Endpoints
2626
++++++++++++++++++++++
2727

28-
The :doc:`/api/native-api` contains a useful but potentially dangerous API endpoint called "admin" that allows you to change system settings, make ordinary users into superusers, and more. The "builtin-users" endpoint lets admins create a local/builtin user account if they know the key defined in :ref:`BuiltinUsers.KEY`.
28+
The :doc:`/api/native-api` contains a useful but potentially dangerous set of API endpoints called "admin" that allows you to change system settings, make ordinary users into superusers, and more. The "builtin-users" endpoints let admins do tasks such as creating a local/builtin user account if they know the key defined in :ref:`BuiltinUsers.KEY`.
2929

30-
By default, most APIs can be operated on remotely and a number of endpoints do not require authentication. The endpoints "admin" and "builtin-users" are limited to localhost out of the box by the settings :ref:`:BlockedApiEndpoints` and :ref:`:BlockedApiPolicy`.
30+
By default in the code, most of these API endpoints can be operated on remotely and a number of endpoints do not require authentication. However, the endpoints "admin" and "builtin-users" are limited to localhost out of the box by the installer, using the JvmSettings :ref:`dataverse.api.blocked.endpoints` and :ref:`dataverse.api.blocked.policy`.
3131

32-
It is very important to keep the block in place for the "admin" endpoint, and to leave the "builtin-users" endpoint blocked unless you need to access it remotely. Documentation for the "admin" endpoint is spread across the :doc:`/api/native-api` section of the API Guide and the :doc:`/admin/index`.
32+
.. note::
33+
The database settings :ref:`:BlockedApiEndpoints` and :ref:`:BlockedApiPolicy` are deprecated and will be removed in a future version. Please use the JvmSettings mentioned above instead.
3334

34-
It's also possible to prevent file uploads via API by adjusting the :ref:`:UploadMethods` database setting.
35+
It is **very important** to keep the block in place for the "admin" endpoint, and to leave the "builtin-users" endpoint blocked unless you need to access it remotely. Documentation for the "admin" endpoint is spread across the :doc:`/api/native-api` section of the API Guide and the :doc:`/admin/index`.
3536

37+
Given how important it is to avoid exposing the "admin" and "builtin-user" APIs, sites using a proxy, e.g. Apache or Nginx, should also consider blocking them through rules in the proxy.
38+
The following examples may be useful:
39+
40+
Apache/Httpd Rule:
41+
42+
Rewrite lines added to /etc/httpd/conf.d/ssl.conf. They can be the first lines inserted after the RewriteEngine On statement:
43+
44+
.. code-block:: apache
45+
46+
RewriteRule ^/api/(admin|builtin-users) - [R=403,L]
47+
RewriteRule ^/api/(v[0-9]*)/(admin|builtin-users) - [R=403,L]
48+
49+
Nginx Configuration Rule:
50+
51+
.. code-block:: nginx
52+
53+
location ~ ^/api/(admin|v1/admin|builtin-users|v1/builtin-users) {
54+
deny all;
55+
return 403;
56+
}
57+
3658
If you are using a load balancer or a reverse proxy, there are some additional considerations. If no additional configurations are made and the upstream is configured to redirect to localhost, the API will be accessible from the outside, as your installation will register as origin the localhost for any requests to the endpoints "admin" and "builtin-users". To prevent this, you have two options:
3759

3860
- If your upstream is configured to redirect to localhost, you will need to set the :ref:`JVM option <useripaddresssourceheader>` to one of the following values ``%client.name% %datetime% %request% %status% %response.length% %header.referer% %header.x-forwarded-for%`` and configure from the load balancer side the chosen header to populate with the client IP address.
3961

4062
- Another solution is to set the upstream to the client IP address. In this case no further configuration is needed.
4163

64+
For more information on configuring blocked API endpoints, see :ref:`dataverse.api.blocked.endpoints` and :ref:`dataverse.api.blocked.policy` in the JvmSettings documentation.
65+
66+
.. note::
67+
It's also possible to prevent file uploads via API by adjusting the :ref:`:UploadMethods` database setting.
68+
4269
Forcing HTTPS
4370
+++++++++++++
4471

@@ -3153,6 +3180,64 @@ Defaults to ``false``.
31533180
Can also be set via any `supported MicroProfile Config API source`_, e.g. the environment variable
31543181
``DATAVERSE_API_ALLOW_INCOMPLETE_METADATA``. Will accept ``[tT][rR][uU][eE]|1|[oO][nN]`` as "true" expressions.
31553182

3183+
.. _dataverse.api.blocked.endpoints:
3184+
3185+
dataverse.api.blocked.endpoints
3186+
+++++++++++++++++++++++++++++++
3187+
3188+
A comma-separated list of API endpoints that should be blocked. A minimal example that blocks endpoints for security reasons:
3189+
3190+
``./asadmin create-jvm-options '-Ddataverse.api.blocked.endpoints=api/admin,api/builtin-users'``
3191+
3192+
Another example:
3193+
3194+
``./asadmin create-jvm-options '-Ddataverse.api.blocked.endpoints=api/admin,api/builtin-users,api/datasets/:persistentId/versions/:versionId/files,api/files/:id'``
3195+
3196+
Defaults to an empty string (no endpoints blocked), but, in almost all cases, should include at least ``admin, builtin-users`` as a security measure.
3197+
3198+
For more information on API blocking, see :ref:`blocking-api-endpoints` in the Admin Guide.
3199+
3200+
Can also be set via any `supported MicroProfile Config API source`_, e.g. the environment variable ``DATAVERSE_API_BLOCKED_ENDPOINTS``.
3201+
3202+
.. _dataverse.api.blocked.policy:
3203+
3204+
dataverse.api.blocked.policy
3205+
++++++++++++++++++++++++++++
3206+
3207+
Specifies how to treat blocked API endpoints. Valid values are:
3208+
3209+
- ``drop``: Blocked requests are dropped (default).
3210+
- ``localhost-only``: Blocked requests are only allowed from localhost.
3211+
- ``unblock-key``: Blocked requests are allowed if they include a valid unblock key.
3212+
3213+
For example:
3214+
3215+
``./asadmin create-jvm-options '-Ddataverse.api.blocked.policy=localhost-only'``
3216+
3217+
Can also be set via any `supported MicroProfile Config API source`_, e.g. the environment variable ``DATAVERSE_API_BLOCKED_POLICY``.
3218+
3219+
.. note::
3220+
This setting will be ignored unless the :ref:`dataverse.api.blocked.endpoints` and, for the unblock-key policy, the :ref:`dataverse.api.blocked.key` are also set. Otherwise the deprecated :ref:`:BlockedApiPolicy` will be used
3221+
3222+
.. _dataverse.api.blocked.key:
3223+
3224+
dataverse.api.blocked.key
3225+
+++++++++++++++++++++++++
3226+
3227+
When the blocked API policy is set to ``unblock-key``, this setting specifies the key that allows access to blocked endpoints. For example:
3228+
3229+
``./asadmin create-jvm-options '-Ddataverse.api.blocked.key=your-secret-key-here'``
3230+
3231+
**WARNING**:
3232+
*Since the blocked API key is sensitive, you should treat it like a password.*
3233+
*See* :ref:`secure-password-storage` *to learn about ways to safeguard it.*
3234+
3235+
Can also be set via any `supported MicroProfile Config API source`_, e.g. the environment variable ``DATAVERSE_API_BLOCKED_KEY`` (although you shouldn't use environment variables for sensitive information).
3236+
3237+
.. note::
3238+
This setting will be ignored unless the :ref:`dataverse.api.blocked.policy` is set to ``unblock-key``. Otherwise the deprecated :ref:`:BlockedApiKey` will be used
3239+
3240+
31563241
.. _dataverse.ui.show-validity-label-when-published:
31573242

31583243
dataverse.ui.show-validity-label-when-published
@@ -3481,6 +3566,70 @@ This setting allows admins to highlight a few of the 1000+ CSL citation styles a
34813566
These will be listed above the alphabetical list of all styles in the "View Styled Citations" pop-up.
34823567
The default value when not set is "chicago-author-date, ieee".
34833568

3569+
.. _dataverse.cors:
3570+
3571+
CORS Settings
3572+
-------------
3573+
3574+
The following settings control Cross-Origin Resource Sharing (CORS) for your Dataverse installation.
3575+
3576+
.. _dataverse.cors.origin:
3577+
3578+
dataverse.cors.origin
3579+
+++++++++++++++++++++
3580+
3581+
Allowed origins for CORS requests. The default with no value set is to not include CORS headers. However, if the deprecated :AllowCors setting is explicitly set to true the default is "\*" (all origins).
3582+
When the :AllowsCors setting is not used, you must set this setting to "\*" or a list of origins to enable CORS headers.
3583+
3584+
Multiple origins can be specified as a comma-separated list.
3585+
3586+
Example:
3587+
3588+
``./asadmin create-jvm-options '-Ddataverse.cors.origin=https://example.com,https://subdomain.example.com'``
3589+
3590+
Can also be set via any `supported MicroProfile Config API source`_, e.g. the environment variable ``DATAVERSE_CORS_ORIGIN``.
3591+
3592+
.. _dataverse.cors.methods:
3593+
3594+
dataverse.cors.methods
3595+
++++++++++++++++++++++
3596+
3597+
Allowed HTTP methods for CORS requests. The default when this setting is missing is "GET,POST,OPTIONS,PUT,DELETE".
3598+
Multiple methods can be specified as a comma-separated list.
3599+
3600+
Example:
3601+
3602+
``./asadmin create-jvm-options '-Ddataverse.cors.methods=GET,POST,OPTIONS'``
3603+
3604+
Can also be set via any `supported MicroProfile Config API source`_, e.g. the environment variable ``DATAVERSE_CORS_METHODS``.
3605+
3606+
.. _dataverse.cors.headers.allow:
3607+
3608+
dataverse.cors.headers.allow
3609+
++++++++++++++++++++++++++++
3610+
3611+
Allowed headers for CORS requests. The default when this setting is missing is "Accept,Content-Type,X-Dataverse-key,Range".
3612+
Multiple headers can be specified as a comma-separated list.
3613+
3614+
Example:
3615+
3616+
``./asadmin create-jvm-options '-Ddataverse.cors.headers.allow=Accept,Content-Type,X-Custom-Header'``
3617+
3618+
Can also be set via any `supported MicroProfile Config API source`_, e.g. the environment variable ``DATAVERSE_CORS_HEADERS_ALLOW``.
3619+
3620+
.. _dataverse.cors.headers.expose:
3621+
3622+
dataverse.cors.headers.expose
3623+
+++++++++++++++++++++++++++++
3624+
3625+
Headers to expose in CORS responses. The default when this setting is missing is "Accept-Ranges,Content-Range,Content-Encoding".
3626+
Multiple headers can be specified as a comma-separated list.
3627+
3628+
Example:
3629+
3630+
``./asadmin create-jvm-options '-Ddataverse.cors.headers.expose=Accept-Ranges,Content-Range,X-Custom-Header'``
3631+
3632+
Can also be set via any `supported MicroProfile Config API source`_, e.g. the environment variable ``DATAVERSE_CORS_HEADERS_EXPOSE``.
34843633

34853634
.. _feature-flags:
34863635

@@ -3614,8 +3763,11 @@ The pattern you will observe in curl examples below is that an HTTP ``PUT`` is u
36143763

36153764
.. _:BlockedApiPolicy:
36163765

3617-
:BlockedApiPolicy
3618-
+++++++++++++++++
3766+
:BlockedApiPolicy (Deprecated)
3767+
++++++++++++++++++++++++++++++
3768+
3769+
.. note::
3770+
This setting is deprecated. Please use the JvmSetting :ref:`dataverse.api.blocked.policy` instead. This legacy setting will only be used if the newer JvmSettings are not set.
36193771

36203772
``:BlockedApiPolicy`` affects access to the list of API endpoints defined in :ref:`:BlockedApiEndpoints`.
36213773

@@ -3631,8 +3783,11 @@ Below is an example of setting ``localhost-only``.
36313783

36323784
.. _:BlockedApiEndpoints:
36333785

3634-
:BlockedApiEndpoints
3635-
++++++++++++++++++++
3786+
:BlockedApiEndpoints (Deprecated)
3787+
+++++++++++++++++++++++++++++++++
3788+
3789+
.. note::
3790+
This setting is deprecated. Please use the JvmSetting :ref:`dataverse.api.blocked.endpoints` instead. This legacy setting will only be used if the newer JvmSettings are not set.
36363791

36373792
A comma-separated list of API endpoints to be blocked. For a standard production installation, the installer blocks both "admin" and "builtin-users" by default per the security section above:
36383793

@@ -3642,16 +3797,21 @@ See the :ref:`list-of-dataverse-apis` for lists of API endpoints.
36423797

36433798
.. _:BlockedApiKey:
36443799

3645-
:BlockedApiKey
3646-
++++++++++++++
3800+
:BlockedApiKey (Deprecated)
3801+
+++++++++++++++++++++++++++
3802+
3803+
.. note::
3804+
This setting is deprecated. Please use the JvmSetting :ref:`dataverse.api.blocked.key` instead. This legacy setting will only be used if the newer JvmSettings are not set.
36473805

36483806
``:BlockedApiKey`` is used in conjunction with :ref:`:BlockedApiEndpoints` and :ref:`:BlockedApiPolicy` and will not be enabled unless the policy is set to ``unblock-key`` as demonstrated below. Please note that the order is significant. You should set ``:BlockedApiKey`` first to prevent locking yourself out.
36493807

36503808
``curl -X PUT -d s3kretKey http://localhost:8080/api/admin/settings/:BlockedApiKey``
36513809

36523810
``curl -X PUT -d unblock-key http://localhost:8080/api/admin/settings/:BlockedApiPolicy``
36533811

3654-
Now that ``:BlockedApiKey`` has been enabled, blocked APIs can be accessed using the query parameter ``unblock-key=theKeyYouChose`` as in the example below.
3812+
Now that ``:BlockedApiKey`` has been enabled, blocked APIs can be accessed using the header ``X-Dataverse-unblock-key: theKeyYouChoose`` or, less securely, the query parameter ``unblock-key=theKeyYouChose`` as in the examples below.
3813+
3814+
``curl -H 'X-Dataverse-unblock-key:theKeyYouChoose' https://demo.dataverse.org/api/admin/settings``
36553815

36563816
``curl https://demo.dataverse.org/api/admin/settings?unblock-key=theKeyYouChose``
36573817

@@ -4665,14 +4825,19 @@ This can be helpful in situations where multiple organizations are sharing one D
46654825
or
46664826
``curl -X PUT -d '*' http://localhost:8080/api/admin/settings/:InheritParentRoleAssignments``
46674827

4668-
:AllowCors
4669-
++++++++++
4828+
:AllowCors (Deprecated)
4829+
+++++++++++++++++++++++
4830+
4831+
.. note::
4832+
This setting is deprecated. Please use the JVM settings above instead.
4833+
This legacy setting will only be used if the newer JVM settings are not set.
46704834

4671-
Allows Cross-Origin Resource sharing(CORS). By default this setting is absent and the Dataverse Software assumes it to be true.
4835+
Enable or disable support for Cross-Origin Resource Sharing (CORS) by setting ``:AllowCors`` to ``true`` or ``false``.
46724836

4673-
If you don’t want to allow CORS for your installation, set:
4837+
``curl -X PUT -d true http://localhost:8080/api/admin/settings/:AllowCors``
46744838

4675-
``curl -X PUT -d 'false' http://localhost:8080/api/admin/settings/:AllowCors``
4839+
.. note::
4840+
New values for this setting will only be used after a server restart.
46764841

46774842
:ChronologicalDateFacets
46784843
++++++++++++++++++++++++

modules/container-configbaker/scripts/bootstrap/demo/init.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ echo ""
3333
echo "Revoke the key that allows for creation of builtin users..."
3434
curl -sS -X DELETE "${DATAVERSE_URL}/api/admin/settings/BuiltinUsers.KEY"
3535

36+
# TODO: stop using these deprecated database settings. See https://github.com/IQSS/dataverse/pull/11454
3637
echo ""
3738
echo "Set key for accessing blocked API endpoints..."
3839
curl -sS -X PUT -d "$BLOCKED_API_KEY" "${DATAVERSE_URL}/api/admin/settings/:BlockedApiKey"

src/main/java/edu/harvard/iq/dataverse/api/Admin.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import edu.harvard.iq.dataverse.settings.JvmSettings;
2121
import edu.harvard.iq.dataverse.util.StringUtil;
2222
import edu.harvard.iq.dataverse.util.cache.CacheFactoryBean;
23-
import edu.harvard.iq.dataverse.util.cache.RateLimitUtil;
2423
import edu.harvard.iq.dataverse.util.json.NullSafeJsonBuilder;
2524
import edu.harvard.iq.dataverse.validation.EMailValidator;
2625
import edu.harvard.iq.dataverse.EjbDataverseEngine;

0 commit comments

Comments
 (0)