close

Security & Identity Management Considerations for Application Development

Posted by Errin O'Connor on May, 08, 2015 12:05

There are various security, identity management, and authentication considerations when developing custom applications and related features in SharePoint 2013, Office 365, SharePoint Online, and Microsoft Azure.

You should always keep in mind SharePoint 2013’s “claims first” authentication architecture during your development, as well as in discussions with the business about their custom requirements.

With SharePoint 2013’s user authentication based on claims, user authentication results in creation of a claims token, which tracks name-value pairs related to the token subject. These claims tokens are stored in memory using the FEDAUTH token format.

Overview of App Authentication

SharePoint 2013’s app authentication is supported in CSOM as well as in REST API endpoints but is not supported for custom web services.

Three types of app authentication are utilized by SharePoint 2013:

  • Internal authentication
  • External authentication using server-to-server trusts
  • External authentication using OAuth

Internal Authentication

Internal authentication is utilized when an incoming call targets a CSOM or REST API endpoint or when an incoming call carries a claims token with an established user identity.

Internal authentication is also utilized when an incoming call targets the URL of an existing SharePoint 2013 app web. This authentication does not support app-only authentication to elevate privilege(s).

There is no programming effort required in terms of access tokens; internal authentication is automatically utilized with client-side calls from pages in the app web, and it can also be utilized from remote web pages that are using the cross-domain library.

External Authentication

External authentication, which users both S2S and OAuth, is utilized for server-side code in the “remote web” and issues CSOM or REST API calls against the SharePoint host. The incoming calls can target host web and other sites within your organization’s tenancy.

External authentication does require custom app code to be developed to create and manage access tokens which carry the app’s identity as well as user identity because the app is required to transmit an access token in the request header when making a call to SharePoint 2013.

Apps Granted Permissions

In SharePoint 2013, how an app is granted permissions is not identical to how a user is granted permissions. App permissions have only two options, which are that they are or are not granted permissions, because it is really a simple “yes or no” type of scenario.

App permissions have no permissions hierarchy, unlike the user permissions strategy and available security hierarchy within a given site collection.

Apps with Default Permissions

An app that has been provided with default permissions has full control over the app web, as well as access to incoming query string parameters, but does not have default access to the host web.

An app with default permissions must include a permission request within its application manifest because the installer actually grants or denies permissions during the installation of the app and will automatically cancel any app install if permissions are denied.

Adding a Permission Request

As mentioned previously, an app must have a permissions request added to its application manifest. You can achieve this by opening the AppManifest.xml file in the manifest designer in Visual Studio and adding a permission request for each permission to SharePoint that the web application requires.

The Visual Studio 2013 SDK provides for project templates, tools, tests, and reference assemblies that are required to build extensions for Visual Studio 2013.

EPC Group’s Nationally Recognized Practice Areas

EPC Group leading Custom Application DevelopmentSharePointOffice 365, Infrastructure Design and Business Intelligence Practice areas continue to lead the way in providing our clients with the most up-to-date and relevant information that is tailored to their individual business and functional needs.

Additional “From the Consulting Trenches” strategies and methodologies are covered in EPC Group’s new book, “SharePoint 2013 Field Guide: Advice from the Consulting Trenches” covering not only SharePoint 2013, Office 365 and SharePoint Online but Information Management, ECM\RM and overall compliance strategies in this ever changing world of “Hybrid IT.”

[gravityform id="43" title="true" description="false" ajax="true"]
<div class='gf_browser_unknown gform_wrapper gform_legacy_markup_wrapper' id='gform_wrapper_43' ><div id='gf_43' class='gform_anchor' tabindex='-1'></div> <div class='gform_heading'> <h3 class="gform_title">Subscriber - Powerbi e-book</h3> </div><form method='post' enctype='multipart/form-data' target='gform_ajax_frame_43' id='gform_43' action='/security-identity-management-consulting/#gf_43' > <div class='gform_body gform-body'><ul id='gform_fields_43' class='gform_fields top_label form_sublabel_below description_below'><li id="field_43_7" class="gfield gfield--width-full gform_hidden field_sublabel_below field_description_below gfield_visibility_visible" ><div class='ginput_container ginput_container_text'><input name='input_7' id='input_43_7' type='hidden' class='gform_hidden' aria-invalid="false" value='https://www.epcgroup.net/security-identity-management-consulting/' /></div></li><li id="field_43_4" class="gfield gfield_html gfield_html_formatted gfield_no_follows_desc field_sublabel_below field_description_below gfield_visibility_visible" > <div class="description_data"> <p class="dp_one">Subscribe to our newsletter and get the first three chapters of the eBook for <strong>free<strong>.</p> </div></li><li id="field_43_6" class="gfield gfield_contains_required field_sublabel_below field_description_below gfield_visibility_visible" ><label class='gfield_label gfield_label_before_complex' >Name<span class="gfield_required"><span class="gfield_required gfield_required_asterisk">*</span></span></label><div class='ginput_complex ginput_container no_prefix has_first_name no_middle_name has_last_name no_suffix gf_name_has_2 ginput_container_name' id='input_43_6'> <span id='input_43_6_3_container' class='name_first' > <input type='text' name='input_6.3' id='input_43_6_3' value='' aria-label='First name' aria-required='true' placeholder='First Name' /> <label for='input_43_6_3' >First</label> </span> <span id='input_43_6_6_container' class='name_last' > <input type='text' name='input_6.6' id='input_43_6_6' value='' aria-label='Last name' aria-required='true' placeholder='Last Name' /> <label for='input_43_6_6' >Last</label> </span> </div></li><li id="field_43_2" class="gfield gfield_contains_required field_sublabel_below field_description_below gfield_visibility_visible" ><label class='gfield_label' for='input_43_2' >Email Address<span class="gfield_required"><span class="gfield_required gfield_required_asterisk">*</span></span></label><div class='ginput_container ginput_container_email'> <input name='input_2' id='input_43_2' type='text' value='' class='medium' aria-required="true" aria-invalid="false" aria-describedby="gfield_description_43_2" /> </div><div class='gfield_description' id='gfield_description_43_2'>Please enter your correct email address. You will receive an email to download the eBook.</div></li><li id="field_43_3" class="gfield g-captcha field_sublabel_below field_description_below gfield_visibility_visible" ><label class='gfield_label screen-reader-text' for='input_43_3' ></label><div id='input_43_3' class='ginput_container ginput_recaptcha' data-sitekey='6LdQ388UAAAAAJaahWs7D_jWzeQhUZW6-VNwWfaU' data-theme='light' data-tabindex='0' data-badge=''></div></li><li id="field_43_5" class="gfield gfield_html gfield_html_formatted gfield_no_follows_desc field_sublabel_below field_description_below gfield_visibility_visible" ><div class="note_description"><p><i><strong>NOTE: </strong>We will never send you spam or pass on your email address to any third party. You may choose to opt-out at any time.</i></p></div></li></ul></div> <div class='gform_footer top_label'> <input type='submit' id='gform_submit_button_43' class='gform_button button' value='Download Now' onclick='if(window["gf_submitting_43"]){return false;} window["gf_submitting_43"]=true; ' onkeypress='if( event.keyCode == 13 ){ if(window["gf_submitting_43"]){return false;} window["gf_submitting_43"]=true; jQuery("#gform_43").trigger("submit",[true]); }' /> <input type='hidden' name='gform_ajax' value='form_id=43&amp;title=1&amp;description=&amp;tabindex=0' /> <input type='hidden' class='gform_hidden' name='is_submit_43' value='1' /> <input type='hidden' class='gform_hidden' name='gform_submit' value='43' /> <input type='hidden' class='gform_hidden' name='gform_unique_id' value='' /> <input type='hidden' class='gform_hidden' name='state_43' value='WyJbXSIsIjEwNTJhNGVmMWMyNzI3YTJmMjdiZTA1NjU4ZDMzYzY3Il0=' /> <input type='hidden' class='gform_hidden' name='gform_target_page_number_43' id='gform_target_page_number_43' value='0' /> <input type='hidden' class='gform_hidden' name='gform_source_page_number_43' id='gform_source_page_number_43' value='1' /> <input type='hidden' name='gform_field_values' value='' /> </div> <p style="display: none !important;"><label>&#916;<textarea name="ak_hp_textarea" cols="45" rows="8" maxlength="100"></textarea></label><input type="hidden" id="ak_js" name="ak_js" value="38"/><script>document.getElementById( "ak_js" ).setAttribute( "value", ( new Date() ).getTime() );</script></p></form> </div> <iframe style='display:none;width:0px;height:0px;' src='about:blank' name='gform_ajax_frame_43' id='gform_ajax_frame_43' title='This iframe contains the logic required to handle Ajax powered Gravity Forms.'></iframe> <script type="text/javascript"> gform.initializeOnLoaded( function() {gformInitSpinner( 43, 'https://www.epcgroup.net/wp-content/plugins/gravityforms/images/spinner.svg' );jQuery('#gform_ajax_frame_43').on('load',function(){var contents = jQuery(this).contents().find('*').html();var is_postback = contents.indexOf('GF_AJAX_POSTBACK') >= 0;if(!is_postback){return;}var form_content = jQuery(this).contents().find('#gform_wrapper_43');var is_confirmation = jQuery(this).contents().find('#gform_confirmation_wrapper_43').length > 0;var is_redirect = contents.indexOf('gformRedirect(){') >= 0;var is_form = form_content.length > 0 && ! is_redirect && ! is_confirmation;var mt = parseInt(jQuery('html').css('margin-top'), 10) + parseInt(jQuery('body').css('margin-top'), 10) + 100;if(is_form){jQuery('#gform_wrapper_43').html(form_content.html());if(form_content.hasClass('gform_validation_error')){jQuery('#gform_wrapper_43').addClass('gform_validation_error');} else {jQuery('#gform_wrapper_43').removeClass('gform_validation_error');}setTimeout( function() { /* delay the scroll by 50 milliseconds to fix a bug in chrome */ jQuery(document).scrollTop(jQuery('#gform_wrapper_43').offset().top - mt); }, 50 );if(window['gformInitDatepicker']) {gformInitDatepicker();}if(window['gformInitPriceFields']) {gformInitPriceFields();}var current_page = jQuery('#gform_source_page_number_43').val();gformInitSpinner( 43, 'https://www.epcgroup.net/wp-content/plugins/gravityforms/images/spinner.svg' );jQuery(document).trigger('gform_page_loaded', [43, current_page]);window['gf_submitting_43'] = false;}else if(!is_redirect){var confirmation_content = jQuery(this).contents().find('.GF_AJAX_POSTBACK').html();if(!confirmation_content){confirmation_content = contents;}setTimeout(function(){jQuery('#gform_wrapper_43').replaceWith(confirmation_content);jQuery(document).scrollTop(jQuery('#gf_43').offset().top - mt);jQuery(document).trigger('gform_confirmation_loaded', [43]);window['gf_submitting_43'] = false;wp.a11y.speak(jQuery('#gform_confirmation_message_43').text());}, 50);}else{jQuery('#gform_43').append(contents);if(window['gformRedirect']) {gformRedirect();}}jQuery(document).trigger('gform_post_render', [43, current_page]);} );} ); </script>
[gravityforms id=41 title=”true” description=”false”]
<div class='gf_browser_unknown gform_wrapper exit_intent_popup_wrapper gform_legacy_markup_wrapper' id='gform_wrapper_41' > <div class='gform_heading'> <h3 class="gform_title">Exit Intent</h3> <span class='gform_description'></span> </div><form method='post' enctype='multipart/form-data' id='gform_41' class='exit_intent_popup gform_legacy_markup' action='/security-identity-management-consulting/' > <div class='gform_body gform-body'><ul id='gform_fields_41' class='gform_fields top_label form_sublabel_below description_below'><li id="field_41_1" class="gfield gform_hidden field_sublabel_below field_description_below gfield_visibility_visible" ><div class='ginput_container ginput_container_text'><input name='input_1' id='input_41_1' type='hidden' class='gform_hidden' aria-invalid="false" value='https://www.epcgroup.net/security-identity-management-consulting/' /></div></li><li id="field_41_11" class="gfield gfield--width-full gform_hidden field_sublabel_below field_description_below gfield_visibility_visible" ><div class='ginput_container ginput_container_text'><input name='input_11' id='input_41_11' type='hidden' class='gform_hidden' aria-invalid="false" value='ddd01b75-d4fc-ea11-a816-000d3a591fb8' /></div></li><li id="field_41_12" class="gfield gfield--width-full gform_hidden field_sublabel_below field_description_below gfield_visibility_visible" ><div class='ginput_container ginput_container_text'><input name='input_12' id='input_41_12' type='hidden' class='gform_hidden' aria-invalid="false" value='' /></div></li><li id="field_41_13" class="gfield gfield--width-full gform_hidden field_sublabel_below field_description_below gfield_visibility_visible" ><div class='ginput_container ginput_container_text'><input name='input_13' id='input_41_13' type='hidden' class='gform_hidden' aria-invalid="false" value='' /></div></li><li id="field_41_9" class="gfield gfield_contains_required field_sublabel_below field_description_below gfield_visibility_visible" ><label class='gfield_label' for='input_41_9' >Full Name<span class="gfield_required"><span class="gfield_required gfield_required_asterisk">*</span></span></label><div class='ginput_container ginput_container_text'><input name='input_9' id='input_41_9' type='text' value='' class='medium' placeholder='Full Name' aria-required="true" aria-invalid="false" /> </div></li><li id="field_41_6" class="gfield gfield_contains_required field_sublabel_below field_description_below gfield_visibility_visible" ><label class='gfield_label' for='input_41_6' >Email<span class="gfield_required"><span class="gfield_required gfield_required_asterisk">*</span></span></label><div class='ginput_container ginput_container_email'> <input name='input_6' id='input_41_6' type='text' value='' class='medium' placeholder='Email Address' aria-required="true" aria-invalid="false" /> </div></li><li id="field_41_7" class="gfield gfield_contains_required field_sublabel_below field_description_below gfield_visibility_visible" ><label class='gfield_label' for='input_41_7' >Phone<span class="gfield_required"><span class="gfield_required gfield_required_asterisk">*</span></span></label><div class='ginput_container ginput_container_phone'><input name='input_7' id='input_41_7' type='text' value='' class='medium' placeholder='Phone Number' aria-required="true" aria-invalid="false" /></div></li><li id="field_41_10" class="gfield gfield_contains_required field_sublabel_below field_description_below gfield_visibility_visible" ><label class='gfield_label' for='input_41_10' >Company Name<span class="gfield_required"><span class="gfield_required gfield_required_asterisk">*</span></span></label><div class='ginput_container ginput_container_text'><input name='input_10' id='input_41_10' type='text' value='' class='medium' placeholder='Company Name' aria-required="true" aria-invalid="false" /> </div></li><li id="field_41_8" class="gfield gfield_contains_required field_sublabel_below field_description_below gfield_visibility_visible" ><label class='gfield_label' for='input_41_8' >Message<span class="gfield_required"><span class="gfield_required gfield_required_asterisk">*</span></span></label><div class='ginput_container ginput_container_textarea'><textarea name='input_8' id='input_41_8' class='textarea medium' placeholder='Type your message here...' aria-required="true" aria-invalid="false" rows='10' cols='50'></textarea></div></li></ul></div> <div class='gform_footer top_label'> <input type='submit' id='gform_submit_button_41' class='gform_button button' value='Submit' onclick='if(window["gf_submitting_41"]){return false;} window["gf_submitting_41"]=true; ' onkeypress='if( event.keyCode == 13 ){ if(window["gf_submitting_41"]){return false;} window["gf_submitting_41"]=true; jQuery("#gform_41").trigger("submit",[true]); }' /> <input type='hidden' class='gform_hidden' name='is_submit_41' value='1' /> <input type='hidden' class='gform_hidden' name='gform_submit' value='41' /> <input type='hidden' class='gform_hidden' name='gform_unique_id' value='' /> <input type='hidden' class='gform_hidden' name='state_41' value='WyJbXSIsIjEwNTJhNGVmMWMyNzI3YTJmMjdiZTA1NjU4ZDMzYzY3Il0=' /> <input type='hidden' class='gform_hidden' name='gform_target_page_number_41' id='gform_target_page_number_41' value='0' /> <input type='hidden' class='gform_hidden' name='gform_source_page_number_41' id='gform_source_page_number_41' value='1' /> <input type='hidden' name='gform_field_values' value='' /> </div> <p style="display: none !important;"><label>&#916;<textarea name="ak_hp_textarea" cols="45" rows="8" maxlength="100"></textarea></label><input type="hidden" id="ak_js" name="ak_js" value="122"/><script>document.getElementById( "ak_js" ).setAttribute( "value", ( new Date() ).getTime() );</script></p></form> </div>