<?xml version="1.0" encoding="utf-8"?> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <style type="text/css"> /* :Author: David Goodger (goodger@python.org) :Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. Despite the name, some widely supported CSS2 features are used. See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to customize this style sheet. */ /* used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { border: 0 } table.borderless td, table.borderless th { /* Override padding for "table.docutils td" with "! important". The right padding separates the table cells. */ padding: 0 0.5em 0 0 ! important } .first { /* Override more specific margin styles with "! important". */ margin-top: 0 ! important } .last, .with-subtitle { margin-bottom: 0 ! important } .hidden { display: none } .subscript { vertical-align: sub; font-size: smaller } .superscript { vertical-align: super; font-size: smaller } a.toc-backref { text-decoration: none ; color: black } blockquote.epigraph { margin: 2em 5em ; } dl.docutils dd { margin-bottom: 0.5em } object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } /* Uncomment (and remove this text!) to get bold-faced definition list terms dl.docutils dt { font-weight: bold } */ div.abstract { margin: 2em 5em } div.abstract p.topic-title { font-weight: bold ; text-align: center } div.admonition, div.attention, div.caution, div.danger, div.error, div.hint, div.important, div.note, div.tip, div.warning { margin: 2em ; border: medium outset ; padding: 1em } div.admonition p.admonition-title, div.hint p.admonition-title, div.important p.admonition-title, div.note p.admonition-title, div.tip p.admonition-title { font-weight: bold ; font-family: sans-serif } div.attention p.admonition-title, div.caution p.admonition-title, div.danger p.admonition-title, div.error p.admonition-title, div.warning p.admonition-title, .code .error { color: red ; font-weight: bold ; font-family: sans-serif } /* Uncomment (and remove this text!) to get reduced vertical space in compound paragraphs. div.compound .compound-first, div.compound .compound-middle { margin-bottom: 0.5em } div.compound .compound-last, div.compound .compound-middle { margin-top: 0.5em } */ div.dedication { margin: 2em 5em ; text-align: center ; font-style: italic } div.dedication p.topic-title { font-weight: bold ; font-style: normal } div.figure { margin-left: 2em ; margin-right: 2em } div.footer, div.header { clear: both; font-size: smaller } div.line-block { display: block ; margin-top: 1em ; margin-bottom: 1em } div.line-block div.line-block { margin-top: 0 ; margin-bottom: 0 ; margin-left: 1.5em } div.sidebar { margin: 0 0 0.5em 1em ; border: medium outset ; padding: 1em ; background-color: #ffffee ; width: 40% ; float: right ; clear: right } div.sidebar p.rubric { font-family: sans-serif ; font-size: medium } div.system-messages { margin: 5em } div.system-messages h1 { color: red } div.system-message { border: medium outset ; padding: 1em } div.system-message p.system-message-title { color: red ; font-weight: bold } div.topic { margin: 2em } h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { margin-top: 0.4em } h1.title { text-align: center } h2.subtitle { text-align: center } hr.docutils { width: 75% } img.align-left, .figure.align-left, object.align-left, table.align-left { clear: left ; float: left ; margin-right: 1em } img.align-right, .figure.align-right, object.align-right, table.align-right { clear: right ; float: right ; margin-left: 1em } img.align-center, .figure.align-center, object.align-center { display: block; margin-left: auto; margin-right: auto; } table.align-center { margin-left: auto; margin-right: auto; } .align-left { text-align: left } .align-center { clear: both ; text-align: center } .align-right { text-align: right } /* reset inner alignment in figures */ div.align-right { text-align: inherit } /* div.align-center * { */ /* text-align: left } */ .align-top { vertical-align: top } .align-middle { vertical-align: middle } .align-bottom { vertical-align: bottom } ol.simple, ul.simple { margin-bottom: 1em } ol.arabic { list-style: decimal } ol.loweralpha { list-style: lower-alpha } ol.upperalpha { list-style: upper-alpha } ol.lowerroman { list-style: lower-roman } ol.upperroman { list-style: upper-roman } p.attribution { text-align: right ; margin-left: 50% } p.caption { font-style: italic } p.credits { font-style: italic ; font-size: smaller } p.label { white-space: nowrap } p.rubric { font-weight: bold ; font-size: larger ; color: maroon ; text-align: center } p.sidebar-title { font-family: sans-serif ; font-weight: bold ; font-size: larger } p.sidebar-subtitle { font-family: sans-serif ; font-weight: bold } p.topic-title { font-weight: bold } pre.address { margin-bottom: 0 ; margin-top: 0 ; font: inherit } pre.literal-block, pre.doctest-block, pre.math, pre.code { margin-left: 2em ; margin-right: 2em } pre.code .ln { color: gray; } /* line numbers */ pre.code, code { background-color: #eeeeee } pre.code .comment, code .comment { color: #5C6576 } pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } pre.code .literal.string, code .literal.string { color: #0C5404 } pre.code .name.builtin, code .name.builtin { color: #352B84 } pre.code .deleted, code .deleted { background-color: #DEB0A1} pre.code .inserted, code .inserted { background-color: #A3D289} span.classifier { font-family: sans-serif ; font-style: oblique } span.classifier-delimiter { font-family: sans-serif ; font-weight: bold } span.interpreted { font-family: sans-serif } span.option { white-space: nowrap } span.pre { white-space: pre } span.problematic, pre.problematic { color: red } span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80% } table.citation { border-left: solid 1px gray; margin-left: 1px } table.docinfo { margin: 2em 4em } table.docutils { margin-top: 0.5em ; margin-bottom: 0.5em } table.footnote { border-left: solid 1px black; margin-left: 1px } table.docutils td, table.docutils th, table.docinfo td, table.docinfo th { padding-left: 0.5em ; padding-right: 0.5em ; vertical-align: top } table.docutils th.field-name, table.docinfo th.docinfo-name { font-weight: bold ; text-align: left ; white-space: nowrap ; padding-left: 0 } /* "booktabs" style (no vertical lines) */ table.docutils.booktabs { border: 0px; border-top: 2px solid; border-bottom: 2px solid; border-collapse: collapse; } table.docutils.booktabs * { border: 0px; } table.docutils.booktabs th { border-bottom: thin solid; text-align: left; } h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { font-size: 100% } ul.auto-toc { list-style-type: none } </style> </head>

Flask HTTP Digest Authentication

Description

Flask-Digest-Auth is an HTTP Digest Authentication implementation for Flask applications. It authenticates the user for the protected views. It works with Flask-Login, so that log in protection can be separated with the authentication mechanism. You can write Flask modules that work with different authentication mechanisms.

Flask-Digest-Auth Alone without Flask-Login

Flask-Digest-Auth can authenticate the users alone without Flask-Login.

Example for Simple Applications with Flask-Digest-Auth Alone

from flask import Flask
from flask_digest_auth import DigestAuth

app: flask = Flask(__name__)
... (Configure the Flask application) ...

auth: DigestAuth = DigestAuth(realm="Admin")

@auth.register_get_password
def get_password_hash(username: str) -> t.Optional[str]:
    ... (Load the password hash) ...

@auth.register_get_user
def get_user(username: str) -> t.Optional[t.Any]:
    ... (Load the user) ...

@app.get("/admin")
@auth.login_required
def admin():
    ... (Process the view) ...

Example for Larger Applications with create_app() with Flask-Digest-Auth Alone

::

from flask import Flask
from flask_digest_auth import DigestAuth

auth: DigestAuth = DigestAuth(realm="Admin")

def create_app(test_config) -> Flask:
    app: flask = Flask(__name__)
    ... (Configure the Flask application) ...

    auth.realm = app.config["REALM"]

    @auth.register_get_password
    def get_password_hash(username: str) -> t.Optional[str]:
        ... (Load the password hash) ...

    @auth.register_get_user
    def get_user(username: str) -> t.Optional[t.Any]:
        ... (Load the user) ...

    return app

In your views:

from . import auth
from flask import Flask, Blueprint

bp = Blueprint("admin", __name__, url_prefix="/admin")

@bp.get("/")
@auth.login_required
def admin():
    ... (Process the view) ...

def init_app(app: Flask) -> None:
    app.register_blueprint(bp)

Flask-Login Integration

Flask-Digest-Auth can work with Flask-Login. You can write a Flask module that requires log in, without specifying the authentication mechanism. The Flask application can specify the actual authentication mechanism as they see fit.

Example for Simple Applications with Flask-Login Integration

from flask import Flask
from flask_digest_auth import DigestAuth
from flask_login import LoginManager

app: flask = Flask(__name__)
... (Configure the Flask application) ...

login_manager: LoginManager = LoginManager()
login_manager.init_app(app)

@login_manager.user_loader
def load_user(user_id: str) -> t.Optional[User]:
    ... (Load the user with the username) ...

auth: DigestAuth = DigestAuth(realm="Admin")
auth.init_app(app)

@auth.register_get_password
def get_password_hash(username: str) -> t.Optional[str]:
    ... (Load the password hash) ...

@app.get("/admin")
@login_manager.login_required
def admin():
    ... (Process the view) ...

Example for Larger Applications with create_app() with Flask-Login Integration

::

from flask import Flask
from flask_digest_auth import DigestAuth
from flask_login import LoginManager

def create_app(test_config) -> Flask:
    app: flask = Flask(__name__)
    ... (Configure the Flask application) ...

    login_manager: LoginManager = LoginManager()
    login_manager.init_app(app)

    @login_manager.user_loader
    def load_user(user_id: str) -> t.Optional[User]:
        ... (Load the user with the username) ...

    auth: DigestAuth = DigestAuth(realm=app.config["REALM"])
    auth.init_app(app)

    @auth.register_get_password
    def get_password_hash(username: str) -> t.Optional[str]:
        ... (Load the password hash) ...

    return app

In your views:

import flask_login
from flask import Flask, Blueprint

bp = Blueprint("admin", __name__, url_prefix="/admin")

@bp.get("/")
@flask_login.login_required
def admin():
    ... (Process the view) ...

def init_app(app: Flask) -> None:
    app.register_blueprint(bp)

The views only depend on Flask-Login, but not its underlying authentication mechanism. You can always change the authentication mechanism without changing the views, or release a protected Flask module without specifying the authentication mechanism.

Authors

imacat
2022/11/23
</html>
Description
Flask HTTP Digest Authentication
Readme 179 KiB
0.7.1 Latest
2024-12-09 08:35:10 +08:00
Languages
Python 100%