DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Building Enterprise-Ready Landing Zones: Beyond the Initial Setup
  • Cookies Revisited: A Networking Solution for Third-Party Cookies
  • It’s Not About Control — It’s About Collaboration Between Architecture and Security
  • Hybrid Cloud vs Multi-Cloud: Choosing the Right Strategy for AI Scalability and Security

Trending

  • A Developer's Guide to Mastering Agentic AI: From Theory to Practice
  • Integrating Security as Code: A Necessity for DevSecOps
  • Unlocking AI Coding Assistants Part 2: Generating Code
  • Top Book Picks for Site Reliability Engineers
  1. DZone
  2. Coding
  3. Languages
  4. Secure Your Method Using AOP

Secure Your Method Using AOP

In this article, we take a look at how you can secure your methods using aspect-oriented programming.

By 
Harsh Yadav user avatar
Harsh Yadav
·
May. 26, 20 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
16.1K Views

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

Pre-requisites:

  • 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.

Java
 




x


 
1
public class SecureMessage
2
{
3
  public void writeSecureMessage() 
4
  {
5
    System.out.println("100 pushup and 100 situp is the key to success-Saitama");
6
  }
7
}


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:

Java
 




x


 
1
public class UserInfo 
2
{
3
  private String userName;
4
  private String password;
5
  public UserInfo(String userName, String password)
6
  {
7
    this.userName = userName;
8
    this.password = password;
9
    }
10
    public String getPassword() {
11
        return password;
12
    }
13
    public String getUserName() {
14
        return userName;
15
    }
16
  }
17
}



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:

Java
 




xxxxxxxxxx
1
13


 
1
public class SecurityManager {
2
  private static ThreadLocal<UserInfo>
3
  threadLocal = new ThreadLocal<>();
4
  public void login(String userName, String password) {
5
    threadLocal.set(new UserInfo(userName, password));
6
  }
7
  public void logout() {
8
    threadLocal.set(null);
9
  }
10
  public UserInfo getLoggedOnUser() {
11
    return threadLocal.get();
12
  }
13
}



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  UserInfo  object for the user and stores it on the current thread by using ThreadLocal. 
  • logout(): method sets any value that might be stored in  ThreadLocal  to null. 
  • getLoggedOnUser(): method returns the  UserInfo object 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:

Java
 




x


 
1
import java.lang.reflect.Method;
2
import org.springframework.aop.MethodBeforeAdvice;
3
public class SecurityAdvice implements MethodBeforeAdvice {
4
  private SecurityManager securityManager;
5
  public SecurityAdvice() {
6
    this.securityManager = new SecurityManager();
7
  }
8
  @Override
9
  public void before(Method method, Object[] args, Object target)
10
  throws Throwable {
11
    UserInfo user = securityManager.getLoggedOnUser();
12
    if (user == null) {
13
      System.out.println("No user authenticated");
14
      throw new SecurityException(
15
      "You must login before attempting to invoke the method: "
16
      + method.getName());
17
    } else if ("Saitama".equals(user.getUserName())) {
18
        System.out.println("Logged in user is Saitama - OKAY!");
19
    } else {
20
      System.out.println("Logged in user is " + user.getUserName()
21
      + " NOT GOOD :(");
22
      throw new SecurityException("User " + user.getUserName()
23
      + " is not allowed access to method " + method.getName());
24
  }
25
}


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:

Java
 




x


 
1
import org.springframework.aop.framework.ProxyFactory;
2

          
3
public class SecurityDemo {
4
    public static void main(String... args) {
5
        SecurityManager mgr = new SecurityManager();
6
        SecureMessage bean = getSecureBean();
7
        mgr.login("Saitama", "pwd");
8
        System.out.println("---Scenario 1---");
9
        bean.writeSecureMessage();
10
        mgr.logout();
11
        try {
12
            mgr.login("invalid user", "pwd");
13
            System.out.println("---Scenario 2---");
14
            bean.writeSecureMessage();
15
        } catch (SecurityException ex) {
16
            System.out.println("Exception Caught: " + ex.getMessage());
17
        } finally {
18
            mgr.logout();
19
        }
20
        try {
21
            System.out.println("---Scenario 3---");
22
            bean.writeSecureMessage();
23
        } catch (SecurityException ex) {
24
            System.out.println("Exception Caught: " + ex.getMessage());
25
        }
26
    }
27

          
28
    private static SecureBean getSecureBean() {
29
        SecureMessage target = new SecureMessage();
30
        SecurityAdvice advice = new SecurityAdvice();
31
        ProxyFactory factory = new ProxyFactory();
32
        factory.setTarget(target);
33
        factory.addAdvice(advice);
34
        SecureMessage proxy = (SecureMessage) factory.getProxy();
35
        return proxy;
36
    }
37
}


Output:

---Scenario 1---

Logged in user is Saitama - OKAY!

100 pushup and 100 situp is the key to success-Saitama

---Scenario 2---

Logged in user is invalid user NOT GOOD.

Exception Caught: User invalid user is not allowed access to method writeSecureMessage

---Scenario 3---
No user authenticated

Exception Caught: You must login before attempting to invoke the method: writeSecureMessage

Explanation

In the  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

security Advice (programming) Aspect-oriented programming

Opinions expressed by DZone contributors are their own.

Related

  • Building Enterprise-Ready Landing Zones: Beyond the Initial Setup
  • Cookies Revisited: A Networking Solution for Third-Party Cookies
  • It’s Not About Control — It’s About Collaboration Between Architecture and Security
  • Hybrid Cloud vs Multi-Cloud: Choosing the Right Strategy for AI Scalability and Security

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!