防止匿名访问CKAN网站的方法
Approach for preveting annomyous access to CKAN site
我有一个 CKAN 站点 运行 配置了 ckanext-ldap 扩展,但我只希望经过身份验证的用户无法访问该站点。
这是我目前的解决方案,但我并不完全满意:
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 密钥,但我可以接受)
如果未登录,我想不出重定向到登录页面的方法 and/or 使 "remember me" 功能正常工作。
添加如下内容:toolkit.redirect_to('/user/login') 而不是 return {'success': False} 没有效果。
我也查看了 IRoutes 接口,但我不知道如何获取当前登录的用户(或检查用户是否登录)
我认为有几种方法可以实现这一点。
可能是最简单的。您可以尝试这样的操作 suggestion to 检查用户是否在每个页面上登录,如果没有则重定向。但这让人们知道网站在那里并尝试登录。
您可以打破一些身份验证并将其放在应用程序前面的 gateway/load balancer/reverse 代理上并在那里进行身份验证(我看到类似的是 azure 与应用程序网关 运行 nginx 与 azure AD).
如果您使用的是 LDAP,我猜您可能有本地网络(可能是 Intranet?)。你也可以把它放在后面。或者创建一个阻止访问的防火墙,除非特定的网络或 IP 阻止。
Another suggestion
我在 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,例如
class Disable_Anon_AccessPlugin(plugins.SingletonPlugin):
plugins.implements(plugins.IMiddleware, inherit=True)
def make_middleware(self, app, config):
return AuthMiddleware(app, config)
我有一个 CKAN 站点 运行 配置了 ckanext-ldap 扩展,但我只希望经过身份验证的用户无法访问该站点。
这是我目前的解决方案,但我并不完全满意:
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 密钥,但我可以接受)
如果未登录,我想不出重定向到登录页面的方法 and/or 使 "remember me" 功能正常工作。
添加如下内容:toolkit.redirect_to('/user/login') 而不是 return {'success': False} 没有效果。
我也查看了 IRoutes 接口,但我不知道如何获取当前登录的用户(或检查用户是否登录)
我认为有几种方法可以实现这一点。
可能是最简单的。您可以尝试这样的操作 suggestion to 检查用户是否在每个页面上登录,如果没有则重定向。但这让人们知道网站在那里并尝试登录。
您可以打破一些身份验证并将其放在应用程序前面的 gateway/load balancer/reverse 代理上并在那里进行身份验证(我看到类似的是 azure 与应用程序网关 运行 nginx 与 azure AD).
如果您使用的是 LDAP,我猜您可能有本地网络(可能是 Intranet?)。你也可以把它放在后面。或者创建一个阻止访问的防火墙,除非特定的网络或 IP 阻止。
Another suggestion
我在 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,例如
class Disable_Anon_AccessPlugin(plugins.SingletonPlugin):
plugins.implements(plugins.IMiddleware, inherit=True)
def make_middleware(self, app, config):
return AuthMiddleware(app, config)