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
Comments
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. |
@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? |
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. |
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: 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:
|
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... |
@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. |
@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... |
I'm sorry your avatar looks like the one on the comment before yours, I edited. |
Something like the following? [Authorize("myPolicy")]
@page "customers" |
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! |
@robertmclaws The HttpClient uses JS interop to call into the fetch API (BrowserHttpMessageHandler). We don't introduce a new cookie container. |
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? |
@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? |
@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? |
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: The first So then you can modify MainLayout.cshtml to have login controls, like this: The beauty of this system is that everything responds in real-time, the 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 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 :). |
It would be nice to have an @authorize
@authorize "Operator", "Partner" |
@robertmclaws is this sample in github? |
@xrkolovos Yep, it should be in there. https://github.com/CloudNimble/BlazorEssentials/tree/master/src/CloudNimble.BlazorEssentials.TestApp |
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]. |
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? |
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! |
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. |
Closing as a dupe with #4048 |
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.
The text was updated successfully, but these errors were encountered: