Prateek Narendra
Prateek Narendra

Reputation: 1937

Enable ConditionalOnProperty in a RequestMapping in Controller

I have a piece of code -

    @PropertySource(value = "classpath:securityConfig.properties", ignoreResourceNotFound = true)
    @Controller
    public class IndexController {
        private static final String LOGIN_PAGE           = "login";
        private static final String HOME_PAGE            = "home";
        private static final String LOBBY_PAGE           = "lobby";
        private static final String FORGOT_USER_PAGE     = "forgotUserName";
        private static final String FORGOT_PASSWORD_PAGE = "forgotPassWord";

        @ConditionalOnProperty(name = "auth.mode", havingValue = "fixed")
        @PreAuthorize("isAnonymous()")
        @RequestMapping(method = RequestMethod.GET, value = { "/login" })
        public String getIndexPage() {
            return LOGIN_PAGE;
        }
}

However, the ConditionalOn annotation doesnt work as expected. I do not want the controller to execute if auth.mode is anything other than fixed. Note - auth.mode is in securityConfig.properties file

Am I missing something? Probably an annotation at class level?

Upvotes: 3

Views: 4639

Answers (3)

vvauban
vvauban

Reputation: 485

@ConditionalOnProperty can be used as a method-level annotation only on @Bean method like (in a configuration class):

  @Bean
  @ConditionalOnProperty(name = "myapp.feature.enabled", havingValue = "true")
  public MyFeature myFeature() {
      // create and return MyFeature instance
  }

I personally used a @Value annotation that loads a property, and then uses a conditional structure (a if) according to the property value.

Like in:

@RestController
@RequestMapping("/my-endpoint")
public class MyController {

  @Value("${myapp.my-config-value}")
  private String myConfigValue;

  @GetMapping
  public String myMethod() {
    if ("disable".equals(myConfigValue)) {
      throw new IllegalStateException("This service is disabled.");
    }
    // if not disabled, do your stuff
    return myService.doStuff();
  }

}

Upvotes: 1

Prateek Narendra
Prateek Narendra

Reputation: 1937

Edit the @PreAuthorize annotation to add the condition

@PropertySource(value = "classpath:securityConfig.properties", ignoreResourceNotFound = true)
@Controller
public class IndexController {
    private static final String LOGIN_PAGE           = "login";
    private static final String HOME_PAGE            = "home";
    private static final String LOBBY_PAGE           = "lobby";
    private static final String FORGOT_USER_PAGE     = "forgotUserName";
    private static final String FORGOT_PASSWORD_PAGE = "forgotPassWord";

    @Value("${auth.mode:fixed}")
    private String authenticationMode;

    public String getAuthenticationMode(){
         return this.authenticationMode;
    }

    @PreAuthorize("isAnonymous() AND this.getAuthenticationMode().equals(\"fixed\")")
    @RequestMapping(method = RequestMethod.GET, value = { "/login" })
    public String getIndexPage() {
        return LOGIN_PAGE;
    }

Upvotes: 0

ptomli
ptomli

Reputation: 11818

You should move the @ConditionalOnProperty annotation to the class, not on the method.

@PropertySource(value = "classpath:securityConfig.properties", ignoreResourceNotFound = true)
@Controller
@ConditionalOnProperty(name = "auth.mode", havingValue = "fixed")
public class IndexController {
    ...
}

This will mean the entire controller will not exist in the application context unless the condition is satisfied.

Upvotes: 4

Related Questions