mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Enable mod_proxy to sit in front of TurboGears and pass along the
kerberos principal name Add an identity an visit class to TurboGears that can handle the user without requiring a database Update the UI to show the user correctly. Note that this is currently disabled. It is hardcoded to always return the principal test@FREEIPA.ORG in proxyprovider.py It doesn't handle an unauthorized request because that can never happen.
This commit is contained in:
parent
37d10e0c51
commit
182fbe3094
@ -13,8 +13,19 @@
|
|||||||
|
|
||||||
# If you have sqlite, here's a simple default to get you started
|
# If you have sqlite, here's a simple default to get you started
|
||||||
# in development
|
# in development
|
||||||
sqlobject.dburi="sqlite://%(current_dir_uri)s/devdata.sqlite"
|
# sqlobject.dburi="sqlite://%(current_dir_uri)s/devdata.sqlite"
|
||||||
|
|
||||||
|
# Our our sqlobject-derived proxy provider
|
||||||
|
identity.provider='proxyprovider'
|
||||||
|
|
||||||
|
# the first thing checked on any request. We want to short-circuit this
|
||||||
|
# as early as possible
|
||||||
|
identity.source = 'visit'
|
||||||
|
|
||||||
|
# Turn on identity and visit (visit is required for identity)
|
||||||
|
identity.on=True
|
||||||
|
visit.on=True
|
||||||
|
visit.manager='proxyvisit'
|
||||||
|
|
||||||
# if you are using a database or table type without transactions
|
# if you are using a database or table type without transactions
|
||||||
# (MySQL default, for example), you should turn off transactions
|
# (MySQL default, for example), you should turn off transactions
|
||||||
|
@ -4,6 +4,7 @@ start-ipagui.py
|
|||||||
ipa_gui.egg-info/PKG-INFO
|
ipa_gui.egg-info/PKG-INFO
|
||||||
ipa_gui.egg-info/SOURCES.txt
|
ipa_gui.egg-info/SOURCES.txt
|
||||||
ipa_gui.egg-info/dependency_links.txt
|
ipa_gui.egg-info/dependency_links.txt
|
||||||
|
ipa_gui.egg-info/entry_points.txt
|
||||||
ipa_gui.egg-info/not-zip-safe
|
ipa_gui.egg-info/not-zip-safe
|
||||||
ipa_gui.egg-info/paster_plugins.txt
|
ipa_gui.egg-info/paster_plugins.txt
|
||||||
ipa_gui.egg-info/requires.txt
|
ipa_gui.egg-info/requires.txt
|
||||||
@ -13,8 +14,14 @@ ipagui/__init__.py
|
|||||||
ipagui/controllers.py
|
ipagui/controllers.py
|
||||||
ipagui/json.py
|
ipagui/json.py
|
||||||
ipagui/model.py
|
ipagui/model.py
|
||||||
|
ipagui/proxyprovider.py
|
||||||
|
ipagui/proxyvisit.py
|
||||||
ipagui/release.py
|
ipagui/release.py
|
||||||
ipagui/config/__init__.py
|
ipagui/config/__init__.py
|
||||||
|
ipagui/forms/__init__.py
|
||||||
|
ipagui/forms/user.py
|
||||||
|
ipagui/helpers/__init__.py
|
||||||
|
ipagui/helpers/userhelper.py
|
||||||
ipagui/templates/__init__.py
|
ipagui/templates/__init__.py
|
||||||
ipagui/tests/__init__.py
|
ipagui/tests/__init__.py
|
||||||
ipagui/tests/test_controllers.py
|
ipagui/tests/test_controllers.py
|
||||||
|
6
ipa-server/ipa-gui/ipa_gui.egg-info/entry_points.txt
Normal file
6
ipa-server/ipa-gui/ipa_gui.egg-info/entry_points.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
[turbogears.identity.provider]
|
||||||
|
proxyprovider = ipagui.proxyprovider:ProxyIdentityProvider
|
||||||
|
|
||||||
|
[turbogears.visit.manager]
|
||||||
|
proxyvisit = ipagui.proxyvisit:ProxyVisitManager
|
@ -8,6 +8,7 @@ from turbogears import controllers, expose, flash
|
|||||||
from turbogears import validators, validate
|
from turbogears import validators, validate
|
||||||
from turbogears import widgets, paginate
|
from turbogears import widgets, paginate
|
||||||
from turbogears import error_handler
|
from turbogears import error_handler
|
||||||
|
from turbogears import identity
|
||||||
# from model import *
|
# from model import *
|
||||||
# import logging
|
# import logging
|
||||||
# log = logging.getLogger("ipagui.controllers")
|
# log = logging.getLogger("ipagui.controllers")
|
||||||
@ -27,7 +28,6 @@ user_edit_form = forms.user.UserEditForm()
|
|||||||
password_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
password_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||||
|
|
||||||
client = ipa.ipaclient.IPAClient(True)
|
client = ipa.ipaclient.IPAClient(True)
|
||||||
client.set_principal("test@FREEIPA.ORG")
|
|
||||||
|
|
||||||
user_fields = ['*', 'nsAccountLock']
|
user_fields = ['*', 'nsAccountLock']
|
||||||
|
|
||||||
@ -45,10 +45,12 @@ def utf8_encode(value):
|
|||||||
class Root(controllers.RootController):
|
class Root(controllers.RootController):
|
||||||
|
|
||||||
@expose(template="ipagui.templates.welcome")
|
@expose(template="ipagui.templates.welcome")
|
||||||
|
@identity.require(identity.not_anonymous())
|
||||||
def index(self):
|
def index(self):
|
||||||
return dict()
|
return dict()
|
||||||
|
|
||||||
@expose()
|
@expose()
|
||||||
|
@identity.require(identity.not_anonymous())
|
||||||
def topsearch(self, **kw):
|
def topsearch(self, **kw):
|
||||||
if kw.get('searchtype') == "Users":
|
if kw.get('searchtype') == "Users":
|
||||||
return self.userlist(uid=kw.get('searchvalue'))
|
return self.userlist(uid=kw.get('searchvalue'))
|
||||||
@ -62,6 +64,7 @@ class Root(controllers.RootController):
|
|||||||
########
|
########
|
||||||
|
|
||||||
@expose("ipagui.templates.usernew")
|
@expose("ipagui.templates.usernew")
|
||||||
|
@identity.require(identity.not_anonymous())
|
||||||
def usernew(self, tg_errors=None):
|
def usernew(self, tg_errors=None):
|
||||||
"""Displays the new user form"""
|
"""Displays the new user form"""
|
||||||
if tg_errors:
|
if tg_errors:
|
||||||
@ -70,9 +73,11 @@ class Root(controllers.RootController):
|
|||||||
return dict(form=user_new_form)
|
return dict(form=user_new_form)
|
||||||
|
|
||||||
@expose()
|
@expose()
|
||||||
|
@identity.require(identity.not_anonymous())
|
||||||
def usercreate(self, **kw):
|
def usercreate(self, **kw):
|
||||||
"""Creates a new user"""
|
"""Creates a new user"""
|
||||||
restrict_post()
|
restrict_post()
|
||||||
|
client.set_principal(identity.current.user_name)
|
||||||
if kw.get('submit') == 'Cancel':
|
if kw.get('submit') == 'Cancel':
|
||||||
turbogears.flash("Add user cancelled")
|
turbogears.flash("Add user cancelled")
|
||||||
raise turbogears.redirect('/userlist')
|
raise turbogears.redirect('/userlist')
|
||||||
@ -104,11 +109,13 @@ class Root(controllers.RootController):
|
|||||||
|
|
||||||
|
|
||||||
@expose("ipagui.templates.useredit")
|
@expose("ipagui.templates.useredit")
|
||||||
|
@identity.require(identity.not_anonymous())
|
||||||
def useredit(self, uid, tg_errors=None):
|
def useredit(self, uid, tg_errors=None):
|
||||||
"""Displays the edit user form"""
|
"""Displays the edit user form"""
|
||||||
if tg_errors:
|
if tg_errors:
|
||||||
turbogears.flash("There was a problem with the form!")
|
turbogears.flash("There was a problem with the form!")
|
||||||
|
|
||||||
|
client.set_principal(identity.current.user_name)
|
||||||
user = client.get_user_by_uid(uid, user_fields)
|
user = client.get_user_by_uid(uid, user_fields)
|
||||||
user_dict = user.toDict()
|
user_dict = user.toDict()
|
||||||
# Edit shouldn't fill in the password field.
|
# Edit shouldn't fill in the password field.
|
||||||
@ -121,9 +128,11 @@ class Root(controllers.RootController):
|
|||||||
return dict(form=user_edit_form, user=user_dict)
|
return dict(form=user_edit_form, user=user_dict)
|
||||||
|
|
||||||
@expose()
|
@expose()
|
||||||
|
@identity.require(identity.not_anonymous())
|
||||||
def userupdate(self, **kw):
|
def userupdate(self, **kw):
|
||||||
"""Updates an existing user"""
|
"""Updates an existing user"""
|
||||||
restrict_post()
|
restrict_post()
|
||||||
|
client.set_principal(identity.current.user_name)
|
||||||
if kw.get('submit') == 'Cancel Edit':
|
if kw.get('submit') == 'Cancel Edit':
|
||||||
turbogears.flash("Edit user cancelled")
|
turbogears.flash("Edit user cancelled")
|
||||||
raise turbogears.redirect('/usershow', uid=kw.get('uid'))
|
raise turbogears.redirect('/usershow', uid=kw.get('uid'))
|
||||||
@ -169,8 +178,10 @@ class Root(controllers.RootController):
|
|||||||
|
|
||||||
|
|
||||||
@expose("ipagui.templates.userlist")
|
@expose("ipagui.templates.userlist")
|
||||||
|
@identity.require(identity.not_anonymous())
|
||||||
def userlist(self, **kw):
|
def userlist(self, **kw):
|
||||||
"""Retrieve a list of all users and display them in one huge list"""
|
"""Retrieve a list of all users and display them in one huge list"""
|
||||||
|
client.set_principal(identity.current.user_name)
|
||||||
users = None
|
users = None
|
||||||
counter = 0
|
counter = 0
|
||||||
uid = kw.get('uid')
|
uid = kw.get('uid')
|
||||||
@ -190,8 +201,10 @@ class Root(controllers.RootController):
|
|||||||
|
|
||||||
|
|
||||||
@expose("ipagui.templates.usershow")
|
@expose("ipagui.templates.usershow")
|
||||||
|
@identity.require(identity.not_anonymous())
|
||||||
def usershow(self, uid):
|
def usershow(self, uid):
|
||||||
"""Retrieve a single user for display"""
|
"""Retrieve a single user for display"""
|
||||||
|
client.set_principal(identity.current.user_name)
|
||||||
try:
|
try:
|
||||||
user = client.get_user_by_uid(uid, user_fields)
|
user = client.get_user_by_uid(uid, user_fields)
|
||||||
return dict(user=user.toDict(), fields=forms.user.UserFields())
|
return dict(user=user.toDict(), fields=forms.user.UserFields())
|
||||||
@ -200,10 +213,12 @@ class Root(controllers.RootController):
|
|||||||
raise turbogears.redirect("/")
|
raise turbogears.redirect("/")
|
||||||
|
|
||||||
@validate(form=user_new_form)
|
@validate(form=user_new_form)
|
||||||
|
@identity.require(identity.not_anonymous())
|
||||||
def usercreatevalidate(self, tg_errors=None, **kw):
|
def usercreatevalidate(self, tg_errors=None, **kw):
|
||||||
return tg_errors, kw
|
return tg_errors, kw
|
||||||
|
|
||||||
@validate(form=user_edit_form)
|
@validate(form=user_edit_form)
|
||||||
|
@identity.require(identity.not_anonymous())
|
||||||
def userupdatevalidate(self, tg_errors=None, **kw):
|
def userupdatevalidate(self, tg_errors=None, **kw):
|
||||||
return tg_errors, kw
|
return tg_errors, kw
|
||||||
|
|
||||||
@ -222,10 +237,12 @@ class Root(controllers.RootController):
|
|||||||
return password
|
return password
|
||||||
|
|
||||||
@expose()
|
@expose()
|
||||||
|
@identity.require(identity.not_anonymous())
|
||||||
def suggest_uid(self, givenname, sn):
|
def suggest_uid(self, givenname, sn):
|
||||||
if (len(givenname) == 0) or (len(sn) == 0):
|
if (len(givenname) == 0) or (len(sn) == 0):
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
client.set_principal(identity.current.user_name)
|
||||||
givenname = givenname.lower()
|
givenname = givenname.lower()
|
||||||
sn = sn.lower()
|
sn = sn.lower()
|
||||||
|
|
||||||
@ -309,7 +326,9 @@ class Root(controllers.RootController):
|
|||||||
#########
|
#########
|
||||||
|
|
||||||
@expose("ipagui.templates.groupindex")
|
@expose("ipagui.templates.groupindex")
|
||||||
|
@identity.require(identity.not_anonymous())
|
||||||
def groupindex(self, tg_errors=None):
|
def groupindex(self, tg_errors=None):
|
||||||
|
client.set_principal(identity.current.user_name)
|
||||||
return dict()
|
return dict()
|
||||||
|
|
||||||
|
|
||||||
@ -318,5 +337,7 @@ class Root(controllers.RootController):
|
|||||||
############
|
############
|
||||||
|
|
||||||
@expose("ipagui.templates.resindex")
|
@expose("ipagui.templates.resindex")
|
||||||
|
@identity.require(identity.not_anonymous())
|
||||||
def resindex(self, tg_errors=None):
|
def resindex(self, tg_errors=None):
|
||||||
|
client.set_principal(identity.current.user_name)
|
||||||
return dict()
|
return dict()
|
||||||
|
118
ipa-server/ipa-gui/ipagui/proxyprovider.py
Normal file
118
ipa-server/ipa-gui/ipagui/proxyprovider.py
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
from turbogears.identity.soprovider import *
|
||||||
|
from turbogears.identity.visitor import *
|
||||||
|
import logging
|
||||||
|
|
||||||
|
log = logging.getLogger("turbogears.identity")
|
||||||
|
|
||||||
|
class IPA_User(object):
|
||||||
|
'''
|
||||||
|
Shell of a User definition. We don't really need much here.
|
||||||
|
'''
|
||||||
|
|
||||||
|
def __init__(self, user_name):
|
||||||
|
self.user_name = user_name
|
||||||
|
self.display_name = user_name
|
||||||
|
self.permissions = None
|
||||||
|
self.groups = None
|
||||||
|
return
|
||||||
|
|
||||||
|
class ProxyIdentity(object):
|
||||||
|
def __init__(self, visit_key, user=None):
|
||||||
|
if user:
|
||||||
|
self._user= user
|
||||||
|
self.visit_key= visit_key
|
||||||
|
|
||||||
|
def _get_user(self):
|
||||||
|
try:
|
||||||
|
return self._user
|
||||||
|
except AttributeError:
|
||||||
|
# User hasn't already been set
|
||||||
|
return None
|
||||||
|
user= property(_get_user)
|
||||||
|
|
||||||
|
def _get_user_name(self):
|
||||||
|
if not self.user:
|
||||||
|
return None
|
||||||
|
return self.user.user_name
|
||||||
|
user_name= property(_get_user_name)
|
||||||
|
|
||||||
|
def _get_name(self):
|
||||||
|
if not self.user:
|
||||||
|
return None
|
||||||
|
return self.user.name
|
||||||
|
user_name= property(_get_name)
|
||||||
|
|
||||||
|
def _get_anonymous(self):
|
||||||
|
return not self.user
|
||||||
|
anonymous= property(_get_anonymous)
|
||||||
|
|
||||||
|
def _get_permissions(self):
|
||||||
|
try:
|
||||||
|
return self._permissions
|
||||||
|
except AttributeError:
|
||||||
|
# Permissions haven't been computed yet
|
||||||
|
return None
|
||||||
|
permissions= property(_get_permissions)
|
||||||
|
|
||||||
|
def _get_groups(self):
|
||||||
|
try:
|
||||||
|
return self._groups
|
||||||
|
except AttributeError:
|
||||||
|
# Groups haven't been computed yet
|
||||||
|
return None
|
||||||
|
groups= property(_get_groups)
|
||||||
|
|
||||||
|
def logout(self):
|
||||||
|
'''
|
||||||
|
Remove the link between this identity and the visit.
|
||||||
|
'''
|
||||||
|
# Clear the current identity
|
||||||
|
anon= ProxyObjectIdentity(None,None)
|
||||||
|
#XXX if user is None anonymous will be true, no need to set attr.
|
||||||
|
#anon.anonymous= True
|
||||||
|
identity.set_current_identity( anon )
|
||||||
|
|
||||||
|
class ProxyIdentityProvider(SqlObjectIdentityProvider):
|
||||||
|
'''
|
||||||
|
IdentityProvider that uses REMOTE_USER from Apache
|
||||||
|
'''
|
||||||
|
def __init__(self):
|
||||||
|
super(ProxyIdentityProvider, self).__init__()
|
||||||
|
get = turbogears.config.get
|
||||||
|
# We can get any config variables here
|
||||||
|
log.info( "Proxy Identity starting" )
|
||||||
|
|
||||||
|
def create_provider_model(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def validate_identity(self, user_name, password, visit_key):
|
||||||
|
user = IPA_User(user_name)
|
||||||
|
log.debug( "validate_identity %s" % user_name)
|
||||||
|
|
||||||
|
return ProxyIdentity(visit_key, user)
|
||||||
|
|
||||||
|
def validate_password(self, user, user_name, password):
|
||||||
|
'''Validation has already occurred in the proxy'''
|
||||||
|
return True
|
||||||
|
|
||||||
|
def load_identity(self, visit_key):
|
||||||
|
try:
|
||||||
|
# user_name= cherrypy.request.headers['X-FORWARDED-USER']
|
||||||
|
user_name= "test@FREEIPA.ORG"
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
set_login_attempted( True )
|
||||||
|
return self.validate_identity( user_name, None, visit_key )
|
||||||
|
|
||||||
|
def anonymous_identity( self ):
|
||||||
|
'''
|
||||||
|
This shouldn't ever happen in IPA but including it to include the
|
||||||
|
entire identity API.
|
||||||
|
'''
|
||||||
|
return ProxyIdentity( None )
|
||||||
|
|
||||||
|
def authenticated_identity(self, user):
|
||||||
|
'''
|
||||||
|
Constructs Identity object for user that has no associated visit_key.
|
||||||
|
'''
|
||||||
|
return ProxyIdentity(None, user)
|
25
ipa-server/ipa-gui/ipagui/proxyvisit.py
Normal file
25
ipa-server/ipa-gui/ipagui/proxyvisit.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
from turbogears.visit.api import BaseVisitManager, Visit
|
||||||
|
from turbogears import config
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
log = logging.getLogger("turbogears.visit.proxyvisit")
|
||||||
|
|
||||||
|
class ProxyVisitManager(BaseVisitManager):
|
||||||
|
"""Virtually empty class just so can avoid saving this stuff in a
|
||||||
|
database."""
|
||||||
|
def __init__(self, timeout):
|
||||||
|
super(ProxyVisitManager,self).__init__(timeout)
|
||||||
|
return
|
||||||
|
|
||||||
|
def create_model(self):
|
||||||
|
return
|
||||||
|
|
||||||
|
def new_visit_with_key(self, visit_key):
|
||||||
|
return Visit(visit_key, True)
|
||||||
|
|
||||||
|
def visit_for_key(self, visit_key):
|
||||||
|
return Visit(visit_key, False)
|
||||||
|
|
||||||
|
def update_queued_visits(self, queue):
|
||||||
|
return None
|
@ -14,15 +14,6 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body py:match="item.tag=='{http://www.w3.org/1999/xhtml}body'" py:attrs="item.items()">
|
<body py:match="item.tag=='{http://www.w3.org/1999/xhtml}body'" py:attrs="item.items()">
|
||||||
<div py:if="tg.config('identity.on') and not defined('logging_in')" id="pageLogin">
|
|
||||||
<span py:if="tg.identity.anonymous">
|
|
||||||
<a href="${tg.url('/login')}">Login</a>
|
|
||||||
</span>
|
|
||||||
<span py:if="not tg.identity.anonymous">
|
|
||||||
Welcome ${tg.identity.user.display_name}.
|
|
||||||
<a href="${tg.url('/logout')}">Logout</a>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="header">
|
<div id="header">
|
||||||
<div id="logo">
|
<div id="logo">
|
||||||
@ -33,7 +24,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="headerinfo">
|
<div id="headerinfo">
|
||||||
<div id="login">
|
<div id="login">
|
||||||
Logged in as: ace
|
<div py:if="tg.config('identity.on') and not defined('logging_in')" id="pageLogin">
|
||||||
|
<span py:if="tg.identity.anonymous">
|
||||||
|
<a href="${tg.url('/login')}">Login</a>
|
||||||
|
</span>
|
||||||
|
<span py:if="not tg.identity.anonymous">
|
||||||
|
Logged in as: ${tg.identity.user.display_name}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div id="topsearch">
|
<div id="topsearch">
|
||||||
<form action="${tg.url('/topsearch')}" method="post">
|
<form action="${tg.url('/topsearch')}" method="post">
|
||||||
|
@ -58,5 +58,11 @@ setup(
|
|||||||
# 'Framework :: TurboGears :: Widgets',
|
# 'Framework :: TurboGears :: Widgets',
|
||||||
],
|
],
|
||||||
test_suite = 'nose.collector',
|
test_suite = 'nose.collector',
|
||||||
|
entry_points = """
|
||||||
|
[turbogears.identity.provider]
|
||||||
|
proxyprovider = ipagui.proxyprovider:ProxyIdentityProvider
|
||||||
|
[turbogears.visit.manager]
|
||||||
|
proxyvisit = ipagui.proxyvisit:ProxyVisitManager
|
||||||
|
""",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
# LoadModule auth_kerb_module modules/mod_auth_kerb.so
|
# LoadModule auth_kerb_module modules/mod_auth_kerb.so
|
||||||
|
|
||||||
Alias /ipa "/usr/share/ipa/ipaserver/XMLRPC"
|
# Require kerberos authentication for the entire server
|
||||||
|
|
||||||
<Directory "/usr/share/ipa/ipaserver">
|
<LocationMatch />
|
||||||
AuthType Kerberos
|
AuthType Kerberos
|
||||||
AuthName "Kerberos Login"
|
AuthName "Kerberos Login"
|
||||||
KrbMethodNegotiate on
|
KrbMethodNegotiate on
|
||||||
@ -13,6 +13,37 @@ Alias /ipa "/usr/share/ipa/ipaserver/XMLRPC"
|
|||||||
KrbSaveCredentials on
|
KrbSaveCredentials on
|
||||||
Require valid-user
|
Require valid-user
|
||||||
ErrorDocument 401 /errors/unauthorized.html
|
ErrorDocument 401 /errors/unauthorized.html
|
||||||
|
</LocationMatch>
|
||||||
|
|
||||||
|
ProxyRequests Off
|
||||||
|
|
||||||
|
<Proxy *>
|
||||||
|
RewriteEngine on
|
||||||
|
Order deny,allow
|
||||||
|
Allow from all
|
||||||
|
|
||||||
|
# We create a subrequest to find REMOTE_USER. Don't do this for every
|
||||||
|
# subrequest too (slow and huge logs result)
|
||||||
|
RewriteCond %{IS_SUBREQ}% false
|
||||||
|
RewriteRule .* - [E=RU:%{LA-U:REMOTE_USER}]
|
||||||
|
RequestHeader set X-Forwarded-User %{RU}e
|
||||||
|
|
||||||
|
# RequestHeader unset Authorization
|
||||||
|
</Proxy>
|
||||||
|
|
||||||
|
# The URI's with a trailing ! are those that aren't handled by the proxy
|
||||||
|
ProxyPass /errors/ !
|
||||||
|
ProxyPass /ipa !
|
||||||
|
ProxyPass / http://localhost:8080/
|
||||||
|
ProxyPassReverse /errors !
|
||||||
|
ProxyPassReverse /ipa !
|
||||||
|
ProxyPassReverse / http://localhost:8080/
|
||||||
|
|
||||||
|
# Configure the XML-RPC service
|
||||||
|
|
||||||
|
Alias /ipa "/usr/share/ipa/ipaserver/XMLRPC"
|
||||||
|
|
||||||
|
<Directory "/usr/share/ipa/ipaserver">
|
||||||
|
|
||||||
SetHandler mod_python
|
SetHandler mod_python
|
||||||
PythonHandler ipaxmlrpc
|
PythonHandler ipaxmlrpc
|
||||||
@ -22,3 +53,4 @@ Alias /ipa "/usr/share/ipa/ipaserver/XMLRPC"
|
|||||||
# this is pointless to use since it would just reload ipaxmlrpc.py
|
# this is pointless to use since it would just reload ipaxmlrpc.py
|
||||||
PythonAutoReload Off
|
PythonAutoReload Off
|
||||||
</Directory>
|
</Directory>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user