我有一个配置了ckanext-ldap扩展名的CKAN站点,但是我只是不认证用户才能访问该站点。
这是我的解决方案,但我并不完全满意:
import ckan.plugins as plugins
import ckan.plugins.toolkit as toolkit
def site_read(context, data_dict):
# List of allowed paths, when not logged in
allowed_anon_paths = ['/user/login', '/ldap_login_handler']
# Prevent "site read" if the user is not logged in and the
# request path is not in the list of allowed anonymous paths
if not context.get('user') and toolkit.request.path not in allowed_anon_paths:
return {'success': False}
return {'success': True}
class Disable_Anon_AccessPlugin(plugins.SingletonPlugin):
plugins.implements(plugins.IAuthFunctions)
def get_auth_functions(self):
return {'site_read': site_read}
它阻止任何登录的用户访问任何页面(与登录无关的页面除外),但是在登录之前,在所有页面上都提供了403禁止错误。
(API请求也会失败,并显示500错误,除非登录或提供API密钥,但我可以接受)
如果没有登录和/或使“记住我”功能正常工作,我无法找到重定向到登录页面的方法。
添加类似以下内容:toolkit.redirect_to('/ user / login')而不是返回{'success':False}无效。
我也查看了IRoutes界面,但无法弄清楚如何获取当前登录用户(或检查用户是否已登录)
答案 0 :(得分:0)
我认为有几种方法可以实现这一目标。
可能是最简单的。您可以尝试使用类似suggestion to的方法来检查用户是否在每个页面上都已登录,如果没有登录,则进行重定向。但这使人们知道站点在那里并尝试登录。
您可以进行一些身份验证,然后将其放在应用程序前面的网关/负载平衡器/反向代理上并在此处进行身份验证(我看到类似的应用程序网关在运行带有azure AD的nginx的应用程序网关中是azure)。>
如果您使用的是LDAP,我猜测您可能具有局域网(可能是内部网?)。您也可以将其设置为该值。或创建阻止访问的防火墙,除非特定的网络或IP阻止。
答案 1 :(得分:0)
我已经看到CKAN中使用了以下方法来防止对网站的未登录访问。
它使用IMiddleware
插件界面:
class AuthMiddleware(object):
def __init__(self, app, app_conf):
self.app = app
def __call__(self, environ, start_response):
# if logged in via browser cookies or API key, all pages accessible
if 'repoze.who.identity' in environ or self._get_user_for_apikey(environ) or not is_iar():
return self.app(environ,start_response)
else:
# otherwise only login/reset and front pages are accessible
if (environ['PATH_INFO'] == '/' or environ['PATH_INFO'] == '/user/login' or environ['PATH_INFO'] == '/user/_logout'
or '/user/reset' in environ['PATH_INFO'] or environ['PATH_INFO'] == '/user/logged_out'
or environ['PATH_INFO'] == '/user/logged_in' or environ['PATH_INFO'] == '/user/logged_out_redirect'):
return self.app(environ,start_response)
else:
# http://rufuspollock.org/2006/09/28/wsgi-middleware/
environ['wsgiorg.routing_args'] = '',{'action': 'login', 'controller': 'user'}
return self.app(environ,start_response)
def _get_user_for_apikey(self, environ):
# Adapted from https://github.com/ckan/ckan/blob/625b51cdb0f1697add59c7e3faf723a48c8e04fd/ckan/lib/base.py#L396
apikey_header_name = config.get(base.APIKEY_HEADER_NAME_KEY,
base.APIKEY_HEADER_NAME_DEFAULT)
apikey = environ.get(apikey_header_name, '')
if not apikey:
# For misunderstanding old documentation (now fixed).
apikey = environ.get('HTTP_AUTHORIZATION', '')
if not apikey:
apikey = environ.get('Authorization', '')
# Forget HTTP Auth credentials (they have spaces).
if ' ' in apikey:
apikey = ''
if not apikey:
return None
apikey = unicode(apikey)
# check if API key is valid by comparing against keys of registered users
query = model.Session.query(model.User)
user = query.filter_by(apikey=apikey).first()
return user
然后将哪个添加到您的插件类中,例如
class Disable_Anon_AccessPlugin(plugins.SingletonPlugin):
plugins.implements(plugins.IMiddleware, inherit=True)
def make_middleware(self, app, config):
return AuthMiddleware(app, config)