Secure Your Method Using AOP
In this article, we take a look at how you can secure your methods using aspect-oriented programming.
Join the DZone community and get the full member experience.Join For Free
In this article we learn how to secure our methods the easy way!
We basically use the Before Advice of aspect-oriented programming (AOP) to achieve our goal. The article even illustrates how easy it is to use AOP to implement a crosscutting concern such as security. Let's get started
- Knowledge of Spring Framework.
- Overview of AOP
What is AOP?
Spring AOP enables Aspect-Oriented Programming in Spring applications. In AOP, aspects enable the modularization of concerns such as transaction management, logging, or security that cut across multiple types and objects (often called crosscutting concerns).
What Is an Advice?
Advice is an action taken by an aspect at a particular join point. Different types of advice include “around,” “before” and “after” advice.
What is Before advice?
Before advice: Advice that executes before a join point, but which does not have the ability to prevent execution flow proceeding to the join point (unless it throws an exception).
The following code snippet shows the
SecureMessage class. This is the class that we will be securing using AOP.
Because this example requires users to authenticate, we are going to need to store their details. The following code snippet shows the
UserInfo class we can use to store a user’s credentials:
This class simply holds data about the user so that we can use it to validate the user. The following code snippet shows the
SecurityManager class, which is responsible for authenticating users and storing their credentials for later retrieval:
Please note, in a real application, the
login() method would probably check the supplied credentials against a database or LDAP directory, but here we check and assign against static values.
- login(): method creates a
UserInfoobject for the user and stores it on the current thread by using ThreadLocal.
- logout(): method sets any value that might be stored in
- getLoggedOnUser(): method returns the
UserInfoobject for the currently authenticated user. This method returns null if no user is authenticated.
Now we get to the interesting stuff.
To check whether a user is authenticated and, if so, whether the user is permitted to access the methods on SecureMessage, we need to create advice that executes before the method and checks the UserInfo object returned by SecurityManager.getLoggedOnUser() against the set of credentials for allowed users. The code for this advice, SecurityAdvice, is shown as follows:
before() method, we perform a simple check to see whether the username of the authenticated user is Saitama. If so, we allow the user access; otherwise, an exception is raised. Also notice that we check for a null UserInfo object, which indicates that the current user is not authenticated.
In the following code snippet, you can see a sample application that uses the SecurityAdvice class to secure the SecureMessage class:
Logged in user is Saitama - OKAY!
100 pushup and 100 situp is the key to success-Saitama
Logged in user is invalid user NOT GOOD.
Exception Caught: User invalid user is not allowed access to method writeSecureMessage
No user authenticated
Exception Caught: You must login before attempting to invoke the method: writeSecureMessage
getSecureBean() method, we create a proxy of the
SecureMessage class that is advised using an instance of SecurityAdvice. This proxy is returned to the caller. When the caller invokes any method on this proxy, the call is first routed to the instance of SecurityAdvice for a security check. In the
main() method, we test three scenarios, invoking the
SecureMessage.writeSecureMessage() method with two sets of user credentials and then no user credentials at all. Because
SecurityAdvice allows method calls to proceed only if the currently authenticated user is Saitama, we can expect that the only successful scenario in the previous code is the first.
As you can see, only the first invocation of
SecureMessage.writeSecureMessage() was allowed to proceed. The remaining invocations were prevented by the
SecurityException exception thrown by
SecurityAdvice . This example is simple, but it does highlight the usefulness of before advice. Security is a typical example of before advice, but we also find it useful when a scenario demands the modification of arguments passed to the method.ALU
Opinions expressed by DZone contributors are their own.