13

I have two custom fields in Account object Test_Field_RO__c and Test_Field_H__c. I have a profile Test Profile, which has following field level security(FLS) - Test_Field_RO__c is Read Only and Test_Field_H__c FLS is Hidden. I am trying to display them in a VisualForce using following code snippet

<apex:page standardController="Account">
 <apex:form >
  <apex:pageBlock >
      <apex:pageBlockSection title="Standard Controller">
          <apex:inputText value="{!account.Test_Field_RO__c}"/> 
          <apex:inputText value="{!account.Test_Field_H__c}"/>
      </apex:pageBlockSection>
  </apex:pageBlock>
</apex:form>
</apex:page>

When I logged in as a User whose profile is Test Profile and accessed the VF page, I could see Test_Field_RO__c as input field, but Test_Field_H__c is not visible on the page. I have read in developer wiki page that

using other input tags such as apex:inputText or apex:inputTextArea with SObject fields indicate to VisualForce that the fields should not be treated as SObject fields and prevent the platform to automatically enforcing FLS.

In which case the field Test_Field_H__c which is Hidden for this profile should also be visible on the VF page. Am I missing some thing here ? Please Explain this behavior.

  • I think that only applies to custom controllers; you're using the standard controller which I believe enforces FLS. Have you tried with a custom controller? – Mike Chale Oct 16 '13 at 12:42
  • I suspect it might be because of the binding is still directly to the field. The wiki page goes on to give an example of manual FLS, but interestingly uses a controller class member binding and not an SOBject field binding. I think the assumption is when making this statement you are using apex:inputText because you are not using a SObject field binding. I assume if you simply include the binding on the page literally it will also not show? – Andrew Fawcett Oct 16 '13 at 12:44
  • There is a link for this in my answer. – sfdcfox Oct 16 '13 at 12:59
  • 1
    I can't find a reference for this, but I believe inputText now honors the visible flag, but not the read-only flag (e.g. since you explicitly asked for the user to edit the value, it will let you if you have visibility access). This would make sense in scenarios where a field would normally be read-only, but a Visualforce page needs the user to edit the value, perhaps as a means of enforcing business logic. – sfdcfox Oct 16 '13 at 13:24
  • 1
    I suspect this is all down FLS being enforced for literal bindings on the page regardless of controller or components, as per the Wiki section i highlighted in my answer. I also suspect that inputText is not so much honouring FLS, as it is documented that it doesn't, but is really just responding in some way to having an unresolveable binding. – Andrew Fawcett Oct 16 '13 at 13:27
19

Updated 2017-05-24

Visualforce respects Field Level Security when using apex:inputText. It will appear editable if the user has Edit permission on the field, Read-Only if the user has Read permission on the field, and will not be rendered at all if no access is granted to the field. When writing Visualforce, it helps to remember that System Administrators have Edit Read-Only Fields, which overrides the Edit permission on a field (but they won't have any access without Read access to the field). Always make sure you're testing with a profile that does not have the Edit Read-Only Fields permission.


Original Answer

apex:inputText does not honor Field Level Security. Use apex:inputField instead. See Enforcing CRUD and FLS for more details.

| improve this answer | |
  • Is that true? In the page you mention they give the example where they reference {!Contact.Phone} directly in the page, and even then FLS is honored. As the article mentions: "The platform will automatically enforce CRUD and FLS when the developer references SObjects and SObject fields directly in the VisualForce page"... – Willem Mulder May 24 '17 at 8:26
  • @WillemMulder If I remember correctly, apex:inputText was unreliable back in 2013; or I may have been mistaken, as this was a number of years ago. Regardless, it's not correct today, so I'll have to revise this answer. Thanks for bringing this up. – sfdcfox May 24 '17 at 12:45
  • Excellent. For what it helps: I've been digging into it this morning :-) What I found is that apex:inputText WILL respect CRUD read and edit rights and it WILL respect FLS read rights. It will NOT respect FLS edit rights. Would be good to have that confirmed from your side as well... – Willem Mulder May 24 '17 at 12:52
  • @WillemMulder Yes, I just tested this, and FLS is now properly enforced. I'm not sure when it changed, but it definitely works now. – sfdcfox May 24 '17 at 13:03
  • That's right. Note that an apex:inputText field will appear editable if the user has Edit permission on CRUD level! The edit rights on FLS level do not seem to matter at all. Would be good if you could update your answer with that info. – Willem Mulder May 24 '17 at 13:41
9

It will most likely be the direct bindings your making that are driving this behaviour, the Wiki page describes the following behaviour for literal references to SObject field bindings...

When rendering VisualForce pages, the platform will automatically enforce CRUD and FLS when the developer references SObjects and SObject fields directly in the VisualForce page. For example, if a user without FLS visibility to the Phone field of the Contact object was to view the below page, phone numbers would be automatically removed from the table.

<apex:page standardController="Account">
  <apex:pageBlock title="Contacts">
    <apex:dataTable value="{!account.Contacts}" var="contact" cellPadding="4" border="1">
      <apex:column>
        <apex:facet name="header">Name</apex:facet>
        {!contact.Name}
      </apex:column>
      <apex:column>
        <apex:facet name="header">Phone</apex:facet>
        {!contact.Phone}
      </apex:column>
    </apex:dataTable>
  </apex:pageBlock>
</apex:page>

That said i would expect your HTML input box (which apex:inputText is simple wrapper for) to still be rendered just without a value in it. Unless the apex:inputText component choose not render itself at all if the binding cannot be resolved.

The workaround to this is to use an Apex controller to expose your own members/properties from the controller that reference this information from within the controller. Then binding your apex:inputText component to those. Note that 'with sharing' and 'without sharing' does not effect FLS in respect to SOQL and Apex code execution, sharing is purely controlling record visibility.

| improve this answer | |
5

Reading about Visualforce classes, it states that

Like other Apex classes, custom controllers execute entirely in system mode, in which the object and field-level permissions of the current user are ignored. You can specify whether a user can execute methods in a custom controller based on the user's profile.

I believe the issue is that your sample is using the standard controller, which enforces security (runs with sharing).

| improve this answer | |
0

This makes sense. You are using standard controller and Salesforce standard controller is fetching fields to show you in the front end. So, it will enforce SLA automatically before displaying you in the frontend. Hence, as the SLA for field is hidden it is not shown irrespective of vf tags. If you will be using, custom controller then this vf tags will make sense (if your controller is too in system mode)

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.