Object and field-level security

Visualforce pages exposing the SObject information (either via Standard, Custom, or Extension Controllers) can leverage built-in field-level security enforcements when using components or expressions that reference SObject fields directly; such usage will honor the user's field-level security. However, Visualforce expressions referencing SObject fields by way of a controller property are not affected, as the Visualforce engine cannot tell whether the controller property in turn refers to an SObject field.

Lightning does not currently offer components that are sensitive to object- and Field-Level security. You must, instead, inform the client side controller of the permissions via a Lightning server-side action that leverages Apex Describe for the information being accessed. The Lightning Data Service component, in Developer Preview at time of writing, does, however, support not only object and field security, but also sharing rules. Developer Preview status means it is not possible to package components using it.

Enforcing security in Visualforce

When using the Visualforce apex:inputField and apex:outputField components, fields (including the label if present) will be hidden or made read only accordingly. A less well-known fact is that direct SObject field expressions are also affected by field-level security; for example, {!Race__c.Status__c} will not be evaluated (no output emitted to the page) if the user has no read access to the Status__c field. This behavior is particularly subtle and not well documented.

Note

The documentation states that when using components such as apex:inputText and apex:ouputText, these will not enforce field security. While this is correct, security is always applied to SObject field expressions as well. So, if a field is not visible (as opposed to just read only), even the apex:outputText component will not display a value. However, if a field is read only and is used with apex:inputText (for example), it will render as an editable field. Thus, the general guideline here is that, if you have an SObject field expression, use the recommended apex:inputField and apex:outputField components.

A common confusion point is the use of the with sharing and without sharing keywords on the associated controllers. These keywords have no effect at all on the enforcement of field-level security; they purely determine record visibility, and thus effect only SOQL queries made within the controller and other Apex classes that make SOQL queries that are called by this controller.

Tip

In addition to using Apex described within your controller code, you can also determine directly a field's accessibility, using the $ObjectType global variable. For example, you can use the following expression to hide an entire section based on a given field's security, {!$ObjectType.Race__c.fields.Status__c.Accessible}.

The following Visualforce page and associated custom controller illustrates field-level security. In the use case shown here, two users are used, one has full access and the other has been given the following permissions via their profile:

  • Read-only access to the Status__c field
  • No access at all to the FastestLapBy__c field

First, review the Visualforce page; each section shows the following use case:

  • Use Case A shows the use of apex:inputField
  • Use Case B shows the use of apex:outputField
  • Use Case C shows the use of apex:inputText
  • Use Case D shows the use of apex:outputText
  • Use Case E shows the use of an SObject field expression
  • Use Case F shows the use of a controller property expression

To make it easier to compare, messages are shown on the page to confirm the level of field access. The FLSDemoController is included in the sample code for this chapter; it simply reads the first Race__c record in your org. It exposes two string properties indirectly exposing the Status__c and FastestLapBy__c field values. The following shows the Visualforce page used to illustrate the effects of using different Visualforce bindings and components against the permissions of the current user:

<apex:page controller="FLSDemoController" tabStyle="Race__c">
<apex:form>
<apex:pageMessage summary="Race__c.Status__c Accessible is{!$ObjectType.Race__c.fields.Status__c.Accessible}" severity="info"/>
<apex:pageMessage summary="Race__c.Status__c Updatable is{!$ObjectType.Race__c.fields.Status__c.Updateable}"severity="info"/>
<apex:pageMessagesummary="Race__c.FastestLapBy__c Accessible is {!$ObjectType.Race__c.fields.FastestLapBy__c.Accessible}"severity="info"/>
<apex:pageMessage
      summary="Race__c.FastestLapBy__c Updatable is {!$ObjectType.Race__c.fields.FastestLapBy__c.Updateable}"severity="info"/>
<apex:pageBlock>
<apex:pageBlockSection      title="Use Case A: Using apex:inputField">
<apex:inputField value="{!Race.Status__c}"/>
<apex:inputField value="{!Race.FastestLapBy__c}"/>
</apex:pageBlockSection>
<apex:pageBlockSection
      title="Use Case B: Using apex:outputField">
<apex:outputField value="{!Race.Status__c}"/>
<apex:outputField value="{!Race.FastestLapBy__c}"/>
</apex:pageBlockSection>
<apex:pageBlockSection      title="Use Case C: Using apex:inputText">
<apex:inputText value="{!Race.Status__c}"/>
<apex:inputText value="{!Race.FastestLapBy__c}"/>
</apex:pageBlockSection>
<apex:pageBlockSection       title="Use Case D: Using apex:outputText">
<apex:outputText value="{!Race.Status__c}"/>
<apex:outputText value="{!Race.FastestLapBy__c}"/>
</apex:pageBlockSection>
<apex:pageBlockSection       title="Use Case E: Using SObject Field Expressions">
<apex:pageBlockSection>
         The value of Status__c is '{!Race.Status__c}'
</apex:pageBlockSection>
<apex:pageBlockSection>
         The value of FastestLapBy__c is'{!Race.FastestLapBy__c}'
</apex:pageBlockSection>
</apex:pageBlockSection>
<apex:pageBlockSection       title="Use Case F: Using Controller Property Expressions">
<apex:pageBlockSection>
         The value of Status__c is '{!Status}'
</apex:pageBlockSection>
<apex:pageBlockSection>
         The value of FastestLapBy__c is '{!FastestLapBy}'
</apex:pageBlockSection>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>

For a user with full access, this page displays as follows:

Enforcing security in Visualforce

The following screenshot and explanations confirm how the page reacts and displays to a user with limited access; this page shows that some information is hidden or read-only as expected, but not all, the exceptions being use Case C and Case F:

  • For Use Case C, the field is read only, so its value is accessible and placed in the input field. As it is an apex:inputText field, it does not honor the field-level security status of the field and the field is editable when it should not be.
  • For Use Case F, the FastedLapBy__c field value is shown because it is not using a SObject field binding; it is using a binding to controller property, which is indirectly exposing the field value. In this case, the responsibility lies with the developer to check the field-level security in the controller code.
Enforcing security in Visualforce
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.93.169