Spring Security Java Config Preview: Method Security

Engineering | Rob Winch | July 04, 2013 | ...

Update

Users should refer to the Spring Security Reference which contains more up to date information.

Original Blog Post

This is the third installment of a four part blog series. In my first post, I introduced Spring Security Java configuration and discussed some of the logistics of the project. In my previous post, we walked through a few examples of configuring web based security.

In this post, I will discuss how to configure method based security using Spring Security Java configuration. Like our previous post, we will start off with a very basic example and follow it up with an example that performs a bit of customization.

MethodSecurityService

While not terribly interesting, assume that we have a service called MethodSecurityService as shown below:


public interface MethodSecurityService {
    @PreAuthorize("hasRole('ROLE_USER')")
    String requiresUserRole();
}

Our implementation is just as trivial, but will ensure we focus on Spring Security rather than our services.


public class MethodSecurityServiceImpl implements 
      MethodSecurityService {
    
    public String requiresUserRole() {
        return "You have ROLE_USER";
    }
}

Hello Method Security

By using @EnableGlobalMethodSecurity we can easily secure our methods with Java configuration. Note that methodSecurityService is not really part of our Security configuration, but we must create our MethodSecurityService using Spring so that it can have Security applied to it.


@Configuration
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class HelloMethodSecurityConfig {
  @Bean
  public MethodSecurityService methodSecurityService() {
    return new MethodSecurityServiceImpl()
  }

  @Autowired
  public void registerGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth
        .inMemoryAuthentication()
          .withUser("user").password("password").roles("USER").and()
          .withUser("admin").password("password").roles("USER", "ADMIN");
    }
}

This configuration is fairly similar to the following XML configuration:


<global-method-security pre-post-annotations="enabled"/>
<authentication-manager>
  <authentication-provider>
    <user-service>
      <user name="user" password="password" authorities="ROLE_USER"/>
    </user-service>
  </authentication-provider>
</authentication-manager>
<beans:bean id="methodSecuriytService" class="MethodSecurityServiceImpl"/>

With our configuration, the invocation of requiresUserRole() on our methodSecurityService bean would require that the current user be authenticated with the role "ROLE_USER". If the user was unauthenticated or did not have the role "ROLE_USER" a AccessDeniedException would be thrown.

Custom Method Security

There are a number of additional attributes available on the @EnableWebSecurity annotation, but if you wish to customize method security in more advanced ways you will need to extend GlobalMethodSecurityConfiguration. An example where we customize the PermissionEvaluator can be seen below:


@Configuration
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class CustomPermissionEvaluatorWebSecurityConfig extends GlobalMethodSecurityConfiguration {
  @Bean
  public MethodSecurityService methodSecurityService() {
    return new MethodSecurityServiceImpl()
  }

  @Override
  protected MethodSecurityExpressionHandler expressionHandler() {
    DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
    expressionHandler.setPermissionEvaluator(new CustomPermissionEvaluator());
    return expressionHandler;
  }
  
  @Autowired
  public void registerGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth
        .inMemoryAuthentication()
          .withUser("user").password("password").roles("USER").and()
          .withUser("admin").password("password").roles("USER", "ADMIN");
    }
}

This is fairly similar to the following XML configuration:


<global-method-security pre-post-annotations="enabled">
  <expression-handler ref="expressionHandler"/>
</global-method-security>
<authentication-manager>
  <authentication-provider>
    <user-service>
      <user name="user" password="password" authorities="ROLE_USER"/>
    </user-service>
  </authentication-provider>
</authentication-manager>
<beans:bean id="methodSecuriytService" class="MethodSecurityServiceImpl"/>
<beans:bean id="expressionHandler" class="CustomExpressionHandler"/>

Additional Method Samples

We have given a few examples of how the Spring Security Java Configuration can be used to secure your application with method level security. You can find additional samples in the spring-security-javaconfig project's github repository.

Feedback Please

If you encounter a bug, have an idea for improvement, etc please do not hesitate to bring it up! We want to hear your thoughts so we can ensure we get it right before the code is generally available. Trying out new features early is a good and simple way to give back to the community. This also ensures that the features you want are present and working as you think they should.

Please log any issues or feature requests to the Spring Security JIRA under the category "Java Config". After logging a JIRA, we encourage (but do not require) you to submit your changes in a pull request. You can read more about how to do this in the Contributor Guidelines

If you have questions on how to do something, please use the Spring Security forums or Stack Overflow with the tag spring-security (I will be monitoring them closely). If you have specific comments questions about this blog, feel free to leave a comment. Using the appropriate tools will help make it easier for everyone.

Conclusion

You should now have an understanding of how to configure method based security using Spring Security Java configuration support. In the next post, we will demonstrate how Spring Security is designed for extension by walking through the OAuth Java Configuration proof of concept.

Get the Spring newsletter

Thank you for your interest. Someone will get back to you shortly.

Get ahead

VMware offers training and certification to turbo-charge your progress.

Learn more

Get support

Tanzu Spring Runtime offers support and binaries for OpenJDK™, Spring, and Apache Tomcat® in one simple subscription.

Learn more

Upcoming events

Check out all the upcoming events in the Spring community.

View all