# Page Flow Authentication

The following topic explains how to login in users using a nested page flow and then return the logged in user to the original Action in the nesting page flow.

You should not use a <security-constraint> in the WEB-INF/web.xml file to implement this form of security. Instead, use the @jpf:action login-required annotation to protect individual Action methods within the page flow file.

## Requiring Login

You can protect an individual Action method within a page flow from non-logged in users with the @jpf:action login-required="true" annotation. If a non-logged in user tries to access this method, a NotLoggedInException will be thrown. To catch this exception and send the user to another (nested) page flow where they can be logged in, use the @jpf:catch annotation.

On the nesting (parent) page flow...

        /**
         * If a non-logged in user calls this Action, a NotLoggedInException is thrown
         * (this is because login-required is set to "true").  The exception is caught
         * and the user is sent to the login page flow (a nested page flow).
         *
         * If the user successfully logs in, he is returned to this Action, which executes normally.
         *
         * @jpf:action login-required="true"
         * @jpf:forward name="success" path="saved.jsp"
         * @jpf:catch type="com.bea.wlw.netui.pageflow.NotLoggedInException" path="/loginPageFlow/loginPageFlowController.jpf"
         */
        protected Forward save()
        {
            //
            // The code here can be executed only by logged in users.
            //

            return new Forward( "success" );
        }

## Logging In Users

Within the login page flow, you can use an standard <netui:form>, databound to a Form Bean, to collect the users username and password.

            <netui:form action="executeLogin">
                <table>
                    <tr>
                        <td>
                            Username:
                        </td>
                        <td>
                            <netui:textBox dataSource="{actionForm.username}"/>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            Password:
                        </td>
                        <td>
                            <!-- The password attribute hides the user input in the browser -->
                            <netui:textBox dataSource="{actionForm.password}" password="true"/>
                        </td>
                    </tr>
                </table>
                <netui:button value="Submit"/>
            </netui:form>

To handle the user submission of a username and password, use the method login(String username, String password), a method on the com.bea.wlw.netui.pageflow.FlowController class. The login(String username, String password) method will consult WebLogic Server's authentication provider(s) to attempt to login the user.

If the login attempt fails, a javax.security.auth.login.LoginException is thrown. In the sample below, this exception is caught and the user is returned to the login page to try again.

If the login attempt succeeds, the user can be returned to the original Action method in the parent page flow using the @jpf:forward return-action attribute. The return-action attribute always refers to an Action in a parent page flow, not in the current, nested, page flow.

...on the nested (child) page flow

        /**
         * @jpf:action
         * @jpf:catch type="javax.security.auth.login.LoginException" path="login.jsp"
         * @jpf:forward name="success" return-action="loginSuccess"
         */
        protected Forward executeLogin( LoginForm form )
            throws LoginException
        {
            /*
             * The login method below is a method of the com.bea.wlw.netui.pageflow.PageFlow
             * class.  It logs in the user against WebLogic Server's current authentication provider.
             *
             * If the login succeeds (if user is known to the authentication provider), then
             * the user is returned to the originating Action method on
             * the nesting page flow.
             * Note that the user is returned to the save Action via the "loginSuccess" method on the
             * nesting page flow.
             *
             * If the login fails, a LoginException is returned and the user is returned to the
             * login page.
             */
            login( form.getUsername(), form.getPassword() );
            return new Forward( "success" );
        }

Once the user has been logged in via the nested page flow, he is returned to a dummy method on the nesting page flow; this dummy method is used to return the user to the original method requiring login.

...on the nesting (parent) page flow

        /**

         * @jpf:action
         * @jpf:forward name="prevAction" return-to="previousAction"
         */
        protected Forward loginSuccess()
        {
            return new Forward( "prevAction" );
        }

Related Topics

Login Samples

@jpf:action Annotation

@jpf:catch Annotation