logo头像

猪老大要进步!

一行python搭建webdav

本文于 960 天之前发表,文中内容可能已经过时。

想要建一个webdav,然后研究了apache,nginx均失败,最后还是python最简单地完成了我们的要求。

一、Wsgidav

  • 官网:https://wsgidav.readthedocs.io/en/latest/index.html
  • 安装
    1
    pip install cheroot wsgidav cheroot lxml pam
  • 使用
    1
    2
    3
    wsgidav --host=0.0.0.0 --port=80 --root=/tmp --auth=anonymous # 匿名
    wsgidav --host=0.0.0.0 --port=80 --root=/tmp --auth=pam-login # Linux下账号
    wsgidav --host=0.0.0.0 --port=80 --root=/tmp --auth=nt # Windows下账号

二、大问题

Ubuntu下实测,pam模块是有问题的。经过观察代码,这是python2时代的产物,而wsgidav采用pam来验证会带来一些坑。

  • 坑1:字符报错,无效字符
    python3的print有括号的,到该路径的文件中加上去即可

  • 坑2:AttributeError: module ‘pam’ has no attribute ‘pam’
    找到文件,随便改一下,能用就行。

  • 坑3:Linux下密码登录失效,一直在报pam.authenticate错误。
    重写,反正就我一个人用。把用户名密码写死!pam_dc.py文件全文如下。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    # -*- coding: utf-8 -*-
    # (c) 2009-2020 Martin Wendt and contributors; see WsgiDAV https://github.com/mar10/wsgidav
    # Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
    """
    Implementation of a domain controller that allows users to authenticate against
    a Pluggable Authentication Module ('PAM').

    Used by HTTPAuthenticator. Only available on linux and macOS.

    See https://wsgidav.readthedocs.io/en/latest/user_guide_configure.html
    """
    from __future__ import print_function
    from wsgidav import util
    from wsgidav.dc.base_dc import BaseDomainController

    import pam


    __docformat__ = "reStructuredText"
    _logger = util.get_module_logger(__name__)


    class PAMDomainController(BaseDomainController):
    def __init__(self, wsgidav_app, config):
    super(PAMDomainController, self).__init__(wsgidav_app, config)

    self.pam = pam.PamHandle()# origin is pam.pam, replace it

    # auth_conf = config["http_authenticator"]
    dc_conf = config.get("pam_dc", {})

    self.pam_service = dc_conf.get("service", "login")
    self.pam_encoding = dc_conf.get("encoding", "utf-8")
    self.pam_resetcreds = dc_conf.get("resetcreds", True)

    def __str__(self):
    return "{}('{}')".format(self.__class__.__name__, self.pam_service)

    def get_domain_realm(self, path_info, environ):
    return "PAM({})".format(self.pam_service)

    def require_authentication(self, realm, environ):
    return True


    def verify(self, user_name,password):# write die, 写死
    if user_name=='lankning' and password=='123456':
    return True
    else:
    return False

    def basic_auth_user(self, realm, user_name, password, environ):
    pam = self.pam

    is_ok = self.verify(user_name,password)
    # pam.authenticate(
    # user_name,
    # password,
    # service=self.pam_service,
    # resetcreds=self.pam_resetcreds,
    # encoding=self.pam_encoding,
    # )
    if is_ok:
    _logger.debug("User '{}' logged on.".format(user_name))
    return True

    _logger.warning(
    "pam.authenticate('{}', '***', '{}') failed with code {}: {}".format(
    user_name, self.pam_service, pam.code, pam.reason
    )
    )
    return False

    def supports_http_digest_auth(self):
    # We don't have access to a plaintext password (or stored hash)
    return False

    这就可以用了。。。

参考:

  1. https://github.com/mar10/wsgidav/
支付宝打赏 微信打赏

赞赏是不耍流氓的鼓励