Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blazor Security/Authorization #5472

Closed
grahamehorner opened this issue Feb 7, 2018 · 23 comments
Closed

Blazor Security/Authorization #5472

grahamehorner opened this issue Feb 7, 2018 · 23 comments
Labels
area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one ✔️ Resolution: Duplicate Resolved as a duplicate of another issue

Comments

@grahamehorner
Copy link
Contributor

Please consider a claim/policy based client-side authorisation framework where user claims/cookies can be evaluated with in the blazor runtime, to enable/disable application functionality/ui features based on user claims/policy evaluation.

@richbryant
Copy link

I'm sorry, but doesn't this strike anyone else as inherently insecure and unsafe? The client runs in the user's browser. They can change anything. Put authorisation/authentication in the data source, not on the client.

It might be nice to have for convenience but it would only encourage developers to rely on it when they absolutely shouldn't.

And we can already do this. System.Net.HttpClient can handle the a bearer authentication token without issue.

@grahamehorner
Copy link
Contributor Author

grahamehorner commented Jun 7, 2018

@richbryant I think your misunderstanding this topic; a claims based policy systems that has nothing to do with authentication; claims would be issued by a claims server/service and digitally secured so that these can't be modified; complied blazor code running in the browser would determine if a claims token has been issued that fulfils the policy required to perform an action. claims tokens are ready in use by any number of browser application in the form of JWT/access token and stored in cookies for Facebook, Twitter, etc.

I'm not saying remove the security on the server/service and place this on the client; I feel that given Blazor is a SPA style application that some parts of the SPA client may need to evaluate a users claims based on the token supplied to see if that user can/should be allowed to perform some action and/or see parts of the UI

however I would defer to @blowdart the security expert for comment if he thinks this would weaken/create security issues?

@blowdart
Copy link
Contributor

blowdart commented Jun 7, 2018

I'm afraid I'm going to lean towards nope, unless the token itself is kept on the client side, and meant for a client app ID (for example using Facebook's javascript SDK so a server is never involved). At which point generally everyone has SDKs for their own tokens, or you parse and validate the JWT yourself. Server side, well, if you start asking a server "Show/Hide X" and you can just use fiddler or dev tools to influence the result then obviously that's not something we should depend on.

Now I take your point that no, this isn't really security, it's UI, but would all our users be that informed? Would they suddenly see claims and think "Hey this is security". I think that from an API design perspective this one will confuse people and ultimately lead to sadness when the confusion happens.

But as Blazor's a preview we haven't undergone any formal security reviews as yet.

@Andrzej-W
Copy link

Let's assume we have a Customers module with a few fields: name, address, credit limit. To edit credit limit field, users have to have special claims. Without special claims credit limit field is displayed as read-only. This is good user experience. Of course malicious user can try to use other tools (for example Postman) to post some data to the server. If you want to create secure application you have to check the same business rules on the server. The same is true in every application type. Here you can read about ASP.NET Core:
https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/validation?view=aspnetcore-2.1#how-validation-works

In Angular you can use route guards (https://angular.io/guide/router#guards) to hide some parts of the application from unauthorized users, for example you can disable link to example.com/customers. Probably you also have WebAPI endpoint: example.com/api/customers. Of course to make application secure you have to authorize all WebAPI requests.

In summary:

  • you can implement business rules on the client to create good user experience
  • you have to implement the same business rules on the server to create secure application

@chassq
Copy link
Contributor

chassq commented Jun 7, 2018

There have been ways for years for a dev to place "claims" browser side (see Forms Auth Cookies). These cookies could carry auth info as well as roles/claims. Now these cookies were posted to the server and read server-side but a cookie was exposed to the client with that info (of course encrypted). I guess just saying there is precedence for storing roles/claims browser-side.

Maybe a special type of "read-only" cookie/token with a signature that needs to be validated server-side prior to accessing? IDK I could see this implemented various ways to give the client-side a way to make presentation based decisions? Bottom-line is that whatever checks for allowed features, for example, are placed on the browser-side should be enforced server-side. If there were the shared claims/policy mechanism it would be nice to share it across browser/server side for consistent enforcement.... Sorry for the rambling...

@RemiBou
Copy link
Contributor

RemiBou commented Jun 7, 2018

@Andrzej-W I don't agree with "If you want to create secure application you have to check the same business rules on the serve", no you always have to do it on server side, if you want to improve UX you can do it on client side as well but it's not mandatory (just like form validation).

What you need is just an endpoint on your server that send the claims available serialized for the authenticated user, so the cookie reading will only happen on server side.

@chassq
Copy link
Contributor

chassq commented Jun 7, 2018

@RemiBou don't think I said what was in your quotes... I do agree all checks should be server side.. My point is only it would be nice to share the same claim policy framework to the point it makes passing and checking the claims seamless and consistent between client and server...

@RemiBou
Copy link
Contributor

RemiBou commented Jun 8, 2018

I'm sorry your avatar looks like the one on the comment before yours, I edited.

@vertonghenb
Copy link
Contributor

vertonghenb commented Jun 18, 2018

Something like the following?

[Authorize("myPolicy")]
@page "customers"

@robertmclaws
Copy link

So I'm working on an authentication system that will be able to handle the various providers. It works completely client-side, uses ClaimsPrincipal, and doesn't expose any secret keys or anything like that.

Now, my question is this: I'm working on the token refresh mechanism, and I need to know: does the HttpClient instance reuses the browser's CookieContainer when it makes requests? I'm hoping it does, because I need to be able to make a GET request to a location I previously redirected to, and I'll need the previous cookie from the Redirect to be available.

Thanks!

@danroth27
Copy link
Member

@robertmclaws The HttpClient uses JS interop to call into the fetch API (BrowserHttpMessageHandler). We don't introduce a new cookie container.

@shadowmint
Copy link

At a high level, how does this ticket relate to server-side rendered blazor components?

Isn't that going to require a full authorisation framework to invoke server side code, because it will not happen via the fetch api?

@grahamehorner
Copy link
Contributor Author

@shadowmint I don't follow? AFAIA the cookie that is supplied to the server-side rendered blazor components would be the claims cookie that was given to the user at sign-in just like and use the standard roles/claims a standard .net core web application?

@shadowmint
Copy link

@grahamehorner yes, but normally an authorisation policy would be applied, eg. in MVC, at the controller; I don't understand where this would be done in this case?

Or would the component be required to authenticate the user request manually based on the claims? ...in which case, doesn't the client-only blazor need to know about claims?

Perhaps I haven't understood how this is supposed to work; are there any examples of applying an authentication policy using server-side blazor?

@robertmclaws
Copy link

So this is going to be interesting to work out.

I'm working on a framework that allows client-side Blazor to authenticate with 3rd party systems like Auth0 through regular C#, not importing JS libraries. It's wired up in Startup.cs, and should feel very familiar to OWIN and ASP.NET Core developers.

I'm working on a blog post about this, but here's the gist of it:
image

The first Action returns a redirect URL so the user can be redirected to the auth page. The second Func processes the return payload into a ClaimsPrincipal. Gluing it all together is a Blazor page that pulls the payload out of the URL and marshalls it back to AppStateBase.
image

So then you can modify MainLayout.cshtml to have login controls, like this:
image

The beauty of this system is that everything responds in real-time, the AppStateBase tracks authentication, but you can easily inherit from that to track other state data that is not specific to your ViewModels.

I'm working now to try to figure out the best way to handle refreshing your tokens, and if it's possible to have an @authorize declaration (or an equivalent) and what happens when you're not authorized. If you have any ideas, please post here, or in the related BlazorEssentials issue.

So that was long-winded, but the interesting part will be how well all this works in Server-Side Blazor. I haven't had a chance to set that up yet and see if what I have now will need to be changed.

Feedback welcome :).

@danroth27 danroth27 changed the title Blazor Security/Authorisation Blazor Security/Authorization Oct 15, 2018
@marinasundstrom
Copy link

It would be nice to have an @authorize directive which would turn into an [Authorize] attribute on the Component class. Then making it possible to hook into the authorization logic into the Router like a middleware.

@authorize
@authorize "Operator", "Partner"

@xrkolovos
Copy link

@robertmclaws is this sample in github?

@robertmclaws
Copy link

@xrkolovos Yep, it should be in there. https://github.com/CloudNimble/BlazorEssentials/tree/master/src/CloudNimble.BlazorEssentials.TestApp

@omidSarwary
Copy link

Authorization is a real headache especially for beginners like me. It would be really nice if there was a @authorize that would be the same as [authorize].

@aspnet-hello aspnet-hello transferred this issue from dotnet/blazor Dec 17, 2018
@aspnet-hello aspnet-hello added this to the Backlog milestone Dec 17, 2018
@aspnet-hello aspnet-hello added area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates enhancement This issue represents an ask for new feature or an enhancement to an existing one area-blazor Includes: Blazor, Razor Components labels Dec 17, 2018
@grahamehorner
Copy link
Contributor Author

I have been looking into the authorisation and have a working example for server-side blazor and client-side blazor; the sample uses the users claims token returned from the approved/configured oauth service(s) (Microsoft, Facebook, Twitter, etc) this token is held in a client-side cookie and is signed to prevent unauthorised modification, when blazor is required to perform an authorisation check, the cookie is verified by blazor asking the oauth provider to confirm the token is validate and active (not expired) if all is well the token is evaluate decoded and evaluated by the authorisation policy to determine a granted/denied status accordingly.

I will be doing some tied-up of the code and then writing a blog post about this, I welcome feedback should anyone have any ideas or thoughts around this?

@yberstad
Copy link

Hi @grahamehorner or @robertmclaws, have you gotten time to publish a blog post regarding this issue? It would have been much appreciated! 😃 Thanks in advance!

@SteveSandersonMS
Copy link
Member

Moved to preview 5 backlog not because I think we really have time to do it then, but to force us to re-triage this to an actual preview release.

@SteveSandersonMS SteveSandersonMS added this to To do in Blazor via automation Apr 15, 2019
@SteveSandersonMS SteveSandersonMS removed this from To do in Blazor Apr 15, 2019
@mkArtakMSFT
Copy link
Member

Closing as a dupe with #4048

@mkArtakMSFT mkArtakMSFT added the ✔️ Resolution: Duplicate Resolved as a duplicate of another issue label Apr 15, 2019
@mkArtakMSFT mkArtakMSFT removed area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates labels May 9, 2019
@dotnet dotnet locked as resolved and limited conversation to collaborators Dec 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one ✔️ Resolution: Duplicate Resolved as a duplicate of another issue
Projects
None yet
Development

No branches or pull requests