I'm evaluating Umbraco for a project. I have installed it and am following a course about it on Pluralsight. Umbraco looks promising for what I want to do, but before I dive off the deep end I would like to know from more advanced users if what I want to do fits with Umbraco. As far as I can tell so far, it should do, but here is the project:
I currently have an MVC 5 + Web Api project that includes a page with some significant javascript and ajax where users spend some time entering information. Ajax updates occur along the way and then there is a full page form submit that interacts with the database and returns textual and graphical results. This is mostly done.
What I would like is to use Umbraco as a platform for its basic capabilities, but also add in the existing functionality. Interaction with the database will probably not be with PetaPoco, might be Ado.Net or (unlikely) EF.
Obviously extra effort is needed to adapt the existing code to the Umbraco framework - no problem - but before I get in too deep - does this project make sense for Umbraco?
Umbraco is a framework with plenty of hooks to allow you to tap in and put in your own functionality including pulling data from or into third party datasources. I would also recommend https://our.umbraco.org/projects/developer-tools/hybrid-framework/ on some good umbraco mvc practices
Umbraco uses MVC 4. Now MVC 5 says it runs side by side, etc...
However, if you plan on using the Umbraco nuget package to manage your project in visual studio (the best path imo), you will have an issue because Umbraco hard relies on MVC 4 and will not upgrade to 5, so you won't be able to install MVC 5 in your Umbraco Project, nuget will complain and throw errors and halt the install.
Now, Umbraco wise.. Umbraco's front end is done entirely automatically for you with automatic routes to content nodes based on content types and templates (Templates are MVC Razor Views).
When you have custom forms, and ajaxy things, you create a Controller that Inherits from SurfaceController which Umbraco automatically routes to a url like /umbraco/surface/mySurface/SomeAction.
It has a custom Html Helper Umbraco.BeingForm which basically just fills out that url for you to your surface controller.
SurfaceController is an MVC controller and not a web API controller.
Umbraco has WepApi controllers you can use, but there is something really important to understand about that.
Umbraco has a split user/member security model. Meaning you have Front End Members (the users using your site), and Back Office Users (The people with access to the umbraco interfaces that manage the site).
The umbraco backoffice runs entirely on WebApi and Angular JS...
The important thing to know there is that Umbraco Routes controllers derrived from UmbracoApiController to back office urls.. Which means they authenticate as Back Office Users.
A Surface controller on the other hand, authenticates as a Front End Member.
So if you need a controller that authenticates as a Front End member, you are forced to
Use a surface controller (which isn't web api)
or
Derrive directly from the web api classes (below umbraco) and route them yourself to a url that umbraco will authenticate as a member on.
For example, if you manually routed your controller to /MyXyzPlugin/SomeController/SomeAction then it should authenticate as a Front End Member.
The important thing to know there is that Umbraco Routes controllers derrived from UmbracoApiController to back office urls.. Which means they authenticate as Back Office Users.
Both of your corrections are correct, and it's good to know about the MVC change to allow upgrading.
However on your 2nd point I've discovered something I should add "which is probably a bug"
You can inherit from UmbracoApiController and use both MemberAuthorize and UmbracoAuthorize attributes.
However if you are logged in as a front end member and a back office user the front end member seems to trump the back office user.
E.g. the call to the back office authorized method will result in an access restricted error. You have to log out the front member, then it works and the call doesn't get access restricted.
Now, the only front end members that would go to the back office would be admins, so it's not a huge deal to tell them to log out of the front end, but it is an inconvenience.
However, this could be due to me using a custom authentication method. E.g. we have a Jasig Cas Repository we authenticate against. As such I leverage WIF (Windows Identity Foundation) and use federated authentication with Passive Redirect enabled.
To work with umbraco I customized the SessionAuthenticationModule and called it "UmbracoSessionAuthenticationModule, and I use reflection to make a call to "ShouldAuthenticateRequest" on the umbraco module, if true, I disable WIF and if False I let WIF go through (which logs in the front member).
ShouldAuthenticateRequest returns false on /umbraco/api as such WIF Runs, logs in the front member, even when requesting an action with UmbracoAuthorize on it.
That causes a conflict because you can't be logged in to two authenticated sessions simultaneously in the request pipeline (ASP.Net By Design).
Umbraco uses forms authentication, as such it definitely can't be logged in to both at the same time. Both cookies can be present, but it can only process one or the other, not both.
I think a better approach to this would have been to generate two routes for 1 controller. One on /umbraco/api and the other on /umbraco/backoffice/api and assume that /umbraco/api always authenticates as a member and /umbraco/backoffice always authenticates as a user. But allow all requests to be anonymous to these urls unless MemberAuthorize or UmbracoAuthorize is used at the controller level.
E.g. you use MemberAuthorize at the controller level and all /umbraco/backoffice/api/xyxController requests would require being logged in as a member, but user requests to /umbraco/backoffice/api/xyzController would be anonymous. Or vice versa, or both required to be logged in (e.g. tag it with both MemberAuthorize and UserAuthorize requiring both urls to be logged in as a member or a user respectively).
The way it is now I'm going to continue to separate my controllers. I'll use UmbracoApiController for front end members and UmbracoAuthorizedApiController for back office users and I'll use an IOC pattern so that I just use a repository so I don't have duplicate controller logic.
Evaluating Umbraco
I'm evaluating Umbraco for a project. I have installed it and am following a course about it on Pluralsight. Umbraco looks promising for what I want to do, but before I dive off the deep end I would like to know from more advanced users if what I want to do fits with Umbraco. As far as I can tell so far, it should do, but here is the project:
I currently have an MVC 5 + Web Api project that includes a page with some significant javascript and ajax where users spend some time entering information. Ajax updates occur along the way and then there is a full page form submit that interacts with the database and returns textual and graphical results. This is mostly done.
What I would like is to use Umbraco as a platform for its basic capabilities, but also add in the existing functionality. Interaction with the database will probably not be with PetaPoco, might be Ado.Net or (unlikely) EF.
Obviously extra effort is needed to adapt the existing code to the Umbraco framework - no problem - but before I get in too deep - does this project make sense for Umbraco?
James,
Watch http://stream.umbraco.org/video/11665495/custom-editors-and-super-speed-with for some really advanced third party integration with Umbraco.
Umbraco is a framework with plenty of hooks to allow you to tap in and put in your own functionality including pulling data from or into third party datasources. I would also recommend https://our.umbraco.org/projects/developer-tools/hybrid-framework/ on some good umbraco mvc practices
Regards
Ismail
You could run into a few issues...
Umbraco uses MVC 4. Now MVC 5 says it runs side by side, etc...
However, if you plan on using the Umbraco nuget package to manage your project in visual studio (the best path imo), you will have an issue because Umbraco hard relies on MVC 4 and will not upgrade to 5, so you won't be able to install MVC 5 in your Umbraco Project, nuget will complain and throw errors and halt the install.
Now, Umbraco wise.. Umbraco's front end is done entirely automatically for you with automatic routes to content nodes based on content types and templates (Templates are MVC Razor Views).
When you have custom forms, and ajaxy things, you create a Controller that Inherits from SurfaceController which Umbraco automatically routes to a url like /umbraco/surface/mySurface/SomeAction.
It has a custom Html Helper Umbraco.BeingForm which basically just fills out that url for you to your surface controller.
SurfaceController is an MVC controller and not a web API controller.
Umbraco has WepApi controllers you can use, but there is something really important to understand about that.
Umbraco has a split user/member security model. Meaning you have Front End Members (the users using your site), and Back Office Users (The people with access to the umbraco interfaces that manage the site).
The umbraco backoffice runs entirely on WebApi and Angular JS...
The important thing to know there is that Umbraco Routes controllers derrived from UmbracoApiController to back office urls.. Which means they authenticate as Back Office Users.
A Surface controller on the other hand, authenticates as a Front End Member.
So if you need a controller that authenticates as a Front End member, you are forced to
For example, if you manually routed your controller to /MyXyzPlugin/SomeController/SomeAction then it should authenticate as a Front End Member.
A few corrections:
FYI: we stopped doing that a few versions ago, however, there is a bug in Umbraco that you might run into. Read about the caveat (and fix) here: https://umbraco.com/follow-us/blog-archive/2015/7/29/upgrading-your-umbraco-site-to-mvc5-and-webapi2
This is not the case. :-) Use
MemberAuthorize
- https://our.umbraco.org/documentation/Reference/WebApi/authorizationBoth of your corrections are correct, and it's good to know about the MVC change to allow upgrading.
However on your 2nd point I've discovered something I should add "which is probably a bug"
You can inherit from UmbracoApiController and use both MemberAuthorize and UmbracoAuthorize attributes.
However if you are logged in as a front end member and a back office user the front end member seems to trump the back office user.
E.g. the call to the back office authorized method will result in an access restricted error. You have to log out the front member, then it works and the call doesn't get access restricted.
Now, the only front end members that would go to the back office would be admins, so it's not a huge deal to tell them to log out of the front end, but it is an inconvenience.
However, this could be due to me using a custom authentication method. E.g. we have a Jasig Cas Repository we authenticate against. As such I leverage WIF (Windows Identity Foundation) and use federated authentication with Passive Redirect enabled.
To work with umbraco I customized the SessionAuthenticationModule and called it "UmbracoSessionAuthenticationModule, and I use reflection to make a call to "ShouldAuthenticateRequest" on the umbraco module, if true, I disable WIF and if False I let WIF go through (which logs in the front member).
ShouldAuthenticateRequest returns false on /umbraco/api as such WIF Runs, logs in the front member, even when requesting an action with UmbracoAuthorize on it.
That causes a conflict because you can't be logged in to two authenticated sessions simultaneously in the request pipeline (ASP.Net By Design).
Umbraco uses forms authentication, as such it definitely can't be logged in to both at the same time. Both cookies can be present, but it can only process one or the other, not both.
I think a better approach to this would have been to generate two routes for 1 controller. One on /umbraco/api and the other on /umbraco/backoffice/api and assume that /umbraco/api always authenticates as a member and /umbraco/backoffice always authenticates as a user. But allow all requests to be anonymous to these urls unless MemberAuthorize or UmbracoAuthorize is used at the controller level.
E.g. you use MemberAuthorize at the controller level and all /umbraco/backoffice/api/xyxController requests would require being logged in as a member, but user requests to /umbraco/backoffice/api/xyzController would be anonymous. Or vice versa, or both required to be logged in (e.g. tag it with both MemberAuthorize and UserAuthorize requiring both urls to be logged in as a member or a user respectively).
The way it is now I'm going to continue to separate my controllers. I'll use UmbracoApiController for front end members and UmbracoAuthorizedApiController for back office users and I'll use an IOC pattern so that I just use a repository so I don't have duplicate controller logic.
is working on a reply...