@eshupps sharepointcowboywww.sharepointcowboy.com
slideshare.net/eshupps linkedin.com/in/eshupps
Eric Shupps
Office Servers & Services MVP
Introduction
SharePoint Add-Ins
Office Add-Ins
Azure Web Applications
SharePoint Framework
Hello, everyone!
Let’s get going
That will be just fine
Please be quiet
This is really good!
Howdy, y’all!
Lesgitafterit
Ayiteden
Kwityerjackjawin
Cantbeatitwiddastick
I am about to get started Imfixintagitrdone
http://www.slideshare.net/eshupps
https://www.github.com/eshupps
Solution Design
Skills and Prerequisites
Development Models
API’s
OAuth
Solution
Full
Trust
Sandbox
FeatureManifest
Web
Part
WSP
Platform
Add-In
OAuth
Azure AD
SSO
Remote
API’s
SPFx
Web Part
App
Part
Consent
Application & Publishing Pages Framework
Web Parts
App Parts / Framework
WP
Application Pages Web Pages
Timer Jobs Web Jobs
List Templates Code
Web Templates Provisioning
Event Receivers Webhooks
• Windows Server
• IIS
• ASP.NET
• SharePoint Server
Framework
•.NET (C#/VB)
•SharePoint Server OM
•CAML/XOML
Languages and API’s
• Visual Studio
Tools
• Browser
• Server
• Mobile
Framework
•HTML, JavaScript (JQuery, Knockout, Angular, React, etc.)
•CSOM, JSOM, REST, Office JS, Graph, OAuth
•C#, VB, Java, PHP, Python, Ruby, Others
Languages and API’s
• Visual Studio
• VS Code
• IDE of choice
Tools
Full Trust
Coverage
Capability
Integration
Familiarity
Add-Ins
Contextual
PHA/SHA
Extensibility
Framework
X-Platform
Customizations
Modern
Azure
Flexible
SSO
Multi-Tenant
Deployment
authorization
User requests
access
App requests
Request Token
Provider returns
Request Token
App builds auth
link w/ Request
Token
User requests URL +
Request Token
Provider returns
access token
User requests URL +
Access Token
App validates
access token
Access token
validated
User granted
access
1
2
3
User requests
access
App requests
Access Token
Provider returns
Access Token
App builds auth
link w/ Access
Token
User requests URL +
Access Token
App validates
access token
Access token
validated
User granted
access
1
2
Manages identity information for principals (STS)Identity Provider
Handles requests for trusted identity claimsSecurity Token Service
Identity provider associated with a web applicationIdentity Token Issuer
Trusted resource (farm, server, etc.)Security Token Issuer
Resource information and signing certificate (JSON)Metadata Endpoint
Used to request permission to protected resourceRequest Token
Used by App to access resource on behalf of userAccess Token
Operation scope for authorizationRealm
Cloud-based security token service (IP-STS)Azure ACS
Client ID App URL
Tenant ID
Tenant ID
Azure ACS
Start
End
SharePoint
Tenant ID
User ID + Issuer + App + Realm
IP-STS URL
Browser or Event Receiver
Token sent to IP-STS (Azure ACS)
{
"typ":"JWT"
"alg":"RS256"
"x5t":"kriMPdmBvx68skT8-mPAB3BseeA"}.{"aud":
"00000003-0000-0ff1-ce00- 000000000000
/binarywaveinc.sharepoint.com@
2ae1caa2-a173-4989-b8f5-9da45655b8f4"
"iss":"00000001-0000-0000-c000-000000000000@
2ae1caa2-a173-4989-b8f5-9da45655b8f4"
"nbf":1400013357
"exp":1400056557
"nameid":"1003000086ad02d6"
"actor":"c90047b7-392a-42e7-8c52-65afa92e5d0d@
2ae1caa2-a173-4989-b8f5-9da45655b8f4"
"identityprovider":"urn:federation:microsoftonline“
}
SharePoint
Host Web
Tenant ID
Start
Azure ACS
Tenant ID
End
Tenant ID
UPN
STS ID
Introduction
Model
Security
Customizations
Deployment
Full Trust
Coverage
Capability
Integration
Familiarity
Add-Ins
Contextual
PHA/SHA
Extensibility
Framework
X-Platform
Customizations
Modern
Azure
Flexible
SSO
Multi-Tenant
Deployment
• Provider Hosted (External)
• SharePoint Hosted (Internal)
Environment
•CSOM/JSOM
•REST/Unified
API’s
• OAuth
• Consent Framework
Security
•Store
•Catalog
Deployment
What Works What Doesn’t
What Doesn’tWhat Works
HTTP-based web service architecture that
uses nouns and verbs to define operations
Noun: “Items”
Verbs: GET, POST, PUT, DELETE
OData provides metadata, object typing and
query semantics for underlying data
structure (WCF data services)
/items(0)
Client Object Model service (client.svc)
processes queries, interacts with server OM,
returns formatted response (JSON, XML)
/items/GetByTitle(‘foo’)
http://contoso/_api/items/GetById(1)?$select=Title,ID
Location Service Resource Path Query Options
http://<site collection>/<site>/_api/sites/features/GetById(guid’<value>’)
http://<site collection>/<site>/_api/sites/eventreceivers
View Event Receivers
http://<site collection>/<site>/_api/web/webinfos/add
{ 'd' :{
'parameters': {
'__metadata': {'type': 'SP.WebInfoCreationInformation' },
'Url': 'RestSubWeb',
'Title': 'RestSubWeb',
'Description': 'rest created web',
'Language':1033,
'WebTemplate':'sts',
'UseUniquePermissions':false}
}}
Create a Site
Get Feature
http://<site collection>/<site>/_api/lists
Get All Lists
http://<site collection>/<site>/_api/lists/GetByTitle(‘Shared Documents’)
Get List
http://<site collection>/<site>/_api/lists/GetByTitle(‘Shared Documents’)/items/GetById(0)
Get List Item
http://<site collection>/<site>/_api/lists/GetByTitle(‘Shared Documents’)/items/
GetById(1)?$select=Title,ID
Get List Item with Specific Properties
http://<site collection>/<site>/_api/search/query?queryText=‘Value’
Simple Term
http://<site collection>/<site>/_api/search/query?queryText=‘PreferredName:
Robert Smith’
Item Property
http://<site collection>/<site>/_api/search/suggest?queryText=‘quarterly sales’
Suggestions
http://<site collection>/<site>/_api/social.following/followed
Get Followed Users
http://<siteCollection>/<site>/_api/social.following/my/followeddocumentsuri
Get Followed Documents
http://<site collection>/<site>/_api/sp.userprofiles.peoplemanager/getmysuggestions
Get Suggestions
http://<siteCollection>/<site>/_api/sp.userprofiles.peoplemanager/
getpeoplefollowedby(accountName=@v)?@v='domainuser'
Get Followers
http://<site>/_api/Web/Lists(guid’<value>′)/Items(1)/FieldValuesAsHtml
HTML Values
http://<site>/_api/web/lists/getbytitle(‘Products’)/items()/?$select=Title,
Price,effectivebasepermissions
Get Permissions
http://<site>/_api/web/lists/getbytitle('Products')/items()?$select=Title,
Price,Supplier_/Title&$expand=Supplier_/Title
Join
http://<site>/_api/web/lists/getbytitle(‘Products’)/items/?$filter=Price gt 30000
Filter with Comparison
http://<site>/_api/web/lists/getbytitle(‘Products’)/items()?
$select=Title,Price,Supplier_/Title&$expand=Supplier_/Title&$filter=Supplier_/Title
eq ‘Acme’
Join with Filter
http://<site collection>/<site>/_api/web/lists('<guid>')/items$top=10
Top ‘N’ Results
url: http://site url/_api/web/lists/GetByTitle(‘Test')/items
method: POST
body: { '__metadata': { 'type': 'SP.Data.TestListItem' }, 'Title': 'Test'}
headers:
Authorization = "Bearer " + accessToken
X-RequestDigest = form digest value
accept: "application/json;odata=verbose"
content-type: "application/json;odata=verbose"
content-length:1024
Create a List Item
url: http://site url/_api/web/lists/GetByTitle(‘Test')/items(item id)
method: POST
body: { '__metadata': { 'type': 'SP.Data.TestListItem' }, 'Title': 'TestUpdated'}
headers:
Authorization = "Bearer " + accessToken
X-RequestDigest = form digest value
“IF-MATCH”: etag or “*”
“X-HTTP-Method”:”MERGE”,
accept: "application/json;odata=verbose"
content-type: "application/json;odata=verbose"
content-length:1024
Edit a List Item
• Used to prevent replay attacks
• Updates will fail without digest value
• Local
• $("#__REQUESTDIGEST").val()
• Remote
• POST to /_api/contextinfo
PermissionsAuthorizationAuthentication
PermissionsAuthorizationAuthentication
App Web
• Not primary user
context
• Declarative artifacts or
code
• Iterative deployments
destroy content
• Only provisioned via
SPHA or PHA with
declarative artifacts
Host Web
• Code only – no
declarative artifacts
• Requires Cross Domain
calls
• Injection remnants
difficult to remove
• On-Premise
• Modify and manipulate – do not replace
Master Pages
•PHA: External (CDN)
•SPHA: External or App Web
Dependencies
• On-Premise: Declarative or Programmatic
• Online: Programmatic
Assets
•Do not rely upon remote event receivers
•Beware the dangers of injection
Retraction
• Apps
• SSL
• DNS
• [PHA] Server to Server (S2S) High Trust or Hybrid Low Trust
Configuration
• [SHA] None
• [PHA] Servers, Networking, Authentication, Admin Access
Resources
•Corporate Catalog
•Developer Site
•Store
Distribution
• Apps
Configuration
• [SHA] None
• [PHA] Servers, Networking, Authentication, Admin Access
Resources
• Corporate Catalog
• Developer Site
• Store
Distribution
Introduction
Components
Model
Creation
Deployment
•Provider Hosted (External)Environment
•Office JS
•REST
API’s
• OAuth
• Consent Framework
Security
•Store
•File
Deployment
OutlookWord/Excel/PowerPoint
Task Pane Content Mail
• Manifest
• App
• Content
• Images
• Scripts
• Common web standards
• Language & platform agnostic (HTML + JavaScript)
• Desktop or Browser
• Text
• HTML
• OOXML
• Table
• Matrix
• Base Requirement
• Callbacks
• Word, Excel, PowerPoint, Access,
Outlook, Project
• Typed Objects
• Promises
• Word, Excel
Capability Word Excel PowerPoint Outlook Project
Get/set data as text, table or matrix All All Text N/A Text
Settings All All All Roaming N/A
Get file All N/A Compressed N/A N/A
Bindings All All N/A N/A N/A
Custom XML Parts All N/A N/A N/A N/A
HTML and OOXML All N/A N/A N/A N/A
Mailbox N/A N/A N/A All N/A
• Submit to Office store
• Configure licensing
• Individual purchase*
Store
• Upload to Corporate Catalog in Office 365
• Add from Ribbon or Settings
Catalog
•Copy to network share
•Set trusted location in Office client
•Add from Developer ribbon
File Share
Introduction
Model
Security
Creation and Configuration
Deployment
Full Trust
Coverage
Capability
Integration
Familiarity
Add-Ins
Contextual
PHA/SHA
Extensibility
Framework
X-Platform
Customizations
Modern
Azure
Flexible
SSO
Multi-Tenant
Deployment
• Provider Hosted (External)Environment
•CSOM/JSOM
•REST/Unified
API’s
• Azure AD
• OAuth
• Consent Framework
Security
•Marketplace
•Azure Portal
Deployment
Host Web
API’s
Azure
Web
Site
App Launcher
What Works What Doesn’t
Bound to single AD domain
Cannot be accessed by other domains
Simplified authorization model
Owned by single authorizing domain
Accessible by any Azure AD domain
Authorized by Azure admin for individual domains
App owner must manage tenant registration
PermissionsAuthorizationAuthentication
Developers cannot modify login experience
User interface is suboptimal
Access to resources requires permission definition
OAuth tokens for O365
POST to app with user/tenant details
App launcher in O365
Users notified of app availability in alerts
Authorization
Exchange
authorization codes
for access tokens
Refresh tokens enable
long-lived sessions
Designed for native
clients and server-side
API’s
Client
Credential
Requires app
authorization consent
from administrator
Shared secrets or
certificates used to
request tokens
Designed for service
apps and server-to-
server scenarios
Implicit
Retrieve access tokens
directly from single
endpoint
No refresh tokens
(local session
management only)
Designed for SPA's
(requires manifest
modification)
Manifest: oauth2AllowImplicitFlow = true
Token and authorization endpoints
Tenant ID = “common” for multi-tenant
WSFED “common” endpoint
Non-customizable consent page in MSFT domain
GET: https://login.microsoftonline.com/common/oauth2/authorize?client_id={client
ID}& response_type=token&redirect_uri={redirect URI}&prompt=admin_consent
Application
Delegated
Minimum: “Sign in and read user profile”
Beware permission level restrictions
Exchange Yammer Azure AD
SharePoint Online Power BI Azure Management
O365 Management Skype
MANIFEST
Visual Studio templates are incomplete
• Database
• Tenants, IssuingAuthorityKeys, SignupTokens
• Registration Module
• XML Response Parser
• Tenant and User Information
• Auth Tokens
• Federation, Realm and Identity Configuration
• HTTPS Redirection
• Sign-In Page (optional)
• AD Apps
• SSL
• DNS
• SSO
• Permissions
• Multi-tenant
Configuration
•Servers, Networking, Authentication, Admin Access
•Azure AD Premium*
Resources
• Admin Authorization
• User/Group Assignment*
Distribution
Introduction
Setup
Creation
Deployment
Management
Full Trust
Coverage
Capability
Integration
Familiarity
Add-Ins
Contextual
PHA/SHA
Extensibility
Framework
X-Platform
Customizations
Modern
Azure
Flexible
SSO
Multi-Tenant
Deployment
• External or Internal CDNEnvironment
•RESTAPI’s
• Azure AD
• OAuth
• Consent Framework
Security
•App catalogDeployment
Add-Ins
• Standalone
• Remote context
• Framed
• Closed toolset
• Classic
Framework
• Integrated
• Native context
• Inline
• Open toolset
• Modern
• Windows Server
• IIS
• ASP.NET
• SharePoint Server
Framework
•.NET (C#/VB)
•SharePoint Server OM
•CAML/XOML
Languages and API’s
• Visual Studio
Tools
• Browser
• Server
• Mobile
Framework
•HTML, JavaScript (JQuery, Knockout, Angular, React, etc.)
•CSOM, JSOM, REST, Office JS, Graph, OAuth
•C#, VB, Java, PHP, Python, Ruby, Others
Languages and API’s
• Visual Studio
• VS Code
• IDE of choice
Tools
Skills
• HTML + CSS
• Adv. JavaScript
• OAuth
• TypeScript
Software
• Code Editor (Any)
• Node.js/NPM/Gulp
• Yeoman Generator
Services
• SP Online
• CDN
• Git
OS
• Windows
• Mac
• Linux
Platform
• Cloud
• On-Premises
TypeScript - JavaScript superset w/ typed objects, classes &extension methods
Node.js - Web server and component packaging extensions
NPM – Packaging and module management utility
Gulp – Task runner and build automation
Yeoman – Project scaffolding generator
CDN – Content delivery network (or location) for hosting
source files
React – JavaScript library of UI components
Office Fabric – Office-centric set of React UI components
@microsoft/generator-sharepoint Yeoman
@microsoft/sp-client-base
@microsoft/sp-webpart-workbench
@microsoft/sp-module-loader
@microsoft/sp-module-interfaces
@microsoft/sp-lodash-subset lodash
@microsoft/sp-tslint-rules
@microsoft/office-ui-fabric-react-bundle office-ui-fabric-
react
• Node.js
• NPM
• GitHub
• Yeoman Generator
• VS Code (optional)
• Visual Studio Extension
• Node.js
• NPM
• GitHub
• Yeoman Generator
• Homebrew (optional)
• NVM (optional)
• VS Code (optional)
• Developer Site
• Workbench
• Corporate Catalog
• Site collection app catalog
• Content Delivery Network (or accessible file location)
• Apps (On-Premises)
Patience
Lots of disk space
Love of command-line utilities
More patience
A good helmet
A virtual machine with lots of snapshots
Vesa’s email address
AC’s mobile number
Fond memories of real development in Visual Studio
A new career path?
• Install the v8.x LTM release of Node.js from
https://nodejs.org/download/release/latest-v8.x/
• Run the x64 MSI (includes NPM)
npm install –g npm@3
nvm use 6.11.0
• Install Yeoman and Gulp: npm install –g yo gulp
• Install SPFx Yeoman generator: npm install –g
@microsoft/generator-sharepoint
• Install code editor (VS Code, Atom, Webstorm, etc.)
• Install Homebrew: https://brew.sh
• Install the v6.x release of Node.js: brew install node@8
brew update node@6
brew install nvm
nvm use 6.11.0
• Install Yeoman and Gulp: npm install –g yo gulp
• Install SPFx Yeoman generator: npm install
@microsoft/generator-sharepoint
• Install code editor (VS Code, Atom, Webstorm, etc.)
Web Part
• In-context
page
component
• Customizable
property
pane
• Connectable
• Scope: Page
Application
Customizer
• Script
injection
onto pages
• Defined
DOM
element
identifiers
• Scope: Site
Command Set
• Modify list
and item
menus
• Custom
dialogs
• Scope: List
Field
Customizer
• Change
display
options for
field
elements
• Scope: List
SP 2016
(FP2)
SPO
SP 2019
• Local test environment for
Framework solutions
• No live data integration
• Mockup and formatting only
• Simulate data operations with mock
objects
• Launch with “gulp serve”
command
• Preview changes prior to
publication
• External or within O365
/sp-dev-fx-webparts/samples/jquery-photopile
• Placeholders
• DOM elements
• Menus
• Data Views
• Fields
• Global via CSOM/REST
• Sites via Feature Framework
loadSPFX Force loading of SPFx
debugManifestsFile Load extension from localhost
componentType Create a mock SP component
key Extension GUID
location Type of extension
properties Extension property collection
?loadSPFX=true&debugManifestsFile=https://localhost:4321/temp
/manifests.js&customActions={"e5625e23-5c5a-4007-a335-
e6c2c3afa485":{"location":"ClientSideExtension.ApplicationCus
tomizer","properties":{"testMessage":"Hello as property!"}}}
• Top
• Global Navigation!
• Bottom
• Called when the extension is activated on the page. Occurs after
CONTEXT and PROPERTIES are assigned.
/sp-dev-fx-extensions/samples/jquery-application-toastr
• Only ListView is currently supported
• Shown only on the Command Bar
• Size is 16 x 16
• Can be a fixed URL or a ”data” element comprised of MIME Type
+ Base64-encoded string
• Called in response to command invocation (i.e. the menu item is
selected).
• Fires for each command in response to changes in the ListView
that require re-rendering.
• Alter text
• Display graphics
• Custom validation
• Concatenate field values
• KPI Indicators
• Called when the extension is activated on the page. Occurs after
CONTEXT and PROPERTIES are assigned.
• Fires when each cell is rendered.
• Fires immediately before the dell is deleted. Use to deallocate
resources (such as UI elements).
/sp-dev-fx-extensions/samples/react-field-slider
• Fields
• Site Columns
• Content Types
• List Instances
• Use the spHttpClient wrapper to simplify operations:
• Import { SPHttpClient, SPHttpClientResponse} from
‘@microsoft/sp-http’
• this.context.spHttpClient.get([REST URL + ODATA])
• Simplifies mock testing
/sp-dev-fx-extensions/samples/jquery-application-toastr
https://docs.microsoft.com/en-
us/sharepoint/dev/spfx/web-parts/guidance/call-
microsoft-graph-from-your-web-part
login.microsoftonline.com
@microsoft/graph-http
• Read and write all groups
• Read all usage reports
https://docs.microsoft.com/en-
us/sharepoint/dev/spfx/overview-graphhttpclient
/sp-dev-fx-extensions/samples/js-application-graph-client
• Kind of sounds like ASP.NET, doesn’t it? 🤔
• Do not rely on global parameters
• Pass a function as a parameter that gets current values at time of
execution
• Apply changes to multiple properties individually
/sp-dev-fx-webparts/samples/react-todo-basic
✘• Completely violates
established (best)
practices of separation
of concerns [MVP, MVC,
MVVM]
• Markup is embedded
with logic – no views
whatsoever - JSX is an
abomination
• Virtual DOM is
imprecise and state is
inconsistent.
• It’s fast. So what? (REST
will always be slow)
package-solution.json
.sppkg
• Change behavior by setting “includeClientSideAssets” = false
gulp bundle --ship
gulp package-solution --ship
* Introduced in SPFx v1.4; If enabled previously, disable and re-enable. Not
compatible with on-premises SP 2016 FP2.
Set-SPOTenantCdnEnabled –CdnType Public
Get-SPOTenantCdnEnabled
Get-SPOTenantCdnOrigins
Get-SPOTenantCdnPolicies
NOTE: Provisioning can take 15+ minutes to complete
http://www.slideshare.net/eshupps
https://www.github.com/eshupps
https://github.com/SharePoint/sp-dev-fx-
extensions/tree/master/samples
https://docs.microsoft.com/en-
us/sharepoint/dev/spfx/sharepoint-framework-
overview
https://github.com/SharePoint/sp-
dev-fx-webparts
https://github.com/SharePoint/sp-
dev-fx-extensions

SharePoint and Office 365 Development Workshop

Editor's Notes

  • #22 OAuth is an open standard for authorization. OAuth provides a method for clients to access server resources on behalf of a resource owner (such as a different client or an end-user). It also provides a process for end-users to authorize third-party access to their server resources without sharing their credentials (typically, a username and password pair), using user-agent redirections. Grew out of collaboration between Twitter, Google, and other social computing vendors, as a means to provide user access and API integration, primarily via OpenID, without requiring individual accounts.
  • #38 Get-SPSecurityTokenServiceConfig S2S_Farm_NoWebApp S2S_Farm_Metadata
  • #41 S2S_Server S2S_App_HighTrust
  • #50 Get-SPSecurityTokenServiceConfig S2S_Farm_NoWebApp S2S_Farm_Metadata
  • #52 Get-SPSecurityTokenServiceConfig S2S_Farm_NoWebApp S2S_Farm_Metadata
  • #55 S2S_Server S2S_App_HighTrust
  • #57 S2S_Server S2S_App_HighTrust
  • #76 S2S_Server S2S_App_HighTrust
  • #83 S2S_Server S2S_App_HighTrust
  • #89 S2S_Server S2S_App_HighTrust
  • #106 S2S_Server S2S_App_HighTrust
  • #125 S2S_Server S2S_App_HighTrust
  • #154 ?loadSPFX=true&debugManifestsFile=https://localhost:4321/temp/manifests.js
  • #159 ?loadSPFX=true&debugManifestsFile=https://localhost:4321/temp/manifests.js&customActions={”[GUID]":{"location":"ClientSideExtension.ApplicationCustomizer","properties":{"testMessage":"Hello world!"}}}
  • #160 Debug URL: ?loadSPFX=true&debugManifestsFile=https://localhost:4321/temp/manifests.js&customActions={” a861c815-e425-416d-9520-04bcdf557e27":{"location":"ClientSideExtension.ApplicationCustomizer","properties":{}}}
  • #163 ?loadSpfx=true&debugManifestsFile=https://localhost:4321/temp/manifests.js&customActions={”[GUID]":{"location":"ClientSideExtension.ListViewCommandSet.CommandBar","properties":{"sampleTextOne":"One item is selected in the list.","sampleTextTwo":"This command is always visible."}}}
  • #167 Debug URL: ?loadSPFX=true&debugManifestsFile=https://localhost:4321/temp/manifests.js&fieldCustomizers={"Percent":{"id":"f2f6825c-fd37-43f7-a99c-5fe6b39dd7fd","properties":{"sampleText":"Hello!"}}}
  • #174 Debug URL: ?loadSPFX=true&debugManifestsFile=https://localhost:4321/temp/manifests.js&customActions={"6ed4a222-c0c8-441e-ae2e-d2240084deff":{"location":"ClientSideExtension.ApplicationCustomizer"}}
  • #176 S2S_Server S2S_App_HighTrust
  • #191 S2S_Server S2S_App_HighTrust