<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Patrick Lamber</title>
    <description>The latest articles on Forem by Patrick Lamber (@plamber).</description>
    <link>https://forem.com/plamber</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F262635%2F381b5fb1-7fca-492f-aaa3-ad6a601447c6.jpeg</url>
      <title>Forem: Patrick Lamber</title>
      <link>https://forem.com/plamber</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/plamber"/>
    <language>en</language>
    <item>
      <title>How do I rename a SharePoint Online site using PowerShell?</title>
      <dc:creator>Patrick Lamber</dc:creator>
      <pubDate>Tue, 21 Jan 2020 12:48:18 +0000</pubDate>
      <link>https://forem.com/expertsinside/how-do-i-rename-a-sharepoint-online-site-using-powershell-3ok</link>
      <guid>https://forem.com/expertsinside/how-do-i-rename-a-sharepoint-online-site-using-powershell-3ok</guid>
      <description>&lt;p&gt;A SharePoint Online administrator can change the SharePoint Online &lt;a href="https://docs.microsoft.com/en-us/sharepoint/change-site-address"&gt;site address&lt;/a&gt;. The interesting part of this feature is that in many situations Microsoft already considered how to limit the impact of such a change. Nevertheless, you should have a look into the &lt;a href="https://docs.microsoft.com/en-us/sharepoint/change-site-address"&gt;effects of changing a site address&lt;/a&gt; before performing any operation. &lt;/p&gt;

&lt;p&gt;I created a sample script that shows you how to use PowerShell to perform a site change.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## Install the SharePoint Online Management Module if required
## Install-Module -Name Microsoft.Online.SharePoint.PowerShell 
## More info under https://www.nubo.eu/Connect-to-SharePoint-Online-using-PowerShell/

## parameters start
$tenant = "yourTenantName"
$sourceAlias = "aliasOfYourSource"
$targetAlias = "aliasOfYourTarget"
## parameters end

# Connect to SPO and perform the site rename
Connect-SPOService "https://$tenant-admin.sharepoint.com"
$oldUrl = "https://$tenant.sharepoint.com/sites/$sourceAlias"
$newUrl = "https://$tenant.sharepoint.com/sites/$targetAlias"

# Perform the site rename
Start-SPOSiteRename -Identity $oldUrl -NewSiteUrl $newUrl

# The process might take a while depending the size of the site. You can check the status using this command
Get-SPOSiteRenameState -Identity $oldUrl

# By using the standard parameters of Start-SPOSiteRename, a successful site rename will provision  After a successfull site rename a new site with the template 'RedirectSite#0' is created

$site = Get-SPOSite $oldUrl
$site.Template
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;From the script, you can see that the operations are triggered by using the &lt;a href="https://docs.microsoft.com/en-us/powershell/module/sharepoint-online/start-spositerename?view=sharepoint-ps"&gt;Start-SPOSiteRename&lt;/a&gt; command. This will queue a rename job that will be executed in the background. The command &lt;a href="https://docs.microsoft.com/en-us/powershell/module/sharepoint-online/Get-SPOSiteRenameState?view=sharepoint-ps"&gt;Get-SPOSiteRenameState&lt;/a&gt; will return you the current status of the job. Once the job is marked as completed, you will have two sites in your tenant. You will have the site with the new URL and contents and a new site using the Template &lt;strong&gt;Redirect#0&lt;/strong&gt;. This site will ensure that all requests pointing to the old URL will be redirected to the new URL. This site also ensures that nobody is able to request a new site with the old URL. &lt;/p&gt;

&lt;p&gt;In case you want to free up the old name, delete the site collection that has been created for redirection.&lt;/p&gt;

</description>
      <category>sharepoint</category>
      <category>powershell</category>
    </item>
    <item>
      <title>How do I authenticate against Azure AD using React, MSAL.JS and ASP.NET Core 3.0?</title>
      <dc:creator>Patrick Lamber</dc:creator>
      <pubDate>Thu, 09 Jan 2020 12:30:35 +0000</pubDate>
      <link>https://forem.com/expertsinside/how-do-i-authenticate-against-azure-ad-using-react-msal-js-and-asp-net-core-3-0-mam</link>
      <guid>https://forem.com/expertsinside/how-do-i-authenticate-against-azure-ad-using-react-msal-js-and-asp-net-core-3-0-mam</guid>
      <description>&lt;p&gt;This post is also located &lt;a href="https://www.nubo.eu/How-do-I-authenticate-against-Azure-AD-using-React-SPA-and-ASP-NET-Core/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Microsoft is evolving the Azure Active Directory (v1.0) endpoints into the new Microsoft identity platform (v2.0). You should give it a try and consider a move to this new platform. &lt;a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/azure-ad-endpoint-comparison"&gt;This article&lt;/a&gt; if you are interested to understand more and identify the main reasons for performing the switch.&lt;/p&gt;

&lt;p&gt;From a software development perspective, you used ADAL (Azure Active Directory Library) to help you get authenticated against the old Azure Active Directory (v1.0) services. If you want to integrate your application with the Microsoft identity platform (v2.0), you can use MSAL (Microsoft Authentication Library) instead. An overview of MSAL is given &lt;a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-overview"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  The scenario
&lt;/h2&gt;

&lt;p&gt;I wanted to implement both, an ASP.NET Core project to act as an API backend, and a standard CRA React project to act as a UI, but with the convenience of hosting both in a single app project that can be built and published as a single unit. &lt;br&gt;
The authentication has to be handled on the client-side forcing the user to authenticate once accessing any page. Once authenticated, I wanted to provide simple user information about the logged-in user using Microsoft Graph.&lt;/p&gt;

&lt;p&gt;You can find the results of this project in &lt;a href="https://github.com/plamber/MSAL-Authenticationsamples/tree/master/MSAL-Authenticationsamples/AAD-React-AspNetCore"&gt;this GitHub&lt;/a&gt;. I used the existing &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/client-side/spa/react?view=aspnetcore-3.1&amp;amp;tabs=visual-studio"&gt;React project template with ASP.NET Core&lt;/a&gt; as a foundation for my project.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is the website doing?
&lt;/h2&gt;

&lt;p&gt;The users are immediately forced to authenticate themselves once accessing the website. MSAL.JS is used to handle the whole authentication flow. For this, an Azure AD application was registered on the target tenant. &lt;/p&gt;

&lt;p&gt;Once authenticated, the user sees basic information about him/her on the upper-right corner. This information is coming from the authentication token provided by Azure AD. If you just want to authenticate the user using Azure AD, we are already done. &lt;/p&gt;

&lt;p&gt;I also added a section that shows how to get the basic information about the user using Microsoft Graph. This is handled by the page &lt;em&gt;Get Graph data&lt;/em&gt; and the Microsoft Graph JavaScript libraries included in the project.&lt;/p&gt;

&lt;p&gt;At this stage, there is no further interaction with ASP.NET Core. I am not consuming any secured API on our back-end. This will be handled in a future post.&lt;/p&gt;
&lt;h2&gt;
  
  
  How do I get started?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;fork/clone &lt;a href="https://github.com/plamber/MSAL-Authenticationsamples/"&gt;this GitHub repository&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;open the project under MSAL-Authenticationsamples/AAD-React-AspNetCore&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you just want to test it without additional hassle, just run the project. I already configured a multi-tenant application in my test tenant that allows you to authenticate against Azure AD. &lt;/p&gt;

&lt;p&gt;Follow the steps below if you want to have your dedicated Azure AD application.&lt;/p&gt;
&lt;h3&gt;
  
  
  I want to use my dedicated Azure AD application
&lt;/h3&gt;

&lt;p&gt;If you want to use your dedicated Azure AD application, follow these basic steps. You need to ensure that you are properly configuring a new application in Azure AD. Once configured, you need to change the configuration of the application in the code.&lt;/p&gt;
&lt;h4&gt;
  
  
  Register your app
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;a href="https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredApps"&gt;App Registration in Azure AD&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Press &lt;em&gt;New registration&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Specify a name and choose the desired account types (Single tenant, Multitenant) and then press &lt;em&gt;Register&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Copy the &lt;em&gt;Application (client) ID&lt;/em&gt; (&lt;strong&gt;yourClientID&lt;/strong&gt;) and &lt;em&gt;Directory (tenant) ID&lt;/em&gt; (&lt;strong&gt;yourTenantID&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;Go to &lt;em&gt;Authentication&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;Under &lt;em&gt;Redirect URIs&lt;/em&gt; create two entries: &lt;a href="https://localhost:44321/signin-oidc"&gt;https://localhost:44321/signin-oidc&lt;/a&gt;, &lt;a href="https://localhost:44366/"&gt;https://localhost:44366/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Under &lt;em&gt;Implicit grant&lt;/em&gt; select &lt;em&gt;Access tokens&lt;/em&gt; and &lt;em&gt;ID tokens&lt;/em&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Change the configuration in Visual Studio to use your created application
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Go under &lt;em&gt;ClientApp&lt;/em&gt; -&amp;gt; &lt;em&gt;src&lt;/em&gt; -&amp;gt; &lt;em&gt;msal&lt;/em&gt; -&amp;gt; &lt;em&gt;MsalConfig.js&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;Replace the &lt;em&gt;clientId&lt;/em&gt; value with &lt;strong&gt;yourClientID&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;In case you configured a single tenant application, replace &lt;em&gt;common&lt;/em&gt; in the &lt;em&gt;authority&lt;/em&gt; value with &lt;strong&gt;youTenantID&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Key aspects in the code
&lt;/h2&gt;

&lt;p&gt;The app is using the &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/client-side/spa/react?view=aspnetcore-3.1&amp;amp;tabs=visual-studio"&gt;React project template with ASP.NET Core&lt;/a&gt; as a basis. I just removed the unnecessary &lt;em&gt;Weather&lt;/em&gt; controllers and added some minor things.&lt;/p&gt;
&lt;h3&gt;
  
  
  Install the required client-side libraries
&lt;/h3&gt;

&lt;p&gt;I used NPM to install the necessary client-side libraries. &lt;em&gt;msal&lt;/em&gt; is used to get MSAL.JS while &lt;em&gt;@microsoft/microsoft-graph-client&lt;/em&gt; is used for the Microsoft Graph integration part.&lt;/p&gt;

&lt;p&gt;In &lt;em&gt;package.json&lt;/em&gt; you should find these entries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"@microsoft/microsoft-graph-client": "^2.0.0",
"msal": "^1.2.0",
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Forcing the authentication in React
&lt;/h3&gt;

&lt;p&gt;One of my requirements was to force the authentication whenever a user is accessing a page. To implement this, I found it convenient to use the React &lt;a href="https://reactjs.org/docs/higher-order-components.html"&gt;Higher-Order Component pattern&lt;/a&gt; to encapsulate the MSAL.JS authentication logic. The &lt;em&gt;MsalAuthProvider.js&lt;/em&gt; is responsible for this part. The authentication is handled by the logic below. If a user is not authenticated, authenticate him/her using the Azure AD settings in our config.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;componentWillMount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;msalAuth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleRedirectCallback&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;userAccount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;msalAuth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAccount&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;isAuthenticated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userAccount&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;authErr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;accountState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  &lt;span class="c1"&gt;// on fail&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;authErr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;hasError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;errorMessage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;authErr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errorMessage&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msalAuth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;renewIframe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;userAccount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;msalAuth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAccount&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;userAccount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;msalAuth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loginRedirect&lt;/span&gt;&lt;span class="p"&gt;({});&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;isAuthenticated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userAccount&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This function is used in the &lt;em&gt;App.js&lt;/em&gt; file to wire-up the authentication and associate it with the main React app using the High-Order Component pattern.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class RootApp extends Component {
    render() {
        return (
            &amp;lt;Layout {...this.props} &amp;gt;
                &amp;lt;Route exact path='/' component={Home} /&amp;gt;
                &amp;lt;Route exact path='/graph-data' component={GraphData} /&amp;gt;
            &amp;lt;/Layout&amp;gt;
        );
    }
}
export const App = withAuth(RootApp);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;em&gt;GraphData.js&lt;/em&gt; file is handling the creation of the Graph client and the retrieval of the graph information of the user. You can find under &lt;em&gt;GraphService.js&lt;/em&gt; the part of the code which is requesting a new token for the Graph request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const accessTokenRequest = {
    scopes: ["user.read"]
}
var accessToken = null;
try {
    accessToken = await msalAuth.acquireTokenSilent(accessTokenRequest);
}
catch (error) {
    console.log("AquireTokenSilent failure");
    accessToken = await msalAuth.acquireTokenPopup(accessTokenRequest);
}

if (accessToken) {
    var user = await getUserDetails(accessToken);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Go and change the &lt;em&gt;MsalConfig.js&lt;/em&gt; if you want to manipulate the authentication settings for MSAL.JS. You can find the configuration options of MSAL.JS under &lt;a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-js-initializing-client-applications"&gt;this link&lt;/a&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Summarizing
&lt;/h3&gt;

&lt;p&gt;With &lt;a href="https://github.com/plamber/MSAL-Authenticationsamples/tree/master/MSAL-Authenticationsamples/AAD-React-AspNetCore"&gt;this GitHub project&lt;/a&gt; I am showing you how to authenticate against Azure AD using React and ASP.NET core. I will improve the current code and provide more samples on that repository. &lt;/p&gt;

&lt;p&gt;Happy coding.&lt;/p&gt;

</description>
      <category>azure</category>
      <category>react</category>
      <category>msal</category>
    </item>
  </channel>
</rss>
