Low-level API for generic web projects#
Web app that logs in users#
Firstly, create an instance of the
identity.web.Auth
object, and assign it to a (typically global) variable:auth = identity.web.Auth( session=session, # A session object is a key-value storage with a # dict-like interface. Many web frameworks provide this. authority="https://login.microsoftonline.com/common", client_id="your_app_client_id", client_credential="your_secret", )
Now, in your web app’s login controller, call the
auth.log_in(scopes=["your_scope"], redirect_uri="https://your_app.example.com/redirect_uri")
(see alsolog_in()
) to obtain theauth_uri
(and possibly auser_code
), and then render them into your login html page.The second leg of log-in needs to be implemented in another controller, which calls
auth.complete_log_in(incoming_query_parameters)
(see alsocomplete_log_in()
). If its returned dict contains anerror
, then render the error to end user, otherwise your end user has successfully logged in, and his/her information is available as a dict returned byidentity.web.Auth.get_user()
. In particular, the returned dict contains a key namedsub
, whose value is the unique identifier which you can use to represent this end user in your app’s local database.Don’t forget to add one more controller for log out. You do it by calling
auth.log_out("https://your_app.example.com")
. Please refer tolog_out()
’s docs for more details about its return value.
All of the content above are demonstrated in this sample (link to be provided).
Web app that logs in users and calls a web API on their behalf#
Building on top of the previous scenario, you just need to call
auth.get_token_for_user(["your_scope"])
to obtain a token object.
See identity.web.Auth.get_token_for_user()
for more details.
And you can see it in action in this sample (link to be provided).
Generic API, currently used for Flask web apps#
- class identity.web.Auth(*, session, client_id, oidc_authority=None, authority=None, client_credential=None, http_cache=None)#
- __init__(*, session, client_id, oidc_authority=None, authority=None, client_credential=None, http_cache=None)#
Create an identity helper for a web app.
This instance is expected to be long-lived with the web app.
- Parameters:
session¶ (dict) – A dict-like object to hold the session data. If you are using Flask, you should pass in
session
. If you are using Django, you should pass inrequest.session
.oidc_authority¶ (str) – The authority which your app registers with your OpenID Connect provider. For example,
https://example.com/foo
. This library will concatenate/.well-known/openid-configuration
to form the metadata endpoint.authority¶ (str) – The authority which your app registers with your Microsoft Entra ID. For example,
https://example.com/foo
. Historically, the underlying library will sometimes automatically append “/v2.0” to it. If you do not want that behavior, you may useoidc_authority
instead.client_id¶ (str) – The client_id of your web app, issued by its authority.
client_credential¶ (str) – It is somtimes a string. The actual format is decided by the underlying auth library. TBD.
- complete_log_in(auth_response=None)#
This is the second leg of the authentication/authorization.
It is used inside your redirect_uri controller.
- Parameters:
auth_response¶ (dict) –
A dict-like object containing the parameters issued by Identity Provider. If you are using Flask, you can pass in
request.args
. If you are using Django, you can pass inHttpRequest.GET
.If you were using Device Code Flow, you won’t have an auth response, in that case you can leave it with its default value
None
.- Returns:
On failure, a dict containing “error” and optional “error_description”, for you to somehow render it to end user.
On success, a dict as {“next_link”: “/path/to/next/page/if/any”} That dict is actually the claims from an already-validated ID token.
- get_token_for_client(scopes)#
Get access token for the current app, with specified scopes.
- Parameters:
scopes¶ (list) – A list of scopes that your app will need to use.
- Returns:
A dict representing the json response from identity provider.
A successful response would contain “access_token” key,
An error response would contain “error” and usually “error_description”.
See also OAuth2 specs.
- get_token_for_user(scopes)#
Get access token silently for the current user, with specified scopes.
- Parameters:
scopes¶ (list) – A list of scopes that your app will need to use.
- Returns:
A dict representing the json response from identity provider.
A successful response would contain “access_token” key,
An error response would contain “error” and usually “error_description”.
See also OAuth2 specs.
- get_user()#
Returns None if the user has not logged in or no longer passes validation. Otherwise returns a dict representing the current logged-in user.
The dict will have following keys:
sub
. It is the unique identifier of the current logged-in user. You can use it to create an entry in your web app’s local database.Some of other claims
- log_in(scopes=None, redirect_uri=None, state=None, prompt=None, next_link=None)#
This is the first leg of the authentication/authorization.
- Parameters:
scopes¶ (list) – A list of scopes that your app will need to use.
redirect_uri¶ (str) –
Optional. If present, it must be an absolute uri you registered for your web app. In Flask, if your redirect_uri function is named
def auth_response()
, then you can useurl_for("auth_response", _external=True)
.If absent, your end users will log in to your web app using a different method named Device Code Flow. It is less convenient for end user, but still works.
state¶ (str) – Optional. Useful when the caller wants keep their own state.
next_link¶ (str) – The link, typically a path, to redirect to after login.
Returns a dict containing the
auth_uri
that you need to guide end user to visit. If your app has no redirect uri, this method will also return auser_code
which you shall also display to end user for them to use during log-in.
- log_out(homepage)#
Logs out the user from current app.
- Parameters:
homepage¶ (str) – The page to be redirected to, after the log-out. In Flask, you can pass in
url_for("index", _external=True)
.- Returns:
An upstream log-out URL. You can optionally guide user to visit it, otherwise the user remains logged-in there, and can SSO back to your app.