0

OpenID + Authkit และ Pylons แบบมี Admin กับ User อื่นๆ

หลังจากที่โพสไปคราวก่อน ก็ลองใช้ OpenID กับ Authkit และ Pylons ได้แล้ว ใน app ชื่อ topenid แต่ว่าผมก็ยังอยากจะแยกระหว่าง admin กับ user อื่นๆ ก็เลยเขียน code เพิ่มอีกหน่อย เริ่มจาก development.ini เพิ่มบรรทัดนี้เข้าไป

topenid.admins = http://xxxx.myopenid.com/ https://me.yahoo.com/xxxxyyyy

เพื่อบอกว่า admins เป็นใครบ้าง แต่พอดีเป็นแนว openid ก็บอกไปแบบนี้ จากนั้นก็เข้าไปแก้ใน controller แบบนี้

import logging

from pylons import request, response, session, tmpl_context as c
from pylons import config
from pylons.controllers.util import abort, redirect_to
from authkit.permissions import RemoteUser
from authkit.authorize.pylons_adaptors import authorize
from authkit.permissions import RequestPermission

from topenid.lib.base import BaseController, render

log = logging.getLogger(__name__)


# class Admin นี้เป็นตัว check permission ว่าเป็น Admin หรือเปล่า
# ผมว่าน่าแยกอีกไฟล์แต่ขี้เกียจ

from authkit.authorize import NotAuthenticatedError
import urlparse
class Admin(RequestPermission):
    def __init__(self):
        if 'topenid.admins' not in config:
            raise RuntimeError, 'Require topenid.admins'
        self.users = config['topenid.admins'].split()

    def check(self, app, environ, start_response):
        if 'REMOTE_USER' not in environ:
             raise NotAuthenticatedError('Not Authenticated')
        if urlparse.urldefrag(environ['REMOTE_USER'])[0] not in self.users:
             raise NotAuthenticatedError('Not Authenticated')
        return app(environ, start_response)

class AuthController(BaseController):

    # แบบนี้ใครก็เข้าได้
    def index(self):
        return 'Hello World'

    @authorize(Admin())  # ให้เฉพาะ admin เข้า
    def test2(self):
        return 'test'

    @authorize(RemoteUser())   # ใครที่ sign-in ก็เข้าได้
    def test(self):
        return 'test'

    def signout(self):
        return 'signout'

    def signin(self):
        return 'signed in'

    def env1(self):
        return request.environ.get('REMOTE_USER')
        #return config.get('topenid.admins')[0]

ง่วงมาก Zzzz …

2

OpenID + AuthKit + Pylons (simple)

I try to post simple example how to use OpenID with AuthKit 0.4.3 and Pylons 0.9.7. by adapting example from AuthKit. So I just create new Pylons app named “topenid” and modify it as follow:

  1. development.ini:
    These lines below are added to development.ini

    authkit.setup.enable = true
    authkit.setup.method = openid, cookie
    authkit.openid.store.type = file
    authkit.openid.store.config =
    authkit.openid.charset = UTF-8
    authkit.openid.path.signedin = /auth/signin
    authkit.cookie.signoutpath = /auth/signout
    authkit.openid.store.baseurl = http://localhost:5000
    authkit.cookie.secret = somesecret
    
  2. midddleware
    ...
    import authkit.authenticate # this line is added
    ...
        app = PylonsApp()
        app = authkit.authenticate.middleware(app, app_conf) # this line is added
    ...
  3. topenid/controllers/auth.py
    import logging
    
    from pylons import request, response, session, tmpl_context as c
    from pylons.controllers.util import abort, redirect_to
    from authkit.permissions import RemoteUser
    from authkit.authorize.pylons_adaptors import authorize
    
    from topenid.lib.base import BaseController, render
    
    log = logging.getLogger(__name__)
    
    class AuthController(BaseController):
        def index(self):
            return 'Hello World'
    
        @authorize(RemoteUser())
        def test(self):
            return 'test'
    
        def signout(self):
            return 'signout'
    
        def signin(self):
            return 'signed in'

These are all modifications. I can access http://localhost:5000/auth/index as expect and http://localhost:5000/auth/test is redirected to an OpenID signin page. And I can sign out by visiting http://localhost:5000/auth/signout.

