CtrlK
CommunityDocumentationLog inGet started
Tessl Logo

tessl/pypi-flask-security

Simple security for Flask apps

Overview
Eval results
Files

authorization.mddocs/

Authorization and Access Control

Flask-Security provides comprehensive authorization functionality through decorators that protect views and functions based on authentication status and user roles. It integrates with Flask-Principal for role-based access control and supports multiple authentication methods.

Capabilities

Authentication Required Decorators

Decorators that require users to be authenticated before accessing protected resources.

def login_required(fn):
    """
    Decorator that requires user authentication.
    Redirects to login page if user is not authenticated.
    
    Args:
        fn: Function to protect
        
    Returns:
        Decorated function
    """

def auth_required(*auth_methods):
    """
    Multi-method authentication decorator.
    Accepts multiple authentication methods.
    
    Args:
        *auth_methods (str): Authentication methods ('token', 'basic', 'session')
        
    Returns:
        Decorator function
    """

def auth_token_required(fn):
    """
    Decorator for token-based authentication.
    Checks for authentication token in query params or headers.
    
    Args:
        fn: Function to protect
        
    Returns:
        Decorated function
    """

def http_auth_required(realm):
    """
    Decorator for HTTP Basic authentication.
    
    Args:
        realm (str): HTTP Basic auth realm
        
    Returns:
        Decorator function
    """

Role-Based Access Control

Decorators that enforce role-based permissions on protected resources.

def roles_required(*roles):
    """
    Decorator requiring user to have ALL specified roles.
    Returns 403 Forbidden if user lacks any required role.
    
    Args:
        *roles (str): Role names that user must have
        
    Returns:
        Decorator function
    """

def roles_accepted(*roles):
    """
    Decorator requiring user to have AT LEAST ONE of the specified roles.
    Returns 403 Forbidden if user has none of the roles.
    
    Args:
        *roles (str): Role names, user must have at least one
        
    Returns:
        Decorator function
    """

Anonymous User Decorator

Decorator that restricts access to anonymous (non-authenticated) users only.

def anonymous_user_required(fn):
    """
    Decorator that requires user to be anonymous (not logged in).
    Redirects authenticated users away from the protected resource.
    
    Args:
        fn: Function to protect
        
    Returns:
        Decorated function
    """

Usage Examples

Basic Authentication Protection

from flask_security import login_required, current_user

@app.route('/profile')
@login_required
def profile():
    return f"Welcome to your profile, {current_user.email}!"

@app.route('/dashboard')
@login_required
def dashboard():
    return render_template('dashboard.html', user=current_user)

Role-Based Access Control

from flask_security import roles_required, roles_accepted

@app.route('/admin')
@roles_required('admin')
def admin_panel():
    return "Admin Panel - Only admins can see this"

@app.route('/admin/users')
@roles_required('admin', 'user-manager')
def manage_users():
    # User must have BOTH admin AND user-manager roles
    return "User Management"

@app.route('/moderator')
@roles_accepted('admin', 'moderator')
def moderator_panel():
    # User must have EITHER admin OR moderator role
    return "Moderator Panel"

@app.route('/content/edit/<int:post_id>')
@roles_accepted('admin', 'editor', 'author')
def edit_content(post_id):
    return f"Editing post {post_id}"

Token-Based API Protection

from flask_security import auth_token_required

@app.route('/api/data')
@auth_token_required
def api_data():
    return {
        'data': 'Protected API data',
        'user': current_user.email
    }

@app.route('/api/admin')
@auth_token_required
@roles_required('admin')
def api_admin():
    return {'admin_data': 'Secret admin information'}

HTTP Basic Authentication

from flask_security import http_auth_required

@app.route('/basic-auth')
@http_auth_required('Protected Area')
def basic_auth_endpoint():
    return f"Authenticated via HTTP Basic: {current_user.email}"

# Custom realm
@app.route('/api/secure')
@http_auth_required('API Access')
def secure_api():
    return {'message': 'Authenticated via HTTP Basic Auth'}

Multi-Method Authentication

from flask_security import auth_required

@app.route('/api/flexible')
@auth_required('token', 'basic', 'session')
def flexible_auth():
    # Accepts token, HTTP basic, or session authentication
    return {
        'message': 'Authenticated via any method',
        'user': current_user.email
    }

@app.route('/api/token-or-session')
@auth_required('token', 'session')
def token_or_session():
    # Accepts either token or session authentication
    return {'data': 'Protected data'}

Anonymous User Restrictions

from flask_security import anonymous_user_required

@app.route('/register')
@anonymous_user_required
def register():
    # Only show registration to non-logged-in users
    return render_template('register.html')

@app.route('/login')
@anonymous_user_required  
def login():
    # Redirect logged-in users away from login page
    return render_template('login.html')

Combining Decorators

from flask_security import login_required, roles_required

@app.route('/admin/settings')
@login_required
@roles_required('admin')
def admin_settings():
    return "Admin Settings"

# Method-specific protection
@app.route('/api/admin/users', methods=['GET', 'POST'])
@auth_token_required
@roles_required('admin')
def admin_users_api():
    if request.method == 'GET':
        return {'users': get_all_users()}
    elif request.method == 'POST':
        return {'result': create_user(request.json)}

Custom Authorization Logic

from functools import wraps
from flask import abort
from flask_security import current_user, login_required

def owner_required(get_resource_owner):
    """Custom decorator to check resource ownership"""
    def decorator(fn):
        @wraps(fn)
        @login_required
        def decorated_view(*args, **kwargs):
            resource_owner = get_resource_owner(*args, **kwargs)
            if current_user != resource_owner and not current_user.has_role('admin'):
                abort(403)
            return fn(*args, **kwargs)
        return decorated_view
    return decorator

# Usage
@app.route('/posts/<int:post_id>/edit')
@owner_required(lambda post_id: Post.query.get(post_id).author)
def edit_post(post_id):
    return f"Editing post {post_id}"

def permission_required(permission):
    """Custom decorator for fine-grained permissions"""
    def decorator(fn):
        @wraps(fn)
        @login_required
        def decorated_view(*args, **kwargs):
            if not current_user.has_permission(permission):
                abort(403)
            return fn(*args, **kwargs)
        return decorated_view
    return decorator

@app.route('/admin/delete-user/<int:user_id>')
@permission_required('delete_users')
def delete_user(user_id):
    return f"Deleting user {user_id}"

Class-Based View Protection

from flask.views import MethodView
from flask_security import roles_required, login_required

class AdminAPI(MethodView):
    decorators = [login_required, roles_required('admin')]
    
    def get(self):
        return {'message': 'Admin GET endpoint'}
    
    def post(self):
        return {'message': 'Admin POST endpoint'}

app.add_url_rule('/admin-api', view_func=AdminAPI.as_view('admin_api'))

Conditional Authorization

from flask_security import current_user

@app.route('/content/<int:content_id>')
@login_required  
def view_content(content_id):
    content = Content.query.get_or_404(content_id)
    
    # Custom authorization logic
    if content.is_private:
        if not (current_user.has_role('admin') or content.owner == current_user):
            abort(403, "Access denied to private content")
    
    return render_template('content.html', content=content)

@app.route('/api/posts')
@auth_token_required
def get_posts():
    # Filter results based on user role
    if current_user.has_role('admin'):
        posts = Post.query.all()
    else:
        posts = Post.query.filter_by(published=True).all()
    
    return {'posts': [post.to_dict() for post in posts]}
tessl i tessl/pypi-flask-security@3.0.0

docs

authentication.md

authorization.md

core-extension.md

data-storage.md

forms.md

index.md

security-features.md

signals.md

user-role-models.md

tile.json