HowToDoInJava

  • Python
  • Java
  • Spring Boot
  • Dark Mode
Home / Spring Security / Spring Method Security with protect-pointcut

Spring Method Security with protect-pointcut

In previous example of method level security, we added security using @PreAuthorize annotation. Annotations are good way and quick way too to add security on any method. But there is one problem, it tightly couple your application code to spring. It is not desirable, at least in theory and in terms of best practices. A recommended approach is to add all such security definitions to xml configuration file. This way you can always change the implementation without touching your source code.

Overview

In this example, I have using a typical employee management screen. There are two basic operations, ADD and DELETE.

  1. Add requires a authenticated user to have either "ROLE_USER" or "ROLE_ADMIN".
  2. Delete is more protected and requires admin access i.e. only ROLE_ADMIN are allowed to delete a user.

I have two users in application i.e. admin and lokesh. admin user has both roles “ROLE_USER” and “ROLE_ADMIN“, but another user lokesh has only “ROLE_USER” access.

<user-service>
	<user name="lokesh" password="password" authorities="ROLE_USER" />
	<user name="admin"  password="password" authorities="ROLE_USER,ROLE_ADMIN" />
</user-service>

Above security configuration will allow both users to add a user, but only admin should be able to delete a user.

Let’s look at major functional points in example application.

XML Based Spring Security using protect-pointcut

The complete XML configuration looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
	xmlns:beans="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	http://www.springframework.org/schema/security/
	http://www.springframework.org/schema/security/spring-security-3.0.3.xsd">
	
	<global-method-security>
		<protect-pointcut expression="execution(* com.howtodoinjava.service.*Impl.add*(..))" access="ROLE_USER"/>
		<protect-pointcut expression="execution(* com.howtodoinjava.service.*Impl.delete*(..))" access="ROLE_ADMIN"/>
	</global-method-security>
	
	<http auto-config="false"  use-expressions="true">
		<intercept-url pattern="/login" access="permitAll" />
		<intercept-url pattern="/logout" access="permitAll" />
		<intercept-url pattern="/accessdenied" access="permitAll" />
		<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
		<form-login login-page="/login" default-target-url="/list" authentication-failure-url="/accessdenied" />
		<logout logout-success-url="/logout" />
	</http>

	<authentication-manager alias="authenticationManager">
        <authentication-provider>
            <user-service>
                <user name="lokesh" password="password" authorities="ROLE_USER" />
                <user name="admin" password="password" authorities="ROLE_USER,ROLE_ADMIN" />
            </user-service>
        </authentication-provider>
    </authentication-manager>
    
    <beans:bean id="employeeDAO" class="com.howtodoinjava.dao.EmployeeDaoImpl" />
    <beans:bean id="employeeManager" class="com.howtodoinjava.service.EmployeeManagerImpl" />
    
</beans:beans>

Manager class where security is applied

package com.howtodoinjava.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.howtodoinjava.dao.EmployeeDAO;
import com.howtodoinjava.entity.EmployeeEntity;

@Service
public class EmployeeManagerImpl implements EmployeeManager {
	
	@Autowired
    private EmployeeDAO employeeDAO;

	@Override
	@Transactional
	public void addEmployee(EmployeeEntity employee) {
		employeeDAO.addEmployee(employee);
	}

	@Override
	@Transactional
	public List<EmployeeEntity> getAllEmployees() {
		return employeeDAO.getAllEmployees();
	}

	@Override
	@Transactional
	public void deleteEmployee(Integer employeeId) {
		employeeDAO.deleteEmployee(employeeId);
	}

	public void setEmployeeDAO(EmployeeDAO employeeDAO) {
		this.employeeDAO = employeeDAO;
	}
}

I am skipping rest of the code, because it is completely identical to previous security example using annotations. Also, you can download the sourcecode if any thing needs to be referred.

Test the application

1) Login with user “lokesh”

login-with-user-lokesh

2) Add an employee into the list

lokesh-add-user-success-1

3) User is added successfully

lokesh-add-user-success-2

4) Try to delete employee. Access denied.

lokesh-delete-user-failure

5) Login with admin user

login-with-user-admin

6) Add an employee into the list

admin-add-user-success-1

7) User is added successfully

admin-add-user-success-2

8) Try to delete employee. Employee Deleted.

admin-delete-user-success-1

9) Try to delete another employee. Employee Deleted.

admin-delete-user-success-2

Sourcecode Download

Download Sourcecode

Happy Learning !!

Share this:

  • Twitter
  • Facebook
  • LinkedIn
  • Reddit

About Lokesh Gupta

A family guy with fun loving nature. Love computers, programming and solving everyday problems. Find me on Facebook and Twitter.

Feedback, Discussion and Comments

  1. Sanjay

    April 20, 2014

    Yes ! you are right. I was looking the non invasive options for the existing applications.
    Thanks
    -sanjay

  2. Sanjay

    April 18, 2014

    Hi Lokesh,
    gr8 article !! Do we need to alwys configure the spring beans in the config to be able to use spring protect-pointcut?
    Thanks
    -sanjay

    • Lokesh Gupta

      April 19, 2014

      I have not tried but I do not see any reason to enforce this rule. We should be able to define beans in annotations, and secure them in config files. Can you please try once?

      • Sanjay

        April 19, 2014

        Just looked at docs at https://docs.spring.io/spring-security/site/docs/3.0.x/reference/ns-config.html
        refer section : Adding Security Pointcuts using protect-pointcut – it says following
        This will protect all methods on beans declared in the application context whose classes are in the com.mycompany package and whose class names end in “Service”.

        But I see the reason , because the beans not loaded by spring context , spring may not have chance to inspect to enforce rule. will have to try.

        Thanks
        -sanjay

        • Lokesh Gupta

          April 19, 2014

          Hi Sanjay, you asked “configure the spring beans in the config”. I assumed you are saying to configure beans in applicationContext.xml. But we can define spring bean using annotations as well. They all will be available in spring context and will be initialized by spring only.
          So in this way, you do not configure them in applicationContext.xml file, still able to protect them.

          • Sanjay

            April 19, 2014

            Yes Lokesh ! you are right, but I was looking for non invasive way for pintcut if there is existing application as in my case.

            • Lokesh Gupta

              April 20, 2014

              In this case, spring will not help. As you said, context did not created them so it will not able to apply security on them as well.

  3. Jihed Chaâbane

    February 20, 2014

    Sir, I wanna thinks you for these examples ….

  4. Jayakumar Jayaraman

    February 15, 2014

    Wonderful effort….. Thanks Lokesh for the nice article.

Comments are closed on this article!

Search Tutorials

Spring Security Tutorial

  • Security – Introduction
  • Security – Method Level Security
  • Security – Siteminder
  • Security – Login Form
  • Security – JSP taglibs
  • Security – jdbc-user-service
  • Security – UserDetailsService
  • Security – Basic Auth
  • Security – Junit Tests
  • @PreAuthorize and @Secured

Meta Links

  • About Me
  • Contact Us
  • Privacy policy
  • Advertise
  • Guest and Sponsored Posts

Recommended Reading

  • 10 Life Lessons
  • Secure Hash Algorithms
  • How Web Servers work?
  • How Java I/O Works Internally?
  • Best Way to Learn Java
  • Java Best Practices Guide
  • Microservices Tutorial
  • REST API Tutorial
  • How to Start New Blog

Copyright © 2020 · HowToDoInjava.com · All Rights Reserved. | Sitemap

  • Java 15 New Features
  • Sealed Classes and Interfaces
  • EdDSA (Ed25519 / Ed448)