How to share MSALSessionCache with 2 web applications? - asp.net-mvc-4

I have developed 2 web applications.
I have used Azure Active Directory v2.0 for user identity.
These two applications are hosted as separate web apps in Azure.
using Application Gateway, I am redirecting the specific request to web apps.
If User is requesting for any of the web apps, then first it is redirected to azure tenant endpoint for authentication.
After successful login, it will be redirected to the main web app and I have followed this below code in OnAuthorizationCodeReceived method.
TokenCache userTokenCache = new MSALSessionCache(signedInUserID, notification.OwinContext.Environment["System.Web.HttpContextBase"] as HttpContextBase).GetMsalCacheInstance();
ConfidentialClientApplication cca = new ConfidentialClientApplication(ApplicationId, Authority, RedirectUri, new ClientCredential(ApplicationKey), userTokenCache, null);
Now When User is navigating from one web app to the other web app. I am using below code to get token from the cache.
TokenCache userTokenCache = new MSALSessionCache(signedInUserID, new HttpContextWrapper(HttpContext.Current)).GetMsalCacheInstance();
ConfidentialClientApplication cca = new ConfidentialClientApplication(Startup.ApplicationId, Startup.Authority, Startup.RedirectUri, new ClientCredential(Startup.ApplicationKey), userTokenCache, null);
var user = cca.Users.FirstOrDefault();
When I am implementing this code and try to get token in the second web app.then it will give me null in the user variable and it throws an error.
What Should I Do?
Note: If some user logged in one web apps, then it does not require to log in another web app. Sessions and cookies are shared between all web apps.

The customization of Token cache serialization to share the SSO state between ADAL.NET 3.x, ADAL.NET 4.x and MSAL.NET is explained part of the following sample: active-directory-dotnet-v1-to-v2
This solution shows how to customize token cache serialization in a .NET desktop application so that it shares the Single Sign On (SSO) state between: ADAL.NET V3.x applications, ADAL.NET V4.x applications, MSAL.NET 2.x applications

Related

consuming .net core api by xamarin form application

I'm currently working on a Xamarin form that consumes data from the.net core API.
For API side, I use Abp framework.
By using this reference, I can consume data from API.
But in this example, the user needs to login using an administrator credential.
What I need to do is, I just need to consume data from API without login.
Is it correct way if I add [AllowAnonymous] attribute over the API method that I need to access ?
This is the example they show,
var accessToken = await _loginService.AuthenticateAsync();
var httpClient = GetHttpClient(accessToken);
Is there any example like just using clientId/secrets and without using accessToken?
What I need to do is, I just need to consume data from API without login.
This refers to Server-to-Server authentication; backend making request to an other backend without user interaction.
The authentication flow you are looking for, is named Client Credentials Flow.
It boils down to:
Add your api (abp app) as an api resource and api scope at authentication server.
Add your ui app (xamarin app) as a client at authentication server.
Declare a client secret for your xamarin app at authentication server.
Make an access_token request from xamarin app to authentication server with the api scope and client secret that you have already created above.
Its implementation can be varied on authentication server provider (namely your _loginService). It can be Identityserver4, Microsoft, Google etc etc.
If you are using ABP application backend (as authentication server), it handles most of the automated stuff in the background. You can check abp synchronous communication between microservices docs that has explanation about how client credentials is used between microservices.

How to secure Web API with Auth0 without exposing ClientId & ClientSecret to client?

I am creating a new .Net Core Web API that is consumed by a new React client-side app. Both the client-side app and the Web API are on different hosts and protected by Auth0. I set up both the client-side app and the Web API in Auth0, and then I created a machine-to-machine app in Auth0 to be able to communicate with the Web API silently (without a user interface). The security flow works like this:
User tries to access client-side app.
User is re-directed to Auth0 to provide credentials.
Auth0 authenticates the credentials and returns user info (including user ID + access token) to client-side app.
Client-side app stores user info in local storage for future use until it expires.
Any calls to 3rd party APIs are routed through my own Web API, so 3rd party API keys are sitting in a safe place on the server, not on the client-side.
User accesses a page that requires a call to my Web API but we don't have an access token for my Web API yet.
Client-side app reads the ClientId & ClientSecret (hard-coded values) from .env file and makes a POST request to Auth0 to fetch an access token for my Web API (this is Auth0's recommended way of getting the access token for the Web API silently except they don't specify where the ClientId & ClientSecret would be stored).
Auth0 returns an access token for my Web API.
Client-side app stores the Web API access token in local storage for future use until it expires.
Client-side app invokes my Web API with newly acquired access token as the bearer token in the header.
Web API receives the access token, authenticates with Auth0 and fulfills the request.
All of the above is working for me but I am concerned about storing the Auth0 ClientSecret of my Web API in the client-side app. Although it is not visible on the screen or in a cookie anywhere, any capable user would be able to get at it by inspecting the network traffic.
Many people on the Internet seem to be fine with storing 3rd party API keys in .env files while others advise routing 3rd party API access through your own Web API ... and I am doing the latter. But I still need the Auth0 ClientSecret to get to my own Web API and I cannot figure out a better place way to get to it without storing them somewhere on the client-side.
One last-ditch solution I can think of is to not protect my Web API through Auth0 and instead every call from the client-side app to my Web API should include something unique (like the user ID from Auth0) that can be validated by the Web API. Thankfully, the user ID from Auth0 will be stored in our database when the user is set up initially, so this is actually possible.
Does Auth0 have any other way for me to get the Web API access token without providing the ClientSecret given that I already have the client-side app's access token? I am curious to know how others have secured both their client-side app and their Web API through Auth0.
You are correct, you should not include the client secret in your client-side app. Do not use a client credentials flow, instead use a auth code + PKCE or implicit flow.
With that being said, Auth0 should handle most of that if you are using a library or SDK.
You have two options for getting the token:
When requesting the initial access token and ID token add the Web API as an audience and request the related scopes.
Make a silent request using the checkSession function for Auth0.js or getTokenSilently for auth0-spa-js
Take a look at this:
https://auth0.com/docs/architecture-scenarios/spa-api/part-3

Web app ClaimsIdentity in Webapi

I've created a mvc web application that uses openid to authenticate with Azure Ad and get the claims along with the token. I'm interfacing with Web Api to do the business transactions. The web Api is configured to oauth bearer tokens.
I've created separate oauth clients in Azure Ad for the Web App and Web Api. I'm able to get a token for Web Api from the Mvc Controller using AuthenticationContext to send to request to Web Api. I need to know how I can send the current User Claims as well to the Web Api. The claims in the Web Api are not having the claims of the User from the Web App.
Let me provide a bit more context here. I've created a MVC Web Application and a Web Api layer. The MVC Web App is configured to use OpenID authentication using Azure AD and I've configured the Web Api layer to authorize using OAuth Bearer tokens. The actions in the Web Api layer will be called through ajax requests and the bearer token will be added to the header of each Ajax requests. When the User is authenticated in the Web App, additional claims are added to the User on top of the claims from Azure Ad. I'm able to create a token for the Web Api layer using AuthenticationContext.AcquireToken, but the token for Web Api does not have the User info from the Web App.
I'm taking a wild stab in the dark here, based on what I think is happening.
Claims are attached the user, so theoretically, any claim you add in one place should be available in the other, as long as both applications share the same user datastore. However, claims are loaded at the point of authentication and not dynamically updated. As a result, if you're already logged in to the web application and you add a claim with your Web Api, that claim will not be available on the web application side until the user is re-authenticated.

Implementing Azure Active Directory Authentication in a client OWIN Web Application

Hello I have read and implemented these Vittorio Bertocci tutorials:
"Secure ASP.NET Web API with Windows Azure AD and Microsoft OWIN Components"
"Protecting a Self-Hosted API with Microsoft.Owin.Security.ActiveDirectory"
However unlike the tutorials my web application is comprised of the following OWIN components: NancyFx & ASP.NET Web API (following the architecture pattern set forth here)As I attempt to implement AAD authentication (as Mr. Bertocci does in his tutorials) into my NancyFx module (to authenticate a user who hits a route requiring authentication):
I get the following error
Additional information: Loading an assembly required for interactive user authentication failed. Make sure assembly 'Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' exists.
clearly the AAD dialog that pops up asking a user to login has a dependency on WindowsForms and shouldn't be invoked from a web application.
What AAD credential prompt should I be using instead?
How to I implement AAD auth in a web app client?
My understanding of the scenario you are trying to implement is that you have the following actors:
Browser -> Web Application -> Web API
Where the browser is authenticates a user to the Web Application and then the Web Application attempts to obtain a token that will allow it to access a resource at the Web API on behalf of the user.
That being the case, your Web Application will need to redirect the browser to the AAD OAuth 2.0 authorization endpoint. There the user will enter their credentials and be redirected back to the Web Application with an authorization code. You can then use that authorization code to obtain a token via the Active Directory Authentication Library (ADAL). Specifically you will use the AuthenticationContext.AcquireTokenByAuthorizationCode method. The following blog entry by Vittorio gives more detail on the code you will need to implement in the Web Application in order to obtain the token. It is not an OWIN specific implementation, but should be easy to translate into your NancyFx app.
Using ADAL’s AcquireTokenByAuthorizationCode to Call a Web API From a Web App
You should not have to change your ASP.NET Web API that you implemented per "Protecting a Self-Hosted API with Microsoft.Owin.Security.ActiveDirectory"
The version of AuthenticationContext.AcquireToken that is used in the client app example in the Protecting a Hosted API... blog entry is intended for a different scenario where no browser is involved. Instead the user is interacting with a desktop application that is then calling a Web API on the users behalf. In that case, the AcquireToken call must show a browser based dialog in order to allow the user to sign in and obtain an appropriate token.

Automatic AD Auth

I'm developing an ASP .NET application, nothing fancy just another LOB App.
Our company's authentication model is based on a typical AD setup. Nearly all of our applications are written on Sharepoint so it is a requirement that the authentication is "automatic", meaning that once you are logged on your machine you have access to all your applications without writing another user or pwd.
For some reasons i cannot develop this app over Sharepoint.. so, the question is How Can I Automatically Authenticate AD users on my web App?
thanks in advance
You need to enable Windows Authentication on the web app. This article has enough details to get you started.
PrincipalContext Authenticator = new PrincipalContext(ContextType.Domain, 'yourDomainName');
AuthenticationFailed = !Authenticator.ValidateCredentials(Username, Password);
If AuthenticationFailed; you can redirect to login page..