This security solution will probably not stand up to the scrutiny of a JE (Java Expert), but I’m cool with it. It’s probably all you’re really looking for. Something basic and simple. If you’re new to Stripes check out Stripes Quick Start Guide
The solution requires 4 elements:
- @DoesNotRequireLogin Annotation
- Security Interceptor
- Security Action Bean
- JSP login form
Creating a Java annotation is very simple. As a RAJP (Regular Average Java Programmer), I was intimidated at first. What if I’m not smart enough to figure this out? What will the JEs think? ARRRG! Relax. It’s easy
That’s it. You have an annotation. Now let’s see what you can do with it!
see Stripes’ documentation on interceptors http://www.stripesframework.org/display/stripes/Intercept+Execution
An interceptor breaks in at a certain stage of the Stripes life cycle. In this case, we want it to run any time an action is requested so that we can see if the action requires a login. Then we make a decision. Either let the request pass through, or do something else. In this case we’re asking if the Action Bean that is being requested is annotated with @DoesNotRequireLogin. I set it up that way instead of @RequiresLogin because the only thing that doesn’t require login is the login. So I annotated that bean with @DoesNotRequireLogin. Any other bean has to pass the treacherous isLoggedIn method. Anything that fails this gets returned back to the login screen. Also notice that we are implementing the Interceptor interface of which the intercept method is required for implementation.
The action bean serves as the controller. It can be called upon by any page by setting the beanClass property of a form or link. The @UrlBinding annotation is where you specify why URL will map to this bean. The default is to go to the login event because it’s annotated with @DefaultResolution. All this does is forward the request to the login jsp. The first instance variable is an EJB that handles data access for the login transaction. The next two are the variables that will be bound to the login form. The submitLogin method is the event that the login form will call. Got it? That was a lot. You may need to reread and take a closer look at the tiny picture of my code.
Notice that the class has a @DoesNotRequireLogin annotation. A request to this Action Bean will pass through the security interceptor. The submitLogin event processes the login form and uses the EJB to decide whether it passes. If it doesn’t, we add an error message and return the request back to the login screen. If it passes, it uses the path variable to forward the request on to wherever the user was trying to go in the first place.
Notice the annotations on the userId and password. This is Stripes super easy way of doing form validations. It runs the validation before the action event (submitLogin) is run and will automatically return to your form with errors if they fail.
Finally, you need a logout event. This returns the loggedIn session attribute back to false and forwards the request back to the login form. You’ll just need to throw a logout link somewhere in your application.
The login page is a very basic login using a handful of Stripes tags.
It’s a little clipped so you don’t see the layout rendering and the closing div and such, but that’s not what’s important here. I want you to note just a few things.
- The form uses Stripes tags instead of regular HTML tags. You tell it what Action Bean to submit the form to (see beanclass in the stripes:form…this is our security action bean), and then you tell it what event should handle it (see the stripes:submit tag name property…this is the submitLogin event in the security action bean)
- When you use Stripes tags for the inputs, Stripes automagically maps the data input to the instance variables in the Action Bean . The values of the name attributes have to match the variable names in the action bean (userId and password which have to have getters and setters for it to work). Pretty handy if you’re used to getting stuff out of the Request and setting them into the variables yourself.
- Look at the <stripes:errors> tag. If the security action bean says the login failed or if the input fields don’t pass validation, it forwards the request back to the login screen and displays the errors in the stripes:errors tag. Simple. Elegant.
That’s it. Any request that comes into this application will be intercepted by SecurityInterceptor, and if the requested action bean does not have the @DoesNotRequireLogin, it will ask if the person is logged in, etc. And in our case, the security action bean will be accessed. It will route the request to the login page. The form will submit back to the security action bean (and will pass the interceptor) and go straight to the submitLogin event for processing. If the login should fail, the request will be returned to the login page with an error message that says so; otherwise, it’s on to the application!
Ok, JEs (Java Experts), you’re welcome to cut this into shreds, but the rest of RAJPs are satisfied…at least this one is.