Merge "Add public api support to basic auth"

This commit is contained in:
Zuul 2020-07-24 15:18:30 +00:00 committed by Gerrit Code Review
commit 9ecb6e33eb
3 changed files with 55 additions and 2 deletions

View File

@ -164,6 +164,14 @@ class TestBasicAuthApiIntrospect(TestApiIntrospect):
headers=self.headers)
self.assertEqual(401, res.status_code)
def test_unauthenticated_public_api(self):
res = self.app.get('/')
self.assertEqual(200, res.status_code)
res = self.app.get('/v1')
self.assertEqual(200, res.status_code)
res = self.app.get('/v1/introspection')
self.assertEqual(401, res.status_code)
class TestApiContinue(BaseAPITest):
def test_continue(self):

View File

@ -16,12 +16,14 @@ import logging as pylog
import futurist
from ironic_lib import auth_basic
from ironic_lib import exception
from keystonemiddleware import auth_token
from openstack.baremetal.v1 import node
from oslo_config import cfg
from oslo_log import log
from oslo_middleware import cors as cors_middleware
import pytz
import webob
from ironic_inspector.common.i18n import _
from ironic_inspector import policy
@ -169,6 +171,42 @@ class NoAvailableConductor(Error):
super(NoAvailableConductor, self).__init__(msg, code=503, **kwargs)
class DeferredBasicAuthMiddleware(object):
"""Middleware which sets X-Identity-Status header based on authentication
"""
def __init__(self, app, auth_file):
self.app = app
self.auth_file = auth_file
auth_basic.validate_auth_file(auth_file)
@webob.dec.wsgify()
def __call__(self, req):
headers = req.headers
try:
if 'Authorization' not in headers:
auth_basic.unauthorized()
token = auth_basic.parse_header({
'HTTP_AUTHORIZATION': headers.get('Authorization')
})
username, password = auth_basic.parse_token(token)
headers.update(
auth_basic.authenticate(self.auth_file, username, password))
headers['X-Identity-Status'] = 'Confirmed'
except exception.Unauthorized:
headers['X-Identity-Status'] = 'Invalid'
except exception.IronicException as e:
status = '%s %s' % (int(e.code), str(e))
resp = webob.Response(status=status)
resp.headers.update(e.headers)
return resp
return req.get_response(self.app)
def executor():
"""Return the current futures executor."""
global _EXECUTOR
@ -193,7 +231,7 @@ def add_basic_auth_middleware(app):
:param app: application.
"""
app.wsgi_app = auth_basic.BasicAuthMiddleware(
app.wsgi_app = DeferredBasicAuthMiddleware(
app.wsgi_app, CONF.http_basic_auth_user_file)
@ -216,11 +254,13 @@ def check_auth(request, rule=None, target=None):
:param target: dict-like structure to check rule against
:raises: utils.Error if access is denied
"""
if CONF.auth_strategy != 'keystone':
if CONF.auth_strategy not in ('keystone', 'http_basic'):
return
if not request.context.is_public_api:
if request.headers.get('X-Identity-Status', '').lower() == 'invalid':
raise Error(_('Authentication required'), code=401)
if CONF.auth_strategy != 'keystone':
return
target = {} if target is None else target
if not policy.authorize(rule, target, request.context.to_policy_values()):
raise Error(_("Access denied by policy"), code=403)

View File

@ -0,0 +1,5 @@
---
fixes:
- |
Using auth_strategy=http_basic incorrectly required authentication for
public paths such as / and /v1. These paths are now public.