1

I am new for spring security. I've seen many posts on how to inject values via annotation from external property file. I've tried many ways, but I always end up with java.lang.IllegalArgumentException: Could not resolve placeholder 'val.id' exception.

Can you provide me some tips how to handle this exception please?

My java class is the following one:

@Controller
public class Employee {
    @Value("${val.id}") 
    public String valId;

    public String getValId() {
        return valId;
    }

    public void setValId(String valId) {
        this.valId = valId;
    }

My property file is called val.properties which is located under WEB-INF, and its content is val.id=xyz

I put the following in my main context bean.

<context:property-placeholder location="/WEB-INF/*.properties" />
<bean id="valProp" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
        p:location="/WEB-INF/val.properties"/>

A continuous question:

The injecting values from properties file to annotated beans works fine as I accepted the answer above. However, I cannot able to inject it to @PreAuthorize(...) annotation by following the same procedure.

Assume I want to secure a method called 'update'. This method is allowed if and only if valId is equal to empId. values of valId and empId are initialized in the val.properties file.

my java bean is:

public class Employee {
    public String valId;
    public String empId;

    public String getValId() {
        return valId;
    }

    public void setValId(String valId) {
        this.valId = valId;
    }

    public String getEmpId() {
        return empId;
    }

    public void setEmpId(String empId) {
        this.empId = empId;
    }
}

my property file contains: val.id=nn emp.id=nn

I have the place holder configuration in my main context file:

<context:property-placeholder location="/WEB-INF/*.properties" />
<bean id="valProp" class="org.springframework.beans.factory.config.PropertiesFactoryBean"
        p:location="/WEB-INF/val.properties"/>

My PreAuthorize annotation (method security) is:

@PreAuthorize("(#{valProp['val.id']} == #{valProp['emp.id']})")
public boolean update(){
  //if accessable
  return true;
}

But the expression #{valProp['val.id']} == #{valProp['emp.id']} is not evaluated.

Did I do any mistake to inject values? It was worked when I annotate member variables, but it doesn't work here. Any idea please? Thanks in advance.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
efi
  • 11
  • 4
  • Show your whole context. – Sotirios Delimanolis Nov 03 '13 at 21:03
  • Small guess, your placeholder is defined in the context loaded by the `ContextLoaderListener` whereas your @Controller is loaded by the `DispatcherServlet`. A `Bean(Factory)PostProcessor` operates only on the context it is defined in (and the `PropertyPlaceholderConfigurer` is such a bean). – M. Deinum Nov 04 '13 at 08:33

2 Answers2

1

try to consider the following

1). change your annotation to:

@Value("#{valProp['val.id']}")

2). Replace PropertyPlaceholderConfigurer by PropertiesFactoryBean.

Hope this will resolve the exception.

user262
  • 198
  • 1
  • 3
  • 13
  • Why do you think this will change anything? – Sotirios Delimanolis Nov 03 '13 at 22:17
  • Eyasu's answer solves the problem. It works as a charm!. Thanks a lot man :). – efi Nov 03 '13 at 22:30
  • http://stackoverflow.com/questions/10102216/why-is-spring-value-incompatible-with-controller – Nils Nov 03 '13 at 23:58
  • Thanks a lot guys!. What if I want to inject values to @PreAuthorize(...) annotation? I tried to pass in the same way above, but it doesn't work :(. Let me write my question clearly below (because I can't clearly write my question as a comment here) – efi Nov 04 '13 at 10:52
0

The reason why the exception is thrown is, because the property placeholder by default throws an exception when a values cannot be resolved. Furthermore you have two property placeholders, via which probably not all values can be resolved.

You can change this behaviour via setting the ignore-unresolvable property:

<context:property-placeholder location="/WEB-INF/*.properties" ignore-unresolvable="true" />

<bean id="valProp" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
    p:location="/WEB-INF/val.properties" p:ignoreUnresolvablePlaceholders="true" />

Note however that b< turning off this feature typos in a property file will not be detected.

Nils
  • 1,750
  • 14
  • 10