Monday, February 27, 2017

ADF Security - Custom Login Page to get into Application



In this article, we will see ADF security with an example.  We will create an application which has 2 pages. Page-1 is individual ADF page outside any bounded task flow and Page-2 is within bounded task flow.
User needs to login using CustomLogin.jspx page and once Login is successful, user gets landed into “HomePage.jsf” which has links to Page -1 and Page-2.
ADF security is defined at application level, by navigating to “Application->Secure->Configure ADF Security…”


This opens up a wizard, in Authentication Step, define Form-based Authentication and we can choose Login Page, Error Page or Generate Default Pages.

Define Welcome Page in Step 4 as shown below:-


CustomLogin page contains a form with username and password input text fields, as shown below:-


Once user clicks submit, LoginBean(Managed Bean) code gets invoked as shown below:-
    public void doLogin(ActionEvent event) {
         System.out.println("Entering doLogin -- START 123");
         FacesContext ctx = FacesContext.getCurrentInstance();

         if (userName == null || password == null) {
            showError("Invalid credentials",
                        "An incorrect username or password was specified.", null);
         } else {
             ExternalContext ectx = ctx.getExternalContext();
             HttpServletRequest request = (HttpServletRequest)
                                          ctx.getExternalContext().getRequest();
             try {
                 request.login(userName, password); // Servlet 3.0 login
                 userName = null;
                 password = null;

                 String loginUrl = ectx.getRequestContextPath() +"/adfAuthentication?success_url=/faces/HomePage.jsf";
                 redirect(loginUrl);
             } catch (ServletException fle) {
                 showError("ServletException", "Login failed. Please verify the username and password and try again.", null);
             }
         }
         System.out.println("EXITING doLogin -- END ");
     }
Above code redirects to Home Page which has links to Page 1 and Page 2


Page-1 is individual page outside bounded task flow which shows employee details.
Page-2 is within EmployeeTaskFlow with single page SecuredPG.
Logout code is included in LoginBean as shown below:-
    public void doLogout(ActionEvent actionEvent) {
        ExternalContext ectx = FacesContext.getCurrentInstance().getExternalContext();
        HttpSession session = (HttpSession)ectx.getSession(false); 
        session.invalidate(); 
        String loginUrl = ectx.getRequestContextPath() +"/adfAuthentication?success_url=/faces/CustomLogin.jspx";
        HttpServletRequest request = (HttpServletRequest)ectx.getRequest(); 
        ServletAuthentication.logout(request); 
        ServletAuthentication.invalidateAll(request); 
        ServletAuthentication.killCookie(request);         
        try{ 
             ectx.redirect(loginUrl); 
           } 
           catch(Exception e){ 
             e.printStackTrace(); 
           } 
           FacesContext.getCurrentInstance().responseComplete(); 
    }

We define 2 users “hasaccess” and “noaccess” and assign Application Roles by navigating to Application->Secure->Test Users & Roles


Below screenshot shows the resources to which “AllowAccess” role has access to


Below screenshot shows the resource grants to which “NoAccess” application role has access to:-


I have also used test-all application role which gives access to everyone for CustomLogin page.
Also defined Grants at “TaskFlow” level as shown below:-


You can download application from below link


Test Scenarios:-
When “hasaccess” logs in, he can navigate to Page-1 i.e.  Employee Page  as well as Page -2 i.e. SecuredPG. Whereas “noaccess” can login and see home page but get error when he clicks on those links.

P.S. : For opening Employee details Page, you need to setup database connection which is not present in attached application.

1 comment: