Securing the application

Before we get going, let's go ahead and plug-in some security. In the security chapter, we discussed how security can be conveniently added after the fact. But it's even better if we start with it first. We will do so by adding a simple login page, and hard wiring three accounts: a customer, a bank manager, and a bank supervisor.

  1. Let's revise the boot strap main with some extra features to turn on security.
    import cherrypy
    import os
    from springpython.context import ApplicationContext
    from springpython.security.context import *
    from ctx2 import *
    if __name__ == '__main__':
    cherrypy.config.update({'server.socket_port': 8009})
    ctx = ApplicationContext(SpringBankAppContext())
    SecurityContextHolder.setStrategy(SecurityContextHolder.MODE_GLOBAL)
    SecurityContextHolder.getContext()
    conf = {"/": {"tools.sessions.on":True,
    "tools.filterChainProxy.on":True}}
    cherrypy.tree.mount(
    ctx.get_object("view"),
    '/',
    config=conf)
    cherrypy.engine.start()
    cherrypy.engine.block()
    

    First of all, we need to initialize the security context settings stored in SecurityContextHolder. Another thing required by CherryPy is turning on HTTP sessions. We also must activate the filterChainProxy. Spring Python's FilterChainProxy, setup in our application context, automatically registers itself as a CherryPy tool.

  2. Let's add the security components to our IoC configuration.
    from springpython.config import PythonConfig, Object
    from springpython.security.providers import *
    from springpython.security.providers.dao import *
    from springpython.security.userdetails import *
    from springpython.security.vote import *
    from springpython.security.web import *
    from springpython.security.cherrypy3 import *
    from app2 import *
    class SpringBankAppContext(PythonConfig):
    def __init__(self):
    PythonConfig.__init__(self)
    @Object
    banking applicationsecuringdef view(self):
    view = SpringBankView()
    view.auth_provider = self.auth_provider()
    view.filter = self.auth_processing_filter()
    view.http_context_filter = self.httpSessionContextIntegrationFilter()
    return view
    @Object
    def filterChainProxy(self):
    return CP3FilterChainProxy(filterInvocationDefinitionSource =
    [
    ("/login.*", ["httpSessionContextIntegrationFilter"]),
    ("/.*", ["httpSessionContextIntegrationFilter",
    "exception_translation_filter",
    "auth_processing_filter",
    "filter_security_interceptor"])
    ])
    @Object
    def httpSessionContextIntegrationFilter(self):
    filter = HttpSessionContextIntegrationFilter()
    filter.sessionStrategy = self.session_strategy()
    return filter
    @Object
    def session_strategy(self):
    return CP3SessionStrategy()
    @Object
    def exception_translation_filter(self):
    filter = ExceptionTranslationFilter()
    filter.authenticationEntryPoint = self.auth_filter_entry_pt()
    filter.accessDeniedHandler = self.accessDeniedHandler()
    return filter
    @Object
    def auth_filter_entry_pt(self):
    filter = AuthenticationProcessingFilterEntryPoint()
    filter.loginFormUrl = "/login"
    filter.redirectStrategy = self.redirectStrategy()
    return filter
    @Object
    def accessDeniedHandler(self):
    handler = SimpleAccessDeniedHandler()
    handler.errorPage = "/accessDenied"
    handler.redirectStrategy = self.redirectStrategy()
    return handler
    @Object
    def redirectStrategy(self):
    return CP3RedirectStrategy()
    @Object
    def auth_processing_filter(self):
    filter = AuthenticationProcessingFilter()
    filter.auth_manager = self.auth_manager()
    filter.alwaysReauthenticate = False
    return filter
    @Object
    def auth_manager(self):
    auth_manager = AuthenticationManager()
    auth_manager.auth_providers = [self.auth_provider()]
    return auth_manager
    @Object
    def auth_provider(self):
    provider = DaoAuthenticationProvider()
    provider.user_details_service = self.user_details_service()
    provider.password_encoder = PlaintextPasswordEncoder()
    return provider
    @Object
    def user_details_service(self):
    user_details_service = InMemoryUserDetailsService()
    user_details_service.user_dict = {
    "alice": ("alicespassword",["ROLE_CUSTOMER"], True),
    "bob": ("bobspassword", ["ROLE_MGR"], True),
    "carol": ("carolspassword", ["ROLE_SUPERVISOR"], True)
    }
    return user_details_service
    @Object
    def filter_security_interceptor(self):
    filter = FilterSecurityInterceptor()
    filter.auth_manager = self.auth_manager()
    filter.access_decision_mgr = self.access_decision_mgr()
    filter.sessionStrategy = self.session_strategy()
    filter.obj_def_source = [
    ("/.*", ["ROLE_CUSTOMER", "ROLE_MGR", "ROLE_SUPERVISOR"])
    ]
    return filter
    @Object
    def access_decision_mgr(self):
    access_decision_mgr = AffirmativeBased()
    access_decision_mgr.allow_if_all_abstain = False
    access_decision_mgr.access_decision_voters = [RoleVoter()]
    return access_decision_mgr
    

    This is admittedly a lot of code to add to our application context. Spring Python requires a lot of steps to add the security components, a fate shared by the Spring Security project. They spent a considerable amount of effort reducing the amount of code needed to configure security for typical configurations. Hopefully in the future Spring Python can be improved in a similar fashion.

  3. Let's change the core app, so that it has a login page and can handle logging in and logging out.
    import cherrypy
    from springpython.security import *
    from springpython.security.providers import *
    from springpython.security.context import *
    class SpringBankView(object):
    def __init__(self):
    self.filter = None
    self.auth_provider = None
    self.http_context_filter = None
    @cherrypy.expose
    def index(self):
    return """
    Welcome to SpringBank!
    <p>
    <p>
    <a href="logout">Logout</a href>
    """
    @cherrypy.expose
    def login(self, from_page="/", login="", password="", error_msg=""):
    if login != "" and password != "":
    try:
    self.attempt_auth(login, password)
    raise cherrypy.HTTPRedirect(from_page)
    except AuthenticationException, e:
    raise cherrypy.HTTPRedirect(
    "?login=%s&error_msg=Username/password failure"
    % login)
    return """
    %s<p>
    <form method="POST" action="">
    <table>
    <tr>
    <td>Login:</td>
    <td><input type="text" name="login"
    value="%s"/></td>
    </tr>
    <tr>
    <td>Password:</td>
    <td>
    <input type="password" name="password"/> </td>
    </tr>
    </table>
    <input type="hidden" name="from_page"
    value="%s"/><br/>
    <input type="submit"/>
    </form>
    """ % (error_msg, login, from_page)
    def attempt_auth(self, username, password):
    token = UsernamePasswordAuthenticationToken(username, password)
    SecurityContextHolder.getContext().authentication = 
    self.auth_provider.authenticate(token)
    self.http_context_filter.saveContext()
    @cherrypy.expose
    def logout(self):
    self.filter.logout()
    self.http_context_filter.saveContext()
    raise cherrypy.HTTPRedirect("/")
    Here we have slightly altered index, so that it prints our 'welcome' but also offers a hyperlink to logout. We have also added a /login link that either attempts to log the user in, or displays an HTML form so the user can attempt to login.
    

    Here we have slightly altered index, so that it prints our 'welcome' but also offers a hyperlink to logout. We have also added a /login link that either attempts to log the user in, or displays an HTML form so the user can attempt to login.

  4. With these changes in place, let's restart the app, and open up the browser.
Securing the application

As you can see, we are now looking at a very simple login screen. If we look at the shell in which our updated application is running, we can see what has happened.

Securing the application

We pointed our browser at the root URL, but Spring Python's security filter noticed we had no credentials, so it redirected us to /login.

  1. Let's login as Bob the bank manager.
Securing the application

Now we have logged in to our SpringBank web site. With the security in place, we should easily be able to start adding more features and control who can access what.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.13.192