Injecting property values from property file or xm

2020-06-21 06:50发布

问题:

I've asked this question in my previous post here: SpEL for spring security: Passing Values from XML to Java based SpEL configuration. But it wasn't yet resolved. I want to inject values either from an xml configuration or from external file into @PreAuthorize(...) annotation. It is not easy like injecting by using @Value annotation.

To recall the question, I provide the following information.

  1. I have the following xml configuration file (example.xml) that has properties and initialized its corresponding values.

    <beans>
        <bean id="userBean" class="x.y.User">
        <property name="name" value="A"/>
        <property name="userId" value="33"/>
    
        <bean id="customerBean" class="x.y.Customer">
            <property name="name" value="B"/>
            <property name="customerId" value="33"/>
        </bean>
    </beans>
    
  2. I have the following external properties file (example.properties) inside /WEB-INF folder. This file is an alternative for the XML configuration file mentioned above.

    user.id = 33
    customer.id =33
    
  3. I have property policy holder configuration in my applicationContext.xml file

    <context:property-placeholder location="/WEB-INF/*.properties" ignore-unresolvable="true" />
    
    <bean id="propertyConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
          p:location="/WEB-INF/example.properties" p:ignoreUnresolvablePlaceholders="true" />
    
  4. I have two model classes: User and Customer

    public class User {
        private int userId;
    
    public int getUserId() {
            return userId;
        }
    }
    
    public class Customer {
        private int customerId;
    
        public int getCustomerId(){
            return customerId;
        }
    }
    
  5. I have another service/controller class which I want to restrict the 'edit' method by using @PreAuthorize annotation.

    The restriction: The method is allowed (authorized to be executed) if and only if 'userId' and 'customerId' are evaluated equal!.

    To achieve the restriction, I want to consider two ways

    1. by injecting 'userId' and 'customerId' values from the xml file(example.xml) into expression 1 below. The expressions I used in this are suggested by Rob Winch (Thank you Rob!). However, Spring couldn't evaluate the expression.

    2. by injecting 'userId' and 'customerId' values from the external properties file(example.properties) into expression 2 below. Similarly, spring couldn't evaluate this expression as well.

      @Service("..") or @Controller
      public class MyMainClass {
      
          //Expression 1
          @PreAuthorize("@userBean.userId == @customerBean.customerId")
              public Boolean edit(User user, Customer custmer)  {
          return true;
          }
      
          //Expression 2
          ////I've tried other ways as well, but end up with similar exceptions
          @PreAuthorize("${user.id} == ${customer.id}")
          public Boolean edit(User user, Customer customer)  {
              return true;
          }
      }
      

My questions:

Q1. What are the right expressions that I must put inside the @PreAuthorize annotation to inject values from the xml file (example.xml) or from property file (example.properties) into the @PreAuthorize(...) expression, then it can be easily evaluated?

Q2. Point me if I did mistakes other than the expressions.

Q3. Its like a $1,000,000.00 question for me as I am fed up as hell to solve this issue!!!. So please help me out as much as you can!.

回答1:

if you are using properties file and you want to access them in controller classes you have to add <context:property-placeholder location="classpath:my.properties"/> in your servlet context xml file, after that you can use @Value annotation to get the values of that properties. e.g. my.properties file contains some.userid=33 so you would access this property using:

@Value("${some.userid}")
private int someId;

but to be sure for testing purpose i would set ignoreUnresolvablePlaceholders to false and in case it can't resolve properties file i would know where the error is coming from...

hope it helps.