What replaces Session variables in Blazor Web Assembly? - variables

So in a .Net web forms project, I would simply use session variables to be able to set and get them across different pages. What is the proper way to do that in Blazor Web Assembly (with core hosting) ? i.e a user logs in, things like their ID, email, first name, etc are stored and then needed to be accessed in other pages.

in a .Net web forms project, I would simply use session variables
Your Wasm app is a regular C# app so you can use most normal storage mechanisms. I would stay away from static but you can use your own SessionStateService. Just a bunch of properties. Inject it as a singleton or use it as a Cascading value.
But ye old Session data was stored server-side. That means there is a subtle difference with Blazor wasm solutions as soon as the user opens a second tab with the same app. Every tab runs its own instance of the app so your data will be local to that tab. There is no sharing.
When you do want to share between tabs, use JavaScripts localstorage (persisted) or create an endpoint on your API server (persistance is up to you).
things like their ID, email, first name
Those should preferably be stored as claims in a JWT. Especially when you want to base some (serverside) authorization or logic on those values.

You use a Scoped DI service to maintain state, and inject it into any components that need to use or add/update the information.
See Ms Docs - https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/dependency-injection?view=aspnetcore-6.0

Related

How to set up a global variable accessible across all pages of asp.net core razor app

I have developed a simple asp.net core razor app with Windows authentication to be used in our intranet, hosted on prem.
In order to distinguish a normal user from admin user (the the user who is allowed CRUD), I check for the logged in user principal against the AD group member. I have a static helper function which does that.
At the moment I use a public flag on each page by calling that helper function, to be used in the razor page to show/hide the edit/delete buttons.
Is it possible to run this function only once (say, in the index page) and set a global flag to be used across all pages?
It sounds like you need a cache server to store the data fetched in the static helper function.
Of course, from your current design, the least code change is to use redis cache. Then inject the middleware of redis cache into Controller or Razor Page.
If global variables are used in .net core, an object can be set when the program is initialized to store userid and read-write permission. But when running the static helper function, the data may not be dynamic and real-time. So I think the design might be flawed.
But I think you should use Role-Based authorization in your project. Because you also use Azure AAD. So I recommend you to read the article below.
IMPLEMENT APP ROLES AUTHORIZATION WITH AZURE AD AND ASP.NET CORE (Microsoft MVP's Blog)

Unifying auth between a Blazor Server UI and an (effectively external) API

I've a situation where I'm creating a Blazor Server front end for an API, and that API may also be used directly by some other systems. Essentially some smaller customers might use the UI, others (perhaps larger with their own dev team) build their own UI and use the API. We control both sets of code (for the Blazor and the API).
Auth in the api is done (at the moment) by sending a userid and a password and getting a JWT Bearer token that is added to all subsequent requests.
Auth on the BS app is (at the moment) done using Azure AD B2C; the templating in VS makes it an easy setup and then no really specialist knowledge is needed to maintain and add new users
There isn't any special link between the two for now; both are in dev and the BS app just has a hard coded u/p for a single dev user inthe API side. At some point that needs to change so the API serves more than one customer via the UI
It seems I have a couple of routes I could go down:
Make the BS app use the API for auth; in my mind this looks like setting up something similar to what you get when you make a new BS app with "Individual Accounts" auth, except it doesn't use EF on a database with tables for tracking identity - it would probably use a custom store and usermanager that asks the API for auth instead of some DB, and then some (hopefully simple) mechanism of getting the returned token from the API into every httpclient that ends up being used to poke the API (they're abstracted away into proxies built by NSwag but it's easy enough to address because NSwag code calls a particular overridable method to setup the headers.. finding a way to have the httpclientfactory do it might be even easier)
Make the BS app and the API use AD B2C for auth. As a workflow I genuinely have no idea how that's done or what it looks like.
Of the two I'd prefer the latter because it hands off some additional responsibility to AD, such as maybe in future we want to have UI customers also do 2FA but I'm not really sure how to go about researching it. How do we go about sharing auth between the two systems?
I'm not looking for code; some rudimentary instructions on how to share the authenticated identity between the BS app and the API is really what I need. If it's not an achievable goal, what alternative mechanism for Blazor Server do I have that would allow easy sharing of a retrieved bearer across a everything the user might do in a "session" (I don't mind if they lose SignalR connection and have to log in again)?
If either of the approaches above look like I'm just making life hard work, and it should be done another way, an outline of the steps required to make it go would be ideal

Blazor server side role or claim based authorization when using windows login

I am new to working with Blazor and Authorization. Background is desktop apps in Vb.Net, so I have been reading everything I can on it, but it still is very confusing when I only want a specific subset of the options out there.
I have a very simple intranet Razor Server based app that is getting the windows user name correctly with default authentication. (I use the name in calls to stored procedures for logging, so I know that is working correctly.)
What I need is to implement authorization (role based would be fine) based on information I have already in the database tied to the user name).
Where and how does one add roles to an existing authstatetask or other object instantiated by the default processes?
Everything I have seen deals with the EF version of Identity or wants to override the authorization task.
I have Simple DB calls being made in Dapper which will return an identifier from which I can set roles.
I just need pointers to the proper method and where in the app I should put it. I have just a single .razor page being loaded, Navbar is disabled.
You can either :
Implement Identity stores for Dapper following instruction in this blog : ASP.NET CORE IDENTITY WITHOUT ENTITY FRAMEWORK
Use Policy-based authorization and create authorization handlers meeting your requirements

How to store user data in an MVC 5 app ? (with Windows auth)

For each user that connects to our MVC app, I need to store several custom properties (like its role, a list of sites he has access to, etc.). I know how to get the values for those properties (from our SQL database); what I need to know is the best practice to keep this "singleton/static/unique" object accessible across each view, and avoid to poll the DB each time.
Our authentication is Windows authentication.
Could be misinterpreting what you are asking, but ViewBag/ViewData are good tools for cross View/Controller data.

Trying to pass session variables from ASP to ASP.NET

We are doing a slow rollout of pages. basically the Login page is in ASP.NET and the old pages are in ASP Classic which are placed in an Iframe below the menu. They have two different servers that process the menu/pages. What is the best way to pass the users session from .NET to ASP Classic.
I had thought maybe it would be possible to modify the .NET login to send the user credentials to ASP page at the same time when they post their login. Is there any issues with this or is there a cleaner way of doing this?
Your ASP.NET code can read all the cookies in the domain, including the classic ASP session cookie, even though it doesn't use it. You can take advantage of that.
Handle signon on the ASP.NET side. The framework should create both an ASP and an ASP.NET session for you, passively, in addition to whatever other cookies are created by your authentication process.
Write ASP.NET code that reads the classic ASP session cookie and creates a JointSession record in the database indicating which user is currently signed on. Store both the ASP session cookie value and the current ASP.NET session ID (each in their own column), along with the user ID, roles, and whatever else needs to be shared between the two sites.
Write ASP code that reads its own session cookie and looks up any corresponding JointSession database record. If one is found, the ASP side of the site can infer that a user has signed on to ASP.NET, and can create its own matching session, initializing it from the fields in the JointSession record.
If you need to pass data between ASP and ASP.NET, add columns to JointSession, or perhaps use EAV schema. If it were me, I'd just add a VarChar column and throw some JSON in there.