This example seems to work well but I need something more complex for example every user doesn’t have the same role. So I may post another more complex example soon.

0

Authkit: Change sign-in form (simple)

After using Authkit with *form* authentication method for a while, I want to change sign-in form to have the same theme as other pages and also add project name to the form. Finally, I found this site http://jimmyg.org/2007/08/14/pylons-mako-templates-in-authkit/, which is (nearly) identical @sirn suggestion. They told me how to change this form so thank both of them.

However, I want to make a very simple modification first so I simplified the example. In development.ini, I just add “authkit.form.template.obj”.

authkit.setup.enable = true
authkit.setup.method = form, cookie
authkit.form.authenticate.user.type = basaasa.users.authkit_elixir_driver:UsersFromDatabase
authkit.form.authenticate.user.data = basaasa.model
authkit.cookie.secret = SomeSec
authkit.cookie.signoutpath = /auth/signout
authkit.form.template.obj = basaasa.lib.auth:make_template #I added this line

Then I added auth.py to /basaasa/lib.

auth.py:

def make_template():
    return """


Signin


<div>
BasaAsa: Signin

<table>
<tr><td>
Username: 
</td></tr>
<tr><td>
Password: 
</td></tr>
</table>


</div>


"""

def make_template() is required to return template, which is format string. Format string is just normal string with format specifier(s), for example: “xxx %s xxx”. For “def make_template()”, %s will be replace by an action, which is used as form action.

I do not plan to really use this example in BasaAsa but an example in the link in the paragraph above. However I hope this will remind me in the future how template work in Authkit and how to replace it.

1

Authkit + Elixir

ใช้ pylons 0.9.7rc3 แต่ว่าใช้ elixir 0.6.1 มาครอบ sqlalchemy อีกที แทนที่จะใช้ sqlalchemy ตรงๆ ซึ่งเป็นวิถีทางที่เป็นที่นิยมกว่า ก็ไม่ได้ลำบากยากเย็นอะไร แก้ให้ใช้ elixir ก็ทำตาม ที่เคยๆ เขียนไว้ไม่มากก็เป็นอันใช้ได้ แต่พอมาเจอ authkit 0.4.2 ก็เป็นท่ายากขึ้นไปอีกนิดเหมือนกัน เพราะว่าไม่มี driver สำหรับ elixir ติดมาด้วย. ลองเอา driver ที่ http://wiki.pylonshq.com/display/pysbook/Authentication+and+Authorization มาก็ยังใช้ไม่ได้. ก็เลยเขียนใหม่ซะโดยใช้วิธีคล้ายกับของเดิมแต่ว่าเอา sqlalchemy 0.5.x driver มาแก้ แถมด้วยแก้ c-tor ของ entity ด้วย ทำให้ใช้กับ code เก่าง่ายขึ้น นอกจากนั้นก็เอา session.add(…) ที่ไม่จำเป็นสำหรับ elixir ออกซะ (ใช่มะถ้าผมเข้าใจไม่ผิด). elixir driver for authkit ก็เขียนแบบข้างล่างครับ ยาวหน่อย

# Elixir Driver for AuthKit
# Based on the SQLAlchemy 0.5 driver
# authkit_elixir_driver.py
# modified by Vee Satayamas
#
# Copyright (c) Copyright 2005-2007 James Gardner 
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

from sqlalchemy import *
from paste.util.import_string import eval_import
from authkit.users import *

from sqlalchemy.orm import *
from elixir import *

class UsersFromDatabase(Users):
    """
    Database Version
    """
    def __init__(self, model, encrypt=None):
        print "!!! Driver"
        if encrypt is None:
            def encrypt(password):
                return password
        self.encrypt = encrypt
        if isinstance(model, (str, unicode)):
            model = eval_import(model)
        if hasattr(model, 'authkit_initialized'):
            raise AuthKitError(
                'The AuthKit database model has already been setup'
            )
        else:
            model.authkit_initialized = True

        # Update the model
        self.model = self.update_model(model)
        self.meta = self.model.meta

    def update_model(self, model):
        # following methods from a comment at
        # http://wiki.pylonshq.com/display/pysbook/Authentication+and+Authorization

        class User(Entity):
            uid = Field(Integer, primary_key=True)
            username = Field(String(255), unique=True, nullable=False)
            password = Field(String(255), nullable=False)
            group = ManyToOne("Group")
            roles = ManyToMany("Role", lazy=True) #"roles": relation(Role, lazy=True, secondary=users_roles_table),
            group = ManyToOne("Group")

            def __init__(
                self,
                username,
                uid=None,
                password=None,
                group_uid=None,
            ):
                Entity.__init__(self)
                self.uid         = uid
                self.username   = username
                self.password   = password
                self.group_uid  = group_uid

            def __repr__(self):
                return "User(%(username)s)" % self.__dict__

        class Group(Entity):
            uid = Field(Integer, primary_key=True)
            name = Field(String(255), unique=True, nullable=False)
            users = OneToMany("User")

            def __init__(self, name=None):
                Entity.__init__(self)
                self.name = name

            def __repr__(self):
                return "Group(%(name)s)" % self.__dict__

        class Role(Entity):
            uid = Field(Integer, primary_key=True)
            name = Field(String(255), unique=True, nullable=False)
            users = ManyToMany("User", lazy=True) #"users": relation(User, lazy=True, secondary=users_roles_table)

            def __init__(self, name=None):
                Entity.__init__(self)
                self.name = name

            def __repr__(self):
                return "Role(%(name)s)" % self.__dict__


        model.User = User
        model.Group = Group
        model.Role = Role
        setup_all()
        return model

    # Create Methods
    def user_create(self, username, password, group=None):
        """
        Create a new user with the username, password and group name specified.
        """
        if ' ' in username:
            raise AuthKitError("Usernames cannot contain space characters")
        if self.user_exists(username):
            raise AuthKitError("User %r already exists"%username)
        if group is None:
            new_user = self.model.User(
                username=username.lower(),
                password=self.encrypt(password)
            )
        else:
            if not self.group_exists(group):
                raise AuthKitNoSuchGroupError(
                    "There is no such group %r"%group
                )
            new_user = self.model.User(
                username=username.lower(),
                password=self.encrypt(password),
                group_uid=self.meta.Session.query(self.model.Group).\
                    filter_by(name=group.lower()).first().uid
            )
        self.meta.Session.flush()

    def role_create(self, role):
        """
        Add a new role to the system
        """
        if ' ' in role:
            raise AuthKitError("Roles cannot contain space characters")
        if self.role_exists(role):
            raise AuthKitError("Role %r already exists"%role)
        new_role = self.model.Role(role.lower())
        self.meta.Session.flush()

    def group_create(self, group):
        """
        Add a new group to the system
        """
        if ' ' in group:
            raise AuthKitError("Groups cannot contain space characters")
        if self.group_exists(group):
            raise AuthKitError("Group %r already exists"%group)
        new_group = self.model.Group(group.lower())
        self.meta.Session.flush()

    # Delete Methods
    def user_delete(self, username):
        """
        Remove the user with the specified username
        """
        user = self.meta.Session.query(self.model.User).filter_by(username=username.lower()).first()
        if user is None:
            raise AuthKitNoSuchUserError("There is no such user %r"%username)
        else:
            self.meta.Session.delete(user)
            self.meta.Session.flush()

    def role_delete(self, role):
        """
        Remove the role specified. Rasies an exception if the role is still in use.
        To delete the role and remove it from all existing users use
        ``role_delete_cascade()``
        """
        role = self.meta.Session.query(self.model.Role).filter_by(name=role.lower()).first()
        if role is None:
            raise AuthKitNoRoleUserError("There is no such role %r"%role)
        else:
            self.meta.Session.delete(role)
            self.meta.Session.flush()

    def group_delete(self, group):
        """
        Remove the group specified. Rasies an exception if the group is still in use.
        To delete the group and remove it from all existing users use ``group_delete_cascade()``
        """
        group = self.meta.Session.query(self.model.Group).filter_by(name=group.lower()).first()
        if group is None:
            raise AuthKitNoGroupUserError("There is no such group %r"%group)
        else:
            self.meta.Session.delete(group)
            self.meta.Session.flush()

    # Existence Methods
    def user_exists(self, username):
        """
        Returns ``True`` if a user exists with the given username, ``False``
        otherwise. Usernames are case insensitive.
        """
        user = self.meta.Session.query(self.model.User).filter_by(
            username=username.lower()).first()
        if user is not None:
            return True
        return False

    def role_exists(self, role):
        """
        Returns ``True`` if the role exists, ``False`` otherwise. Roles are
        case insensitive.
        """
        role = self.meta.Session.query(self.model.Role).filter_by(
            name=role.lower()).first()
        if role is not None:
            return True
        return False

    def group_exists(self, group):
        """
        Returns ``True`` if the group exists, ``False`` otherwise. Groups
        are case insensitive.
        """
        group = self.meta.Session.query(self.model.Group).filter_by(
            name=group.lower()).first()
        if group is not None:
            return True
        return False

    # List Methods
    def list_roles(self):
        """
        Returns a lowercase list of all roll names ordered alphabetically
        """
        return [r.name for r in self.meta.Session.query(
            self.model.Role).order_by(self.model.Role.name)]

    def list_users(self):
        """
        Returns a lowecase list of all usernames ordered alphabetically
        """
        return [r.username for r in self.meta.Session.query(
            self.model.User).order_by(self.model.User.username)]

    def list_groups(self):
        """
        Returns a lowercase list of all groups ordered alphabetically
        """
        return [r.name for r in self.meta.Session.query(
            self.model.Group).order_by(self.model.Group.name)]

    # User Methods
    def user(self, username):
        """
        Returns a dictionary in the following format:

        .. code-block :: Python

            {
                'username': username,
                'group':    group,
                'password': password,
                'roles':    [role1,role2,role3... etc]
            }

        The role names are ordered alphabetically
        Raises an exception if the user doesn't exist.
        """
        if not self.user_exists(username.lower()):
            raise AuthKitNoSuchUserError("No such user %r"%username.lower())
        user = self.meta.Session.query(self.model.User).filter_by(
            username=username.lower()).first()
        roles = [r.name for r in user.roles]
        roles.sort()
        return {
            'username': user.username,
            'group':    user.group and user.group.name or None,
            'password': user.password,
            'roles':    roles
        }

    def user_roles(self, username):
        """
        Returns a list of all the role names for the given username ordered
        alphabetically. Raises an exception if the username doesn't exist.
        """
        if not self.user_exists(username.lower()):
            raise AuthKitNoSuchUserError("No such user %r"%username.lower())
        roles = [r.name for r in \
            self.meta.Session.query(self.model.User).filter_by(
            username=username.lower()).first().roles]
        roles.sort()
        return roles

    def user_group(self, username):
        """
        Returns the group associated with the user or ``None`` if no group is
        associated. Raises an exception is the user doesn't exist.
        """
        if not self.user_exists(username.lower()):
            raise AuthKitNoSuchUserError("No such user %r"%username.lower())
        return self.meta.Session.query(self.model.User).filter_by(username =
            username.lower()).first().group.name

    def user_password(self, username):
        """
        Returns the password associated with the user or ``None`` if no
        password exists. Raises an exception is the user doesn't exist.
        """
        if not self.user_exists(username.lower()):
            raise AuthKitNoSuchUserError("No such user %r"%username.lower())
        return self.meta.Session.query(self.model.User).filter_by(
            username=username.lower()).first().password

    def user_has_role(self, username, role):
        """
        Returns ``True`` if the user has the role specified, ``False``
        otherwise. Raises an exception if the user doesn't exist.
        """
        if not self.user_exists(username.lower()):
            raise AuthKitNoSuchUserError("No such user %r"%username.lower())
        if not self.role_exists(role.lower()):
            raise AuthKitNoSuchRoleError("No such role %r"%role.lower())
        for role_ in self.meta.Session.query(self.model.User).filter_by(
                username=username.lower()).first().roles:
            if role_.name == role.lower():
                return True
        return False

    def user_has_group(self, username, group):
        """
        Returns ``True`` if the user has the group specified, ``False``
        otherwise. The value for ``group`` can be ``None`` to test that
        the user doesn't belong to a group. Raises an exception if the
        user doesn't exist.
        """
        if not self.user_exists(username.lower()):
            raise AuthKitNoSuchUserError("No such user %r"%username.lower())
        if group is not None and not self.group_exists(group.lower()):
            raise AuthKitNoSuchGroupError("No such group %r"%group.lower())
        user = self.meta.Session.query(self.model.User).filter_by(
            username=username.lower()).first()
        if user.group is None:
            if group == None:
                return True
        else:
            if group is not None and user.group.name == group.lower():
                return True
        return False

    def user_has_password(self, username, password):
        """
        Returns ``True`` if the user has the password specified, ``False``
        otherwise. Passwords are case sensitive. Raises an exception if the
        user doesn't exist.
        """
        if not self.user_exists(username.lower()):
            raise AuthKitNoSuchUserError("No such user %r"%username.lower())
        user = self.meta.Session.query(self.model.User).filter_by(
            username=username.lower()).first()
        if user.password == self.encrypt(password):
            return True
        return False

    def user_set_username(self, username, new_username):
        """
        Sets the user's username to the lowercase of new_username.
        Raises an exception if the user doesn't exist or if there is already
        a user with the username specified by ``new_username``.
        """
        if not self.user_exists(username.lower()):
            raise AuthKitNoSuchUserError("No such user %r"%username.lower())
        if self.user_exists(new_username.lower()):
            raise AuthKitError(
                "A user with the username %r already exists"%username.lower()
            )
        user = self.meta.Session.query(self.model.User).filter_by(
            username=username.lower()).first()
        user.username = new_username.lower()
        self.meta.Session.flush()

    def user_set_password(self, username, new_password):
        """
        Sets the user's password. Should be plain text, will be encrypted using self.encrypt
        Raises an exception if the user doesn't exist.
        """
        if not self.user_exists(username.lower()):
            raise AuthKitNoSuchUserError("No such user %r"%username.lower())
        user = self.meta.Session.query(self.model.User).filter_by(
            username=username.lower()).first()
        user.password = self.encrypt(new_password)
        self.meta.Session.flush()

    def user_set_group(self, username, group, auto_add_group=False):
        """
        Sets the user's group to the lowercase of ``group`` or ``None``. If
        the group doesn't exist and ``add_if_necessary`` is ``True`` the
        group will also be added. Otherwise an ``AuthKitNoSuchGroupError``
        will be raised. Raises an exception if the user doesn't exist.
        """
        if not self.user_exists(username.lower()):
            raise AuthKitNoSuchUserError("No such user %r"%username.lower())
        if not self.group_exists(group.lower()):
            if auto_add_group:
                self.group_create(group.lower())
            else:
                raise AuthKitNoSuchGroupError("No such group %r"%group.lower())
        user = self.meta.Session.query(self.model.User).filter_by(
            username=username.lower()).first()
        user.group = self.meta.Session.query(self.model.Group).filter_by(
            name=group.lower()).first()
        self.meta.Session.flush()

    def user_add_role(self, username, role, auto_add_role=False):
        """
        Sets the user's role to the lowercase of ``role``. If the role doesn't
        exist and ``add_if_necessary`` is ``True`` the role will also be
        added. Otherwise an ``AuthKitNoSuchRoleError`` will be raised. Raises
        an exception if the user doesn't exist.
        """
        if not self.user_exists(username.lower()):
            raise AuthKitNoSuchUserError("No such user %r"%username.lower())
        if not self.role_exists(role.lower()):
            if auto_add_role:
                self.role_create(role.lower())
            else:
                raise AuthKitNoSuchRoleError("No such role %r"%role.lower())
        user = self.meta.Session.query(self.model.User).filter_by(
            username=username.lower()).first()
        role = self.meta.Session.query(self.model.Role).filter_by(
            name=role.lower()).first()
        user.roles.append(role)
        self.meta.Session.flush()

    def user_remove_group(self, username):
        """
        Sets the group to ``None`` for the user specified by ``username``.
        Raises an exception if the user doesn't exist.
        """
        if not self.user_exists(username.lower()):
            raise AuthKitNoSuchUserError("No such user %r"%username.lower())
        user = self.meta.Session.query(self.model.User).filter_by(
            username=username.lower()).first()
        user.group = None
        self.meta.Session.flush()

    def user_remove_role(self, username, role):
        """
        Removes the role from the user specified by ``username``. Raises
        an exception if the user doesn't exist.
        """
        if not self.user_exists(username.lower()):
            raise AuthKitNoSuchUserError("No such user %r"%username.lower())
        if not self.role_exists(role.lower()):
            raise AuthKitNoSuchRoleError("No such role %r"%role.lower())
        user = self.meta.Session.query(self.model.User).filter_by(
            username=username.lower()).first()
        for role_ in user.roles:
            if role_.name == role.lower():
                user.roles.pop(user.roles.index(role_))
                self.meta.Session.flush()
                return
        raise AuthKitError(
            "No role %r found for user %r"%(role.lower(), username.lower())
        )

ในกรณีตัวอย่างของผม ผมทำ project ชื่อ auth7 ขึ้นมาแล้วก็เอา driver ไปไว้ใน auth7/users ใน auth7/users ก็มีไฟล์ __init__.py (ตามแบบ python module ทั่วไป) และ authkit_elixir_driver.py ตามที่เขียนไว้ข้างบน

__init__.py ก็เขียนตามนี้

import authkit_elixir_driver

ใน development.ini ก็เพิ่มแบบนี้เข้ามา

authkit.setup.enable = true
authkit.setup.method = form, cookie
authkit.form.authenticate.user.type = auth7.users.authkit_elixir_driver:UsersFromDatabase
authkit.form.authenticate.user.data = auth7.model
authkit.cookie.secret = SomeSec
authkit.cookie.signoutpath = /auth/signout

ใน websetup ก็เขียนแบบนี้

import logging

from auth7.config.environment import load_environment
from auth7.users.authkit_elixir_driver import UsersFromDatabase

log = logging.getLogger(__name__)

def setup_app(command, conf, vars):
    load_environment(conf.global_conf, conf.local_conf)
    from auth7.model import meta
    from auth7 import model
    from elixir import metadata
    users = UsersFromDatabase(model)
    metadata.create_all(checkfirst=True)
    users.user_create("admin", password="password")

ลืมเขียนอะไรอีกหรือเปล่านะ :-P … ว่าจะ post ที่ blog.vee-u.com ไปสักพักก่อน ไว้แก้ๆ อีกสักนิดค่อยเอาลง pylons66.com ละกัน

1

Pylons-20080827 + Authkit อย่างง่าย

ผมลองใช้ authkit ครั้งแรกก็ทำได้ง่ายๆ แต่ไม่ได้ blog ไว้ได้เรื่องทันทีพยายามทำอีกทีทำไม่ได้ T_T. แต่ก็แก้ได้ละ

แก้ config/middleware.py: โดยเพิ่ม import authkit.authenticate เข้าไป ไม่พอ

...
    # Routing/Session/Cache Middleware
    app = RoutesMiddleware(app, config['routes.map'])
    app = SessionMiddleware(app, config)
    app = CacheMiddleware(app, config)
    app = authkit.authenticate.middleware(app, app_conf) #เพิ่มบรรทัดนี้

    if asbool(full_stack):
        # Handle Python exceptions
        app = ErrorHandler(app, global_conf, **config['pylons.errorware'])

...

แก้ development.ini:

….

full_stack = false # แก้จาะ true ให้เป็น false ซึ่งยังงงๆ อยู่ว่าทำไมต้องทำแบบนี้


beaker.session.secret = somesecret

# เพิ่มพวกข้างล่างนี้
authkit.setup.method = form, cookie
authkit.form.authenticate.user.data = username:password  # ถ้ามี username password อีกก็ใส่เข้าไปบรรทัดนี้เลย
authkit.cookie.secret = SomeSec
authkit.cookie.signoutpath = /auth/signout

import logging

from pylons import request, response, session
from pylons import tmpl_context as c
from pylons.controllers.util import abort, redirect_to

from auth2.lib.base import BaseController, render

from authkit.authorize.pylons_adaptors import authorize
from authkit.permissions import RemoteUser, ValidAuthKitUser

log = logging.getLogger(__name__)

class AuthController(BaseController):
    @authorize(ValidAuthKitUser())  # บอก pylons + authkit ว่า action นี้ต้อง signin ก่อน
    def private(self):
        return 'this is private'

เท่านี้ก็ลองเข้า http://localhost:5000/auth/private ก็จะเด้งไปหน้า login พอใส่เสร็จก็เด้งกลับมา เป็นอันใช้ได้ แต่ยัง signout ไม่ได้ มั้ง เพราะยังไม่ได้เขียนเลย.

อ้างอิง

http://pylonsbook.com/alpha1/authentication_and_authorization