1

Based on the user's payment status situation, I would like to restrict access to some pages for that user. It should be done in the Controller method (GET request).

I am aware that URL can be intercepted by Spring security but it sounds static configuration to me. If I want to intercept URLs by Controller and then block certain pages for the user!, how can I achieve this ?

I am using Spring and Security 3.2.x version. I am attaching minimal flow for this case:

Thanks.

enter image description here

Pujan
  • 3,154
  • 3
  • 38
  • 52
  • 1
    [This answer](http://stackoverflow.com/questions/6632982/how-to-create-custom-methods-for-use-in-spring-security-expression-language-anno#14904130) seems good to me for your situation. – Basemasta Aug 17 '14 at 15:13
  • Thanks @Basemasta .It seems close, I will give a try. – Pujan Aug 17 '14 at 15:32
  • I posted an [example](http://stackoverflow.com/questions/25350389/deny-some-pages-by-controller-in-spring-dynamically/25350733#25350733). – Basemasta Aug 17 '14 at 16:27

2 Answers2

1

Here is an example (Code not tested !)

The methods you want to protect :

It can be controller methods :

@PreAuthorize("@userSecurityService.hasPaid()")
@RequestMapping(value = "/appointment", method = RequestMethod.GET)
public String appointment() {
    //Some code
}

Or Service layer methods :

@PreAuthorize("@userSecurityService.hasPaid()")
@Transactional
public String appointment() {
    //Some code
}

Or whatever :

@PreAuthorize("@userSecurityService.hasPaid()")
public String appointment() {
    //Some code
}

The @Component used for the validation :

@Component("userSecurityService")
public class UserSecurityService {

    // You might want inject DAOs or other components for your validations.
    @Inject
    private UserDao userDao

    public boolean hasPaid() {

        // You might want access to user info from spring context.
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();

        // Here you might want to use injected DAOs
        // in order to validate the fact that the user had paid (or whatever).

        // FIXME
        return true;
    }
}

Update (Thanks to @Pujan Srivastava comment) :

Spring AOP must be add as a dependency and the pre-post-annotations of Spring Security must be enabled :

Dependencies :

I personnaly use :

<!-- Spring framework -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.0.6.RELEASE</version>
</dependency>
<!-- Spring Security -->
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
    <version>3.2.5.RELEASE</version>
</dependency>

This gives me all the basic dependencies for Spring MVC and Spring Security to be properly configured in the Controller layer (and it includes Spring AOP). So I only have to add spring-security-core dependency in the Service layer in order to protect services methods.

Enable pre-post-annotations :

Java config example :

@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class WebMvcSecurityConfig extends WebSecurityConfigurerAdapter {
    ...
}

or with xml config like @Pujan Srivastava comment :

<sec:global-method-security pre-post-annotations="enabled" proxy-target-class="true"/>

in the dispatcher xml file.

Basemasta
  • 381
  • 1
  • 13
  • Thanks it is working. Just for the node, I have to add aop dependency and add in the dispatcher xml file. – Pujan Aug 18 '14 at 03:50
0

Since you are looking at what seems like a cross-cutting issue, I suggest that you take a look at Spring MVC Interceptors.

They provide out of the box and extremely easy to use AOP like features. In your case you would create an interceptor that would be used to check the payment status and then probably redirect to some specific URL if the payment is not correct.

You can check out some blog posts here and here.

You could of course use regular Spring AOP if you need even finer-grained control.

geoand
  • 60,071
  • 24
  • 172
  • 190