windows Authorization in ReactJS and .NET Core API - reactjs

We have a new application which is having ReactJS as front end and back end is .NET Core API.
A requirement is to authorize the windows logon user with respect to Active Directory.
The .NET Core API will be doing the Authorization part.
We have used the following code in .NET Core API but it is returning the ID under which the App-Pool of .NET Core API is running. We tried setting the API on Windows Authentication enabled but it did not work as well.
dynamic userIdentity = WindowsIdentity.GetCurrent();
dynamic userPrincipal = new WindowsPrincipal(userIdentity);
string Admin = _configuration["AppUserRoles:Admin"];
result = userPrincipal.IsInRole(Admin);
I have changed the code to the following:
dynamic userIdentity = WindowsIdentity("UserID");
dynamic userPrincipal = new WindowsPrincipal(userIdentity);
string Admin = _configuration["AppUserRoles:Admin"];
result = userPrincipal.IsInRole(Admin);
We need to pass the the UserID from ReactJS to the API Layer.
In ReactJS I have tried the following:
var path = require('path');
var userName = process.env['USERPROFILE'].split(path.sep)[2];
var loginId = path.join("domainName",userName);
But this is not working in ReactJS.
Is there a way we can fetch the Windows Logon ID in React JS and pass it to the API layer for authorization?

We were able to get this done by the following approach:
under IIS we hosted the website as follows:
Added a website ReactJSWeb.
i. Added .NETCore virtual directory under the ReactJS website.
Both Main website and Virtual directory had Authentication set as Windows Authentication Enabled.
In .NET Core API - authentication module we added a Attribute [Authorize] on the class and added the following code in the method:
using Microsoft.AspNetCore.Authorization;
dynamic userIdentity = WindowsIdentity(**User.Identity.Name**);
dynamic userPrincipal = new WindowsPrincipal(userIdentity);
string Admin = _configuration["AppUserRoles:Admin"];
result = userPrincipal.IsInRole(Admin);
This worked and we are now able to do the Authorization properly based on the Active Directory security group the user is part of.

Is it possible to share what you did to have client authenticated following that approach? I'm getting crazy with a similar scenario like yours...
I very appreciate that.

Related

Using Saml with Azure AD using Blazer Web assembly

I'm trying to use .NET core Blazer webAssembly client UI from main() and authenticate with Azure AD using SAML with the following code, but getting error. can't figure this out one issue below. any clue is appreciated
there was an error trying to log you in: 'Cannot read property 'redirectUri' of undefined'
OIDC works fine.
Below is my code called from Main in Program.cs
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddHttpClient("BlazorWASMAuthApp.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
.CreateClient("BlazorWASMAuthApp.ServerAPI"));
builder.Services.AddApiAuthorization(); builder.Services.AddAuthenticationCore(); builder.Services.AddAuthorizationCore();
builder.Services.AddAuthentication().AddSaml2(options =>
{
// builder.Configuration.Bind("AzureAd", options.SPOptions.AuthenticateRequestSigningBehavior);
//APP Registration keys Will be moved to Json in subsequent story
options.SPOptions.EntityId = new EntityId("https://localhost:5001/saml2");
//options.SPOptions..Add("https://localhost:5001/saml2/API.Access");
options.IdentityProviders.Add(
new IdentityProvider(
new EntityId("https://sts.windows.net/{Clientid}/"), options.SPOptions)
{
//SingleSignOnServiceUrl = signinURI,
MetadataLocation = ...federationdataxml?clientid={clientid}"
});
;
})
.AddCookie();
The most common errors as per ms docs are caused by incorrect configuration
Depending on the requirements of the scenario, a missing or incorrect
Authority, Instance, Tenant ID, Tenant domain, Client ID, or Redirect
URI prevents an app from authenticating clients.
Running the app at a different port than is configured in the Redirect
URI of the Identity Provider's app registration.
Please check if the cause is missing return url parameter in configuration in your code provided:
options.SPOptions.ReturnUrl = new Uri("https://localhost:5001/authentication/azurecallback"); which comes after
options.SPOptions.EntityId = new EntityId("https://localhost:5001/saml2");
else check Portal side configurations.
While registering API , redirect uri is set as web and its field is left empty and api is exposed from Expose api .
But When registering client app , redirect uri must be set ,hope you have done so.
client app > go active directory b2c >give name >select supported account>redirect uri >select SPA-give redirect ur like https://localhost:5001/authentication/login-callback
(format of uri : https://localhost:{PORT}/authentication/login-callback.)
This 'authentication/login-callback' must be present in your code configuration too.
From reference
NOTE: The default port for an app running on Kestrel is 5001. If the
app is run on a different Kestrel port, use the app's port. For IIS
Express, the randomly generated port for the app can be found in the
Server app's properties in the Debug panel. Since the app doesn't
exist at this point and the IIS Express port isn't known, return to
this step after the app is created and update the redirect URI. A
remark appears in the Create the app section to remind IIS Express
users to update the redirect URI.
So Check the port running and update the redirect uri if not done.
References:
Reference 1
Reference 2
Cors

Teams Tab for dynamic SharePoint page / authentication problem

Heyo,
I am trying to build a multi tenant Teams App with personal tabs. The goal is: the user is authenticated (silently like explained in the Microsoft example, a static html page with the JavaScript code is hosted in an Azure Storage), then my custom web service is called and answers with a SharePoint-Online URL which contains an SPFX Webpart. Then the user is redirected to that page. When the user is not registered he gets an error page instead. The problem here is, that I am not able to redirect the user to that SharePoint page. The SharePoint page won't open in the iframe of the Teams tab because the tab's domain is the domain where my static web page is hosted. So my first question is how can I achieve this? (I do not know the SharePoint URL at build time, i do not know if the user has a page at all. This is determined in the custom web service at runtime)
A different approach would be to build a custom JavaScript application (in react, like my SPFX webpart), host it on my static web page and communicate with the SharePoint from there. To test my idea I added permissions for SharePoint in my Azure AD application, wrote a simple call to the SharePoint with the obtained token.
var req = new XMLHttpRequest();
req.open("GET", "https://[tenant].sharepoint.com/sites/[sitecollection]/_api/web/lists", false);
req.setRequestHeader("Authorization", "Bearer " + idToken);
req.setRequestHeader("Accept", "application/json;odata=verbose");
req.onreadystatechange = function () {
if (req.readyState == 4 && req.status == 200) {
var result = JSON.parse(req.responseText);
}
};
req.send();
The problem is my SharePoint is answering with 401 and "Exception of type 'Microsoft.IdentityModel.Tokens.AudienceUriValidationFailedException' was thrown" error in the response.
Is this some sort of CORS problem or do I need a different type of token for SharePoint? Or do I have to use a complete different JavaScript library to authenticate vs SharePoint.

app.UseWindowsAzureActiveDirectoryBearerAuthentication stopped working after upgrade from ADAL to MSAL

I'm running some tests with MSAL but unfortunately it's not working as expected.
I had all configured for an ASP.NET MVC (.net 4.6) + Angular 1.6 SPA application with ADAL and ADAL Angular. All worked just fine but then I decided to try MSAL.
My configured provider's OnValidateIdentity handler in Startup.Auth.cs was being hit correctly with ADAL and I could add additional claims:
Provider = new OAuthBearerAuthenticationProvider
{
OnValidateIdentity = async context =>
{
Now that I changed to MSAL for Angular JS, I'm getting the ID Token and the Access Token but my OnValidateIdentity handler is not being hit anymore.
Is using app.UseWindowsAzureActiveDirectoryBearerAuthentication still valid when using MSAL?
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
.
.
.
MSAL is meant to be used with converged/v2.0 application registrations, while ADAL is usually meant to be used with v1.0 App registrations,
You should create a new application using the new portal in portal.azure.com if you're trying to migrate to the v2 endpoint. In addition to that these docs go over creating a v2.0 App Registration : https://learn.microsoft.com/en-us/graph/auth-register-app-v2
Please refer to this resource for more information on migrating from v1 to the v2 endpoint. https://azure.microsoft.com/en-gb/resources/samples/active-directory-dotnet-v1-to-v2/
In regards to the specifics of using app.UseWindowsAzureActiveDirectoryBearerAuthentication
// NOTE: The usual
WindowsAzureActiveDirectoryBearerAuthenticaitonMiddleware uses a
// metadata endpoint which is not supported by the v2.0 endpoint. Instead, this
// OpenIdConenctCachingSecurityTokenProvider can be used to fetch & use the OpenIdConnect
// metadata document.
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
{
AccessTokenFormat = new JwtFormat(tvps, new OpenIdConnectCachingSecurityTokenProvider("https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration")),
});
This is referenced from the startup.cs : https://github.com/AzureADQuickStarts/AppModelv2-NativeClient-DotNet/blob/a69a4cb41e821f0ea8dddc937ea401a03e2f49fe/TodoListService/App_Start/Startup.Auth.cs
Some more good reading that does a bit of a comparison between the v1/v2 sample apps can be found here : https://simonlamb.codes/2017/02/27/net332-introduction-to-authentication-on-azure-active-directory/

Get SharePoint Office 365 data using Client Id

I am accessing SharePoint online list data using the following code but i get the following error.
The remote server returned an error: (403) Forbidden.
The web forms application is running in Azure and uses Azure authentication. I would like to use the same credentials for authentication
string siteUrl = "[url]";
string aadAppId = "[appid]";
string clientSecret = "[redacted]";
OfficeDevPnP.Core.AuthenticationManager authManager = new OfficeDevPnP.Core.AuthenticationManager();
ClientContext context = authManager.GetAzureADNativeApplicationAuthenticatedContext(siteUrl, aadAppId, appurl, null, AzureEnvironment.Production);
if (context != null)
{
Web web = context.Web;
context.Load(web);
context.ExecuteQuery();
}
I do not want to access the SharePoint using the user credentials.
I have enabled AAD Azure authentication on the web app. The web app authenticates with Azure credentials.
On the CORS setting i have also set the Domain Url to "https://domainname.sharepoint.com";
In the manage permissions section of AAD app I have given the app Permission to read and write sharepoint list and web data.
You example is attempting to retrieve a token as a native client application, which is an app that cannot keep a secret and cannot authenticate by itself. (That's why you'll notice you never use clientSecret.)
If you want to use OfficePnP, you can try one of the AuthenticationManager.GetAzureADAppOnlyAuthenticatedContext methods to authenticate in the app-only context. Note that they all require a certificate for authentication, rather than a secret.

C# .NetCore Okta Search for Users

I am trying to figure out how to search for users in Okta using the SDK and .net core in C#. outside of .net core I am able to do this using Okta.Core but that is not supported in .NET Core. I can't find any documentation for doing this stuff in .NetCore using the SDK.
I can get the OktaClient connected no problem with my API token but after that I am lost now.
Anyone have an example of doing this in Core or can point me in the right direction to get documentation from Okta?
Looking thought the Okta documentation I found the below code, where the client is the Okta client. Hopefully this helps:
Getting A User
// have some user's ID, or login
var someUserId = "<Some User ID String or Login>";
// get the user with the ID or login
var vader = await client.User.GetUserAsync(someUserId);

Resources