@@ -77,17 +77,129 @@ but this is **NOT RECOMMENDED**, unless authentication or access restrictions ar
77
77
c.ServerApp.token = ''
78
78
c.ServerApp.password = ''
79
79
80
- Authorization
81
- -------------
80
+
81
+ Authentication and Authorization
82
+ --------------------------------
82
83
83
84
.. versionadded :: 2.0
84
85
86
+ There are two steps to deciding whether to allow a given request to be happen.
87
+
88
+ The first step is "Authentication" (identifying who is making the request).
89
+ This is handled by the :class: `.IdentityProvider `.
90
+
91
+ Whether a given user is allowed to take a specific action is called "Authorization",
92
+ and is handled separately, by an :class: `.Authorizer `.
93
+
94
+ These two classes may work together,
95
+ as the information returned by the IdentityProvider is given to the Authorizer when it makes its decisions.
96
+
97
+ Authentication always takes precedence because if no user is authenticated,
98
+ no authorization checks need to be made,
99
+ as all requests requiring _authorization_ must first complete _authentication_.
100
+
101
+ Identity Providers
102
+ ******************
103
+
104
+ The :class: `.IdentityProvider ` class is responsible for the "authorization" step,
105
+ identifying the user making the request,
106
+ and constructing information about them.
107
+
108
+ It principally implements two methods.
109
+
110
+ .. autoclass :: jupyter_server.auth.IdentityProvider
111
+
112
+ .. automethod :: get_user
113
+ .. automethod :: identity_model
114
+
115
+ The first is :meth: `.IdentityProvider.get_user `.
116
+ This method is given a RequestHandler, and is responsible for deciding whether there is an authenticated user making the request.
117
+ If the request is authenticated, it should return a :class: `.jupyter_server.auth.User ` object representing the authenticated user.
118
+ It should return None if the request is not authenticated.
119
+
120
+ The default implementation accepts token or password authentication.
121
+
122
+ This User object will be available as `self.current_user ` in any request handler.
123
+ Request methods decorated with tornado's `@web.authenticated ` decorator
124
+ will only be allowed if this method returns something.
125
+
126
+ The User object will be a Python :py:class: `dataclasses.dataclass `, `jupyter_server.auth.User `:
127
+
128
+ .. autoclass :: jupyter_server.auth.User
129
+
130
+ A custom IdentityProvider _may_ return a custom subclass.
131
+
132
+
133
+ The next method an identity provider has is :meth: `~.IdentityProvider.identity_model `.
134
+ `identity_model(user) ` is responsible for transforming the user object returned from `.get_user() `
135
+ into a standard identity model dictionary,
136
+ for use in the `/api/me ` endpoint.
137
+
138
+ If your user object is a simple username string or a dict with a `username ` field,
139
+ you may not need to implement this method, as the default implementation will suffice.
140
+
141
+ Any required fields missing from the dict returned by this method will be filled-out with defaults.
142
+ Only `username ` is strictly required, if that is all the information the identity provider has available.
143
+
144
+ Missing will be derived according to:
145
+
146
+ - if `name ` is missing, use `username `
147
+ - if `display_name ` is missing, use `name `
148
+
149
+ Other required fields will be filled with `None `.
150
+
151
+
152
+ Identity Model
153
+ ^^^^^^^^^^^^^^
154
+
155
+ The identity model is the model accessed at `/api/me `,
156
+ and describes the currently authenticated user.
157
+
158
+ It has the following fields:
159
+
160
+ username
161
+ (string)
162
+ Unique string identifying the user.
163
+ Must be non-empty.
164
+ name
165
+ (string)
166
+ For-humans name of the user.
167
+ May be the same as `username ` in systems where only usernames are available.
168
+ display_name
169
+ (string)
170
+ Alternate rendering of name for display, such as a nickname.
171
+ Often the same as `name `.
172
+ initials
173
+ (string or null)
174
+ Short string of initials.
175
+ Initials should not be derived automatically due to localization issues.
176
+ May be `null ` if unavailable.
177
+ avatar_url
178
+ (string or null)
179
+ URL of an avatar image to be used for the user.
180
+ May be `null ` if unavailable.
181
+ color
182
+ (string or null)
183
+ A CSS color string to use as a preferred color,
184
+ such as for collaboration cursors.
185
+ May be `null ` if unavailable.
186
+
187
+ Authorization
188
+ *************
189
+
190
+ Authorization is the second step in allowing an action,
191
+ after a user has been _authenticated_ by the IdentityProvider.
192
+
85
193
Authorization in Jupyter Server serves to provide finer grained control of access to its
86
194
API resources. With authentication, requests are accepted if the current user is known by
87
195
the server. Thus it can restrain access to specific users, but there is no way to give allowed
88
196
users more or less permissions. Jupyter Server provides a thin and extensible authorization layer
89
197
which checks if the current user is authorized to make a specific request.
90
198
199
+ .. autoclass :: jupyter_server.auth.Authorizer
200
+
201
+ .. automethod :: is_authorized
202
+
91
203
This is done by calling a ``is_authorized(handler, user, action, resource) `` method before each
92
204
request handler. Each request is labeled as either a "read", "write", or "execute" ``action ``:
93
205
@@ -233,6 +345,7 @@ The ``is_authorized()`` method will automatically be called whenever a handler i
233
345
``@authorized `` (from ``jupyter_server.auth ``), similarly to the
234
346
``@authenticated `` decorator for authorization (from ``tornado.web ``).
235
347
348
+
236
349
Security in notebook documents
237
350
==============================
238
351
0 commit comments