[TOC]
Cowj supports auth
using JCasbin
.
Design goal of this has been to do authorisation verification for Request
.
After much thought we have also put authentication.
If anyone wants to use auth, it has to be inside the auth
folder,
the special designated folder must hold all auth definitions.
Suppose, then we have the auth
folder pointing to /something/auth
,
then the designated auth file is : /something/auth/auth.yaml
.
This was done in purpose, to ensure fixed location for auth
.
Although that is not really the design, technically one can override the auth()
function in the model to move auth to any other file location.
For this manual we point to the samples/auth_demo
project.
# The standard location auth file
# is it enabled?
disabled: false
provider:
type: "auth-jwt"
secret-key: "42"
issuer: "test"
expiry: 60000 # 1 minute
risks:
- "/token"
user-header: "u"
# casbin policy
policy:
# this is adapter type file
adapter: file
# for a file type, CSV is the way
file: policy.csv
message: "thou shall not pass!"
In the main app's yaml configuration file we must define the auth provider as follows:
# define plugins
plugins:
cowj.plugins:
auth-jdbc : StorageAuthenticator::JDBC
auth-redis: StorageAuthenticator::REDIS
auth-storage : StorageAuthenticator::STORAGE # Anything that uses underlying storage, Memory, FileSystem, S3, Google Storage
auth-jwt : JWTAuthenticator::JWT # jwt based authentication
Is the auth to be disabled - so that it won't be used it true
. Default value false
.
We have 2 types of Authentication providers.
This is how one can define storage based auth. There are 3 types, but they are to be defined in the plugins section.
provider:
type: "auth-jdbc" # type to be defined in the plugins as above shown
storage: "jdbc-ds-name" # name of the data source to be used
token: "body:token" # defines how to extract the token, from body or header
query: "select * from tokens where token = '%s'" # query which would get back the user row from tokens table
user: "user" # in the resultant row name of the users column
expiry: "expiry" # resultant row name of the expiry column
risks: # bunch of allowed paths - which does not require authentication
- /path1
- /path2
System would pick up the token using the token
expression, it is xpath
expression with a name space either header
or body
. In this case, we are specifically telling body of the request would have a field called token
and we should extract that.
provider:
type: "auth-jwt" # type of the provider - define in the plugin
secrets: "my-secret-provider" # a secrets manager
secret-key: "my-secret-key" # key to the secret key in the secrets manager
issuer: "issuer-identity" # key to the issuer identity in the secrets manager
expiry: 60000 # in ms, how long the token would be valid by default
risks:
- "/token" # bunch of risky routes
To make this work, create a JWT token as follows in the /tokens
route:
// get provider
jwt_provider = _ds["ds:auth"] ?? ""
panic( empty(jwt_provider), "JWT Provider does not exist!")
// create whatever token - presumably after auth
jwt_token = jwt_provider.jwt("bar")
// respond
jstr( { "tok" : jwt_token.toString() } )
And then we can use the token simply by adding them to Authorization
header:
curl -H "Authorization: Bearer <insert-jwt-here>" localhost:6044/hello
See the app/samples/auth_jwt
folder.
The header key which shall have the user's id. Default is username
.
There is a fixed location auth/model.conf
is the location of the model file.
# auth/model.conf
# https://github.com/php-casbin/casbin-tutorials/blob/master/tutorials/RBAC-with-Casbin.md
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
# the definition for the RBAC role inheritance relations
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub) && keyMatch2(r.obj, p.obj) && regexMatch(r.act, p.act)
This comes under policy, plan to support some adapters, specifically the Google Storage and S3 adapters.
Currently only supports file
adapter, which must have file
key to point to the policy file, which must
be present in the auth
folder itself.
Used to deliver the un-auth message to the user.
The Cowj configuration file is shown:
# auth_demo/auth_demo.yaml
port: 6042
# path mapping
routes:
post:
/entity: _/create.zm
get:
/entity/:entityId : _/fetch.zm
The policy file can be found here: auth_demo/auth/policy.csv
g, alice, admin
g, bob, member
p, member, /entity/:id, GET
g, admin, member
p, admin, /entity, POST
It says alice
is admin, and bob
is a member in the first two lines.
Next the policy access : member can access the route /entity:id
via GET
Admin is also a member.
Finally, admin can access /entity
route via POST
.
curl -XPOST localhost:6042/entity -H "u:bob"
Will fail with 403
error. while
curl -XPOST localhost:6042/entity -H "u:alice"
will run through. At the same time:
curl -XGET localhost:6042/entity/111 -H "u:bob"
would work, but :
curl -XGET localhost:6042/entity/111
will give 401
due to not having the header u
. At the same time:
curl -XGET localhost:6042/hello.json
because it is loaded from static
- it is exempt - so anyone would be able to access it.
-
Casbin : https://casbin.org
-
Casbin Adapters : https://casbin.org/docs/adapters
-
Access Control : Computer access control - Wikipedia