Access control¶
Access control is about defining who is allowed to access certain resources. It takes two steps:
- The user is authenticated, that is, the user’s identity is determined based on some form of identification in the request, such as a session cookie.
- After the user has been identified, we can decide whether that user is authorized to access a certain URL or resource.
Authentication¶
For each HTTP request that Zotonic receives, it looks for some form of credentials that can identity the user. This can be a username/password combination when the user logs in for the first time, and a session cookie for subsequent requests. When Zotonic finds some credentials, it checks them for validity. If the credentials are valid, the user is said to be authenticated and authorization can start.
The first request, that does not yet have a session cookie or whose session cookie has expired, needs to contain some credentials in order to be authenticated. The logon controller takes care of processing login requests and checks for the presence of a ‘remember me’ cookie for automatic login. It then responds with a fresh session cookie that the client will send along with subsequent requests.
Authenticating subsequent requests, that have a session cookie, does not take
place until a session is ensured (or continued) for the request context.
This is commonly done by the controller handling the request by a call
to z_context:ensure_all/1
.
Notifications¶
Zotonic relies on a number of notifications to perform authentication. You can observe any of these notifications to customise Zotonic’s authentication behaviour.
Notification | Type | Return | Description |
---|---|---|---|
auth_confirm | foldl | Context | Sent when a user id has been confirmed. |
auth_confirm_done | notify | ||
auth_logon | foldl | Context | Sent when a user has been authenticated. |
auth_logon_done | notify | ||
auth_logoff | foldl | Context | Sent when a user is about to log out, removing the authentication from the current session. |
auth_logoff_done | notify | Sent when a user has been logged out. | |
auth_autologon | first | {ok, UserId} | Sent for new sessions from
z_auth:logon_from_session/1 . Will
attempt to authenticate the session as
UserId (if there was any observer
responding to the notification). |
#user_is_enabled{id} | first | boolean() | Ask observers if the user is enabled
(allowed to login, to be
authenticated). If the result is
undefined , the resource
is_published , publication_start
and publication_end is checked
instead. |
Authorization¶
Once the request has been authenticated, authorization is initialized by sending
an #acl_logon{}
notification. Should the session get logged out, loosing its
authentication, the authorization is cleared by sending a #acl_logoff{}
notification.
Once authorization has been initialized for a request context,
operations against objects can be checked by the z_acl
module from Erlang
code, and by the m_acl model from templates.
Protecting access to controllers¶
The first point of contact for authorization is in the controller’s
is_authorized/2
function. Both controller_page and
controller_template check for ACL options in the
dispatch rule that matched the current request.
See also
Protecting access to resources and modules¶
Zotonic ships with mod_acl_user_groups, a powerful user group-based authorization module. With this module you can define access control rules that determine which user groups are allowed to access which groups of content.
If you only have a handful of users that should all be able to access the admin, have a look at mod_acl_adminonly.
See also
Custom authorization¶
No matter what authorization module you use, you can always override Zotonic’s behaviour by observing the authorization notifications. This is especially useful if your application has some authorization logic that is not easily expressed in ACL rules.
See also
Notifications¶
The authorization system sends several notifications that you can hook into to allow or deny user access to specific resources.
Notification | Type | Return | Description |
---|---|---|---|
#acl_is_allowed{action, object} | first | boolean() | Check if user is authorized to perform operation on
object. Default is false . |
#acl_is_allowed_prop{action, object, prop} | first | boolean() | Check if user is authorized to perform operation on
property of object. Default is true . |
#acl_rsc_update_check{id}, Props | foldl | Props’ | Filter properties about to be updated for a resource. |
#acl_can_see{} | first | integer() | Get max visible_for that the user can see. |
#acl_logon{id} | first | Context | Initialize context with the access policy for the user. |
#acl_logoff{} | first | Context | Clear the associated access policy for the context. |
#acl_context_authenticated{} | first | Context | Set the context to a typical user’s permissions, do not
change the context if an user is logged on. Used by
(for example) m.acl.authenticated.insert.article |