Closed mohankv closed 8 years ago
First check the indentation. It's a YAML file, so indentation matters. In case you write everything in a single line I'm not sure the interpreter can handle your configuration correctly.
permissions:
- role: $unauthenticated
predicate: path-prefix[path="/io/tracks/"] and method[value="GET"]
Could you please post here your complete security configuration file? (Please remove any sensible data like passwords first)
Hello Maurizio, Thanks for helping me on this. Here is the complete security configuration.
With this configuration, $unauthenticated user is not able to access resources under "/io/tracks/" and "io/accounts"
If I update the paths like predicate: path-prefix[path="/"] and method[value="GET"]
, $unauthenticated user is able to access those resources.
Hi @mohankv
Have you already enabled the database authentication? With your security file RESTHeart even refuses to startup, as it is missing the mandatory 'users' section.
However, I added by hand an admin on my local copy of your file:
users:
- userid: a
password: a
roles: [admin]
Then admin created a couple of resources (with httpie, but curl works as well):
$ http -j -a a:a PUT localhost:8080/io
$ http -j -a a:a PUT localhost:8080/io/tracks
$ http -j -a a:a PUT localhost:8080/io/accounts
Then I tested the first resource with $unauthenticated:
$ http GET localhost:8080/io/
HTTP/1.1 401 Unauthorized
This is OK, as $unauthenticated can't GET the /io
path.
Then I GET the /io/tracks
and it worked:
$ http GET localhost:8080/io/tracks
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Location, ETag, Auth-Token, Auth-Token-Valid-Until, Auth-Token-Location, X-Powered-By
Connection: keep-alive
Content-Encoding: gzip
Content-Length: 120
Content-Type: application/hal+json
Date: Sat, 30 Jan 2016 15:58:26 GMT
ETag: 56acda51647d678037540ad4
X-Powered-By: restheart.org
{
"_collection-props-cached": false,
"_etag": {
"$oid": "56acda51647d678037540ad4"
},
"_id": "tracks",
"_returned": 0
}
I did the same for /io/accounts
successfully, so the $unauthenticated user can PUT documents under the /io/accounts
path as specified.
I suspect your problem might be that you roles names in sections users
or dbim
don't match with the role names in the permissions
section below. Please double check this.
Hello, Thanks for your reply again.
Having SimpleFileIdentityManager works for me too. But I would like to use DbIdentityManager. And the request has to be unauthenticated. In your requests you are passing creds.
Thanks
No, I'm not. I'm passing credentials only when creating the resources, as the unauthenticated can't do that as per your configuration file (it hasn't permissions to create the necessary databases and collections). As you can see all the remaining calls via httpie are unauthenticated. You shouldn't experience something different when using a DbIdentityManager, please check the roles in your users collection.
Hi @mohankv I can confirm here it works as expected also using the DbIdentityManager: unauthenticated requests can GET and PUT the configured resources (respectively /io/tracks/ and /io/accounts).
Hi @mohankv , @mkjsix
I made some test with DbIdentityManager and $unauthenticated role. I confirm that it works as expected.
@mohankv please double check that you are not passing credentials in the requests supposed to be $unathenticated (otherwise that permission won't apply).
Take into account that browsers cache basic authentication credentials, for instance if you have previously accessed the /browser section.
To clear browser auth cache, try http://wronged:wrongpwd@127.0.0.1:8080/browser, the auth popup windows should show and click cancel.
I am using only curl or http commands to test... so browser cache should not be the issue. I am using restheart-1.1.4. I am attaching both ymls for your reference; can you please take a look into this. I really appreciate your help. Thanks in advance.
Honestly I can't see anything wrong in your configurations so far. Also the roles in the db seems to be mapped correctly to permissions.
@ujibang the only visible difference I can spot here is auth-token-enabled: false
while usually our tests run with the auth token.
@mohankv could you please run a quick test with auth-token-enabled: true
and check for any difference?
Hi @mohankv
I replicated the issue. The problem seems to be in undertow code: the bug is in method the method isAuthenticationRequired(). of SimpleAccessManager class.
As you can see, if the request resolves against the predicates specified for the $unautenticated role, it should return true thus not requiring authentication for the request.
Using the debugger I can see it iterating over the two predicates specified in your security conf file, however it does not resolve for both.
@Override
public boolean isAuthenticationRequired(final HttpServerExchange exchange) {
if (getAcl() == null) {
return true;
}
Set<Predicate> ps = getAcl().get("$unauthenticated");
return ps == null ? true : !ps.stream().anyMatch(p -> p.resolve(exchange));
}
I'll provide an update as soon as possible...
Hi @mohankv
I found the problem! It is not a bug in undertow, just the predicates are resolved against the relative path of the request (i.e. not taking into account the prefix path used to "mount" the request handlers).
The path specified in predicates must be expressed taking the resource URL mapping into account (set by mongo-mounts configuration option).
The rule is
When the URI of a resource is remapped via mongo-mounts configuration option, the path attribute of permissions must be relative to the what argument of the mongo-mounts option.
I updated the documentation as well, see https://softinstigate.atlassian.net/wiki/x/IgDM#EnableandConfigureSecurity-SpecifyPermissiononURIRemappedResources
For example, given the following mongo-mounts configuration, the collections of the db GFDB are actually bound to the URI _/io/[collname]
mongo-mounts:
- what: /GFDB
where: /io
To allow GET requests on /GFDB/tracks collection:
permissions:
- role: $unauthenticated
predicate: path-prefix[path="/tracks"] and method[value="GET"]
Let us know if this fixes your problem.
Thank you so much! That fixes the issue I have.
Works perfect. I really appreciate your time.
$unauthenticated user is not able to access resources under path="/io/tracks/". It always returns back 401 Unauthorized error. But if I configure it like path="/", it works without any issues. What is wrong with following code?
- role: $unauthenticated predicate: path-prefix[path="/io/tracks/"] and method[value="GET"]
HTTP Error: `401 Unauthorized
Connection: keep-alive Access-Control-Allow-Origin: * WWW-Authenticate: Basic realm="RestHeart Realm" X-Powered-By: restheart.org Access-Control-Allow-Credentials: true access-control-expose-headers: Location, ETag, Auth-Token, Auth-Token-Valid-Until, Auth-Token-Location, X-Powered-By Content-Length: 0 Date: Fri, 29 Jan 2016 03:55:13 GMT`