Wednesday, May 17, 2017

Azure Active Directory B2C - Providing sign-up and sign-in to users with Microsoft Accounts

Create a Microsoft account application

To use Microsoft account as an identity provider in Azure Active Directory (Azure AD) B2C, you need to create a Microsoft account application and supply it with the right parameters. You need a Microsoft account to do this. If you don’t have one, you can get it at https://www.live.com/.
  1. Go to the Microsoft Application Registration Portal and sign in with your Microsoft account credentials.
  2. Click Add an app.
  3. Provide a Name for your application and click Create .
  4. Copy the value of Application Id. You will need it to configure Microsoft account as an identity provider in your tenant.
  5. Click on Add platform and choose Web.

  6. Enter https://login.microsoftonline.com/te/{tenant}/oauth2/authresp in the Redirect URIs field. Replace {tenant} with your tenant's name (for example, contosob2c.onmicrosoft.com).
  7. Click on Generate New Password under the Application Secrets section. Copy the new password displayed on screen. You will need it to configure Microsoft account as an identity provider in your tenant. This password is an important security credential.

  8. Check the box that says Live SDK support under the Advanced Options section. Click Save.

Configure Microsoft Account as an identity provider (IDP) in your tenant

  1. Follow these steps to navigate to the B2C features blade on the Azure portal.
  2. On the B2C features blade, click Identity providers.
  3. Click +Add at the top of the blade.
  4. Provide a friendly Name for the identity provider configuration. For example, enter "MSA".
  5. Click Identity provider type, select Microsoft account, and click OK.
  6. Click Set up this identity provider and enter the Application Id and password of the Microsoft account application that you created earlier.
  7. Click OK and then click Create to save your Microsoft account configuration.

Azure Active Directory B2C- Register your application

If you have the B2C features blade pinned to your Startboard, you will see the blade as soon as you sign in to the Azure portal as the Global Administrator of the B2C tenant.
You can also access the blade by clicking More services and then searching Azure AD B2C in the left navigation pane on the Azure portal.

Register a web application

  1. On the B2C features blade on the Azure portal, click Applications.
  2. Click +Add at the top of the blade.
  3. Enter a Name for the application that will describe your application to consumers. For example, you could enter "Jo B2C App".
  4. Toggle the Include web app / web API switch to Yes. The Reply URLs are endpoints where Azure AD B2C will return any tokens that your application requests. For example, enter https://localhost:38143/.
  5. Click Create to register your application.
  6. Click the application that you just created and copy down the globally unique Application Client ID that you'll use later in your code.
  7. If your web application will also be calling a web API secured by Azure AD B2C, you'll want to create an Application Secret by going to the Keys blade and clicking the Generate Key button.

Register a web api

  1. On the B2C features blade on the Azure portal, click Applications.
  2. Click +Add at the top of the blade.
  3. Enter a Name for the application that will describe your application to consumers. For example, you could enter "Jo B2C api".
  4. Toggle the Include web app / web API switch to Yes. The Reply URLs are endpoints where Azure AD B2C will return any tokens that your application requests. For example, enter https://localhost:38143/.
  5. Enter an App ID URI. This is the identifier used for your web API. For example, enter 'notes'. It will generate the full identifier URI underneath.
  6. Click Create to register your application.
  7. Click the application that you just created and copy down the globally unique Application Client ID that you'll use later in your code.
  8. Click on Published scopes. This is where you define the permissions (scopes) that can be granted to other applications.
  9. Add more scopes as necessary. By default, the "user_impersonation" scope will be defined. This gives other applications the ability to access this api on behalf of the signed-in user. This can be removed if you wish.
  10. Click Save.

Register a mobile/native application

  1. On the B2C features blade on the Azure portal, click Applications.
  2. Click +Add at the top of the blade.
  3. Enter a Name for the application that will describe your application to consumers. For example, you could enter "Jo B2C App".
  4. Toggle the Include native client switch to Yes.
  5. Enter a Redirect URI with a custom scheme. For example, com.onmicrosoft.jollsam.appname://redirect/path. 
  6. Click Save to register your application.
  7. Click the application that you just created and copy down the globally unique Application Client ID that you'll use later in your code.
  8. If your native application will also be calling a web API secured by Azure AD B2C, you'll want to create an Application Secret by going to the Keys blade and clicking the Generate Key button.

Choosing a redirect URI

There are two important considerations when choosing a redirect URI for mobile/native applications:
  • Unique: The scheme of the redirect URI should be unique for every application. In our example (com.onmicrosoft.jollsam.appname://redirect/path), we use com.onmicrosoft.jollsam.appname as the scheme. We recommend following this pattern. If two applications share the same scheme, the user will see a "choose app" dialog. If the user makes an incorrect choice, the login will fail.
  • Complete: Redirect URI must have a scheme and a path. The path must contain at least one forward slash after the domain (for example, //jollsam/ will work and //jollsam will fail).

Build a Quick Start Application

Now that you have an application registered with Azure AD B2C, you can complete one of our quick-start tutorials to get up and running

Tuesday, May 16, 2017

Update SharePoint Online userprofile properties - Powershell

The below powershell script is to update a user profile property called 'CostCenter' and you can replace with your property and update it.

Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.UserProfiles.dll"


$SiteUrl = "https://tenant-admin.sharepoint.com"



$password = Read-Host -Prompt "Enter password" -AsSecureString

$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials("jollsam@tenant.com", $password)


#Set up the context
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl)
$Context.Credentials = $credentials

$targetAccount = "i:0#.f|membership|jollsam@tenant.com"

$PropertyName= "CostCenter"

$Value = "17029"

$peopleManager = New-Object Microsoft.SharePoint.Client.UserProfiles.PeopleManager($Context)

Write-Host "Updating User Profile Property `"$PropertyName`" for account - `"$targetAccount`"" -ForegroundColor Green

$peopleManager.SetSingleValueProfileProperty($targetAccount, $PropertyName, $Value)

$Context.ExecuteQuery()

Wednesday, March 22, 2017

Users unable to access sub folders in SharePoint 2013 - Limited Access issue

This issue happens when you migrate your site from SharePoint 2010 to SharePoint 2013 and you have Limited Access users in your site.
My scenario was below.
Problem
  • I have a sharepoint 2013 site and a document library inside.
  • Have more than 2 sub folders for the document library.
  • Few Users are directly given access to the sub folders without any permission on Library and site.
  • The above users are getting access denied while accessing the folder where they have been given Read/Contribute access.

Cause
  • Since we don't have Limited Access permission level in SharePoint 2013  and when you give users Read/Contribute access to the sub folders, user are not added as Limited Access to the library level.
  • still users should be able to access the sub folders directly as access is given.
  • This issue mainly happens with Publishing sites as when you activate publishing feature, one more site collection feature gets activated as below
  • LimitedAccess_Activated
  • This feature will prevent users with limited access to access the sub folders in library.

Resolution
Just deactivate the site collection feature and you are good to go.
LimitedAccess_Deactivated
The ViewFormPagesLockDown Feature (Site Collection) in SharePoint 2013 is activated and visible by default. This is not the case for previous SharePoint versions.

Thursday, March 2, 2017

Using Microsoft Azure Active Directory for SharePoint 2013 authentication


Summary: Use the Azure Access Control Service to authenticate your SharePoint Server 2013 users with Azure Active Directory.

This article explains how you can use the Azure Access Control Service to authenticate your SharePoint 2013 users with Azure AD, instead of your on-premises Active Directory. In this configuration, Azure AD becomes a trusted identity provider for SharePoint 2013. This configuration adds a user authentication method that is separate from Active Directory authentication used by the SharePoint 2013 installation itself. For more information on WS Federation, see Understanding WS-Federation.
The below diagram shows how authentication works for SharePoint 2013 users in this configuration.
ic728833

Configuration Overview

  1. Create a new Azure AD tenant and namespace.
  2. Add a WS-Federation identity provider.
  3. Add SharePoint as a relying party application.
  4. Create a rule group for claims-based authentication.
  5. Configure the X.509 certificate.
  6. Create a claim mapping.
  7. Configure SharePoint for the new identity provider.
  8. Set the permissions.
  9. Verify the new provider.

    Create ACS and Azure AD App

    Use the following steps to create a new Azure AD tenant and an associated namespace. In this example, we use the namespace "specmazureadservice"
    1. In the Azure Management Portal, click Active Directory.
    2. Click Access Control Namespaces, and create a new namespace.
    3. Click Manage on the bottom bar. This should open this location, https://specmazureadservice.accesscontrol.windows.net/v2/mgmt/web.
    4.  
    5. Go to Azure AD and create new App. In my  case the app name is 'AZ AD Tenant APP'.
    6. Put the Sign-on Url same as ACS url "https://specmazureadservice.accesscontrol.windows.net/"
    7. App ID can be any unique url. I have used the same ACS url.
    8. For Reply URL, use the same ACS url "https://specmazureadservice.accesscontrol.windows.net/"
    9. Save the App.
    10. click on the "View Endpoints" at bottom and copy "Federation Metadata Document" url.

Add a WS-Federation identity provider to the namespace

Use the following steps to add a new WS-Federation identity provider to the "specmazureadservice" namespace.
  1. From the Azure management portal, go to Active Directory > Access Control Namespaces, select the ACS created  and then click Manage.
  2. From the Azure Access Control portal, click Identity Providers > Add, as illustrated in the following figureacshome
  3. Click WS-Federation identity provider, as illustrated in the following figure, and then click Nextacs_addidprovider
Fill out the display name and logon link text, and then click Save. For the WS-Federation metadata URL, put the url copied from AD App Federation Metadata document. eg. https://login.microsoftonline.com/e0b26355-1889-40d8-8ef1-e559616defth/federationmetadata/2007-06/federationmetadata.xml. The following picture illustrates the setting.acs_addws-fedidprovider
Add SharePoint as a relying party application
  1. From the Azure Access Control portal, click Relying party applications, and then click Add, as illustrated in the following pictureacs_addrelypartapp
  2. Provide the display name  eg "ECM Azure AD Rely".
  3. provide Realm , eg - "urn:sharepoint:spapps-stg".
  4. provide Return url as your sharepoint web application url "/_trust" , eg- "http://sharepoint.com/_trust".
Select SAML 1.1 as the token format url. Select IDP and click save. Below picture gives an overview of how it looks like.acs_addrelypartysettingsacs_addrelypartysettings2

Create a rule group for claims-based authentication

  1. In the left pane, click Rule groups, and then click Add.
  2. Type a name for the rule group, click Save, and then click Generate. For the purposes of this article, we are using Default Rule Group for. ECM Azure AD Rely, as illustrated in the below picture.acs_rulegroup
    acs_rules
Click the rule group that you want to change, and then click the claim rule that you want to change. For the purposes of this article, we add a claim rule to the group to pass name as upn, as illustrated by the below picture.acs_newclaimrule

Configure the X.509 certificate

  1. In the Access Control Service pane, Click on Certificates and Keys as given in below pciture certandkeys
  2. Click on Add and copy the makecert command as highlighted in below picture.addtokensigningcert
  3. Create a new certificate with the command in local machine and export it as .pfx (with password) and .cer .
  4. Upload the TokenSigning certificate in the choose file and provide the same password.
  5. Make it primary and click save.

Create a claim mapping by using SharePoint Management Shell

Below is the script I used to configure the claim mapping and New Trusted Identity provider for Azure AD Connect.
$realm = "urn:sharepoint:spapps-stg"
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("F:\Jollgin\certs\ACSTokenSigning.cer")
New-SPTrustedRootAuthority -Name "ACS EK Token Signing" -Certificate $cert
$map = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" -IncomingClaimTypeDisplayName "UPN" -SameAsIncoming
$map2 = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname" -IncomingClaimTypeDisplayName "GivenName" -SameAsIncoming
$map3 = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname" -IncomingClaimTypeDisplayName "SurName" -SameAsIncoming

New-SPTrustedIdentityTokenIssuer -Name "ACS Provider" -Description "SharePoint secured by SAML in ACS" -realm $realm -ImportTrustCertificate $cert -ClaimsMappings $map,$map2,$map3 -SignInUrl "https://specmazureadservice.accesscontrol.windows.net/v2/wsfederation" -IdentifierClaim "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"

Configure SharePoint for the new identity provider

  1. Verify that the user account that is performing this procedure is a member of the Farm Administrators SharePoint group.
  2. In Central Administration, on the home page, click Application Management.
  3. On the Application Management page, in the Web Applications section, click Manage web applications.
  4. Click the appropriate web application.
  5. From the ribbon, click Authentication Providers.
  6. Under Zone, click the name of the zone. For example, Im using Custom as my web application is an extended one.
  7. On the Edit Authentication page, in the Claims Authentication Types section, select Trusted Identity provider, and then click the name of your provider, which for purposes of this article is ACS Provider. Click OK.
The below picture illustrates the Trusted Provider settingsptrustedidp

Set the permissions

For testing purpose, Go to user policy in web application and provide everyone read access to the web application and later on remove and give individual permissions in site level.

Verify the new provider

  1. Enter the web application url in browser.
  2. I had my custom login page and it looks like belowsplogin
  3. Click on Azure AD Connect and you will be redirected to login.microsoftonline.com. Provide you organization account or onmicrosoft account and once authenticated with Azure AD, you will be back to the SharePoint onpremise application.
With this you have acheived the WS Federation login for your on premise sharepoint application, you can have onmicrosoft account which is not in you AD and login to on premise sharepoint application.

Monday, February 20, 2017

Migrate SharePoint Users to/from ADFS

Moving from a domain authentication between ADFS authentication and on premise AD authentication is becoming a not uncommon activity these days, partly because incorporating ADFS into your on-premises farm is the first step in moving either completely or partially into SharePoint Online.
Step 1. You need to move the content db to the target farm and attach it. users wont be able to access until you do the user migration.
Step 2. User Migration - Script is given below for getting list of users and migrate. 
#Start
Set-PSDebug -Strict
add-pssnapin microsoft.sharepoint.powershell -erroraction 0

# Select Options
Write-Host -ForegroundColor Yellow "'Document' will create a CSV dump of users to convert. 'Convert' will use the data in the CSV to perform the migrations."
Write-Host -ForegroundColor Cyan "1. Document"
Write-Host -ForegroundColor Cyan "2. Convert"
Write-Host -ForegroundColor Cyan " "
[int]$Choice = Read-Host "Select an option 1-2: "

switch($Choice)
{
1 {[bool]$convert = $false}
2 {[bool]$convert = $true}
default {Write-Host "Invalid selection! Exiting... "; exit}
}
Write-Host ""

$objCSV = @()
[string]$csvPath = Read-Host "Please enter the path to save the .csv file to. (Ex. C:\migration)"
if ((Test-Path -LiteralPath $csvPath) -eq $false) {
Write-Host "Invalid path specified! Exiting..."; exit
}

if($convert-eq $true)
{
$objCSV = Import-CSV "$csvPath\MigrateUsers.csv"

foreach ($object in $objCSV)
{
$user = Get-SPUser -identity $object.OldLogin -web $object.SiteCollection
write-host "Moving user:" $user "to:" $object.NewLogin "in site:" $object.SiteCollection
move-spuser -identity $user -newalias $object.NewLogin -ignoresid -Confirm:$false
}
}
else
{
[string]$oldprovider = Read-Host "Enter the Old Provider Name (Example -> Domain\ or i:0#.f|MembershipProvider|) "
[string]$newprovider = Read-Host "Enter the New User Provider Name (Example -> Domain\ or i:0e.t|MembershipProvider|) "
[string]$newsuffix = Read-Host "Enter the UPN suffix for the new provider, if desired (Example -> @domain.com) "
[string]$newGroupProvider = Read-Host "Enter the New Group Provider Name (Example -> Domain\ or c:0-.t|MembershipProvider|domain.com\) "


# Select Options
Write-Host -ForegroundColor Yellow "Choose the scope of the migration - Farm, Web App, or Site Collection"
Write-Host -ForegroundColor Cyan "1. Entire Farm"
Write-Host -ForegroundColor Cyan "2. Web Application"
Write-Host -ForegroundColor Cyan "3. Site Collection"
Write-Host -ForegroundColor Cyan " "
[int]$scopeChoice = Read-Host "Select an option 1-3: "

switch($scopeChoice)
{
1 {[string]$scope = "Farm"}
2 {[string]$scope = "WebApp"}
3 {[string]$scope = "SiteColl"}
default {Write-Host "Invalid selection! Exiting... "; exit}
}
Write-Host ""
if($scope -eq "Farm")
{
$sites = @()
$sites = get-spsite -Limit All
}
elseif($scope -eq "WebApp")
{
$url = Read-Host "Enter the Url of the Web Application: "
$sites = @()
$sites = get-spsite -WebApplication $url -Limit All
}
elseif($scope -eq "SiteColl")
{
$url = Read-Host "Enter the Url of the Site Collection: "
$sites = @()
$sites = get-spsite $url
}

foreach($site in $sites)
{
$webs = @() #needed to prevent the next foreach from attempting to loop a non-array variable
$webs = $site.AllWebs

foreach($web in $webs)
{
# Get all of the users in a site
$users = @()
$users = get-spuser -web $web -Limit All #added "-limit" since some webs may have large user lists.

# Loop through each of the users in the site
foreach($user in $users)
{
# Create an array that will be used to split the user name from the domain/membership provider
$a=@()
$displayname = $user.DisplayName
$userlogin = $user.UserLogin

if(($userlogin -like "$oldprovider*") -and ($objCSV.OldLogin -notcontains $userlogin))
{
# Separate the user name from the domain/membership provider
if($userlogin.Contains('|'))
{
$a = $userlogin.split("|")
$username = $a[1]

if($username.Contains('\'))
{
$a = $username.split("\")
$username = $a[1]
}
}
elseif($userlogin.Contains('\'))
{
$a = $userlogin.split("\")
$username = $a[1]
}

# Create the new username based on the given input
if ($user.IsDomainGroup) {
[string]$newalias = $newGroupProvider + $username
} else {
[string]$newalias = $newprovider + $username + $newsuffix
}


$objUser = "" | select OldLogin,NewLogin,SiteCollection
$objUser.OldLogin = $userLogin
$objUser.NewLogin = $newAlias
$objUser.SiteCollection = $site.Url

$objCSV += $objUser
}
}
}
$site.Dispose()
}

$objCSV | Export-Csv "$csvPath\MigrateUsers.csv" -NoTypeInformation -Force
}
#End
csv format is as below.
ADFS to onpremise
OldLoginNewLoginSiteCollection
i:05.t|adfs|explporetest@sp.comi:0#.w|domain\explporetesthttps://exploresharepointfeatures.sharepoint.com/sites/test

onpremise to ADFS
OldLoginNewLoginSiteCollection
i:0#.w|domain\explporetesti:05.t|adfs|explporetest@sp.comhttps://exploresharepointfeatures.sharepoint.com/sites/test

Thursday, February 16, 2017

Update SharePoint Online Audit settings using powershell

You can use below scrip to update Audit settings in SharePoint online using powershell csom. For updating in all site, just loop through all site collections and update it.


#Load SharePoint CSOM Assemblies
[System.Reflection.Assembly]::LoadFile("<dllPath>\Microsoft.SharePoint.Client.dll") | Out-Null
[System.Reflection.Assembly]::LoadFile("<dllPath>\Microsoft.SharePoint.Client.Runtime.dll") | Out-Null



#$SiteUrl = "https://emiratesgroup.sharepoint.com/sites/spdev"
$Password = ConvertTo-SecureString "<enter pswd here>" -AsPlainText –Force
$User = "jo@domain.com"
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($User, $Password)

     
        $SiteUrl = $object.SiteCollection
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl)
$Context.Credentials = $credentials

 $spoSite = $Context.Site
    $Context.Load($spoSite)
    $Audit = $spoSite.Audit
    $Context.Load($Audit)
    $Context.ExecuteQuery()

$All = [Microsoft.SharePoint.Client.AuditMaskType]::All;
    $None = [Microsoft.SharePoint.Client.AuditMaskType]::None;
    $CheckIn = [Microsoft.SharePoint.Client.AuditMaskType]::CheckIn;
    $CheckOut = [Microsoft.SharePoint.Client.AuditMaskType]::CheckOut;
    $ChildDelete = [Microsoft.SharePoint.Client.AuditMaskType]::ChildDelete;
    $CheckIn = [Microsoft.SharePoint.Client.AuditMaskType]::CopyCheckIn;
    $Move = [Microsoft.SharePoint.Client.AuditMaskType]::Move;
    $ObjectDelete = [Microsoft.SharePoint.Client.AuditMaskType]::ObjectDelete;
    $ProfileChange = [Microsoft.SharePoint.Client.AuditMaskType]::ProfileChange;
    $SchemaChange = [Microsoft.SharePoint.Client.AuditMaskType]::SchemaChange;
    $Search = [Microsoft.SharePoint.Client.AuditMaskType]::Search;
    $SecurityChange = [Microsoft.SharePoint.Client.AuditMaskType]::SecurityChange;
    $Undelete = [Microsoft.SharePoint.Client.AuditMaskType]::Undelete;
    $Update = [Microsoft.SharePoint.Client.AuditMaskType]::Update;
    $View = [Microsoft.SharePoint.Client.AuditMaskType]::View;
    $Workflow = [Microsoft.SharePoint.Client.AuditMaskType]::Workflow;


$Audit.AuditFlags = $Update, $Undelete, $SecurityChange
$Audit.Update()
$spoSite.AuditLogTrimmingRetention = 90
$spoSite.TrimAuditLog = $true
$Audit.Update()
$Context.ExecuteQuery()

write-host "updated for site:" $object.SiteCollection