How to secure your Umbraco Api controllers
This section will describe how to secure your Umbraco Api controllers based on a users membership
UmbracoAuthorizedApiController
has been removed from Umbraco 14. Use ManagementApiControllerBase
class instead.
Probably the easiest way to ensure your controller is secured for only backoffice users is to inherit from Umbraco.Cms.Web.BackOffice.Controllers.UmbracoAuthorizedApiController
. This is essentially the same as applying [Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)]
to your controller (see below).
The UmbracoAuthorizedApiController
is automatically routed. Check out the routing documentation for more information on this topic.
To secure your controller based on backoffice membership use the attribute: Microsoft.AspNetCore.Authorization.Authorize
, with the policy parameter set to AuthorizationPolicies.BackOfficeAccess
, like so: [Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)]
.
This attribute will ensure that a valid backoffice user is logged in. It is important to know that this only works if the controller is routed to /umbraco/backoffice/*
.
Example:
This will only allow a logged in backoffice user to access the GetProduct
action:
The AuthorizationPolicies
has a series of other options you can set. An example is UserBelongsToUserGroupInRequest
. By using this policy, you can check if the current incoming request of the user is in a specific backoffice User Group.
Example:
This will only allow a logged-in backoffice user that has access to the SensitiveData User Group to access the GetProduct
action:
You can add custom policies so you can set up your own requirements. You can do this by adding a new Policy to your builder:
Example:
After configuring, you can now use the Authorize
attribute with the name of your policy:
To secure your controller based on front-end membership use the attribute: Umbraco.Cms.Web.Common.Filters.UmbracoMemberAuthorize
.
There are 3 parameters that can be supplied to control how the authorization works:
To allow all members, use the attribute without supplying any parameters.
You can apply these attributes at the controller level or at the action level.
Examples:
This will only allow logged in members of type "Retailers" to access the GetAllProducts
action:
This will only allow member's belonging to the group VIP to access any actions on the controller:
This will only allow member's with Ids 1, 10 and 20 to access any actions on the controller:
How api controllers are routed and how to retrieve their URLs
This section will describe how Umbraco Api controllers are routed and how to retrieve their URLs
Like Surface Controllers in Umbraco, when you inherit from the base class Umbraco.Cms.Web.Common.Controllers.UmbracoApiController
we will auto-route this controller so you don't have to worry about routing at all.
All locally declared Umbraco api controllers will be routed under the URL path of:
~/Umbraco/Api/[YourControllerName]
All plugin based Umbraco api controllers will be routed under the URL path of:
~/Umbraco/[YourAreaName]/[YourControllerName]
We've added some handy UrlHelper
extension methods to help you retrieve the Url of your Umbraco Api controllers. The extension methods are found in the class: Umbraco.Extensions.UrlHelperExtensions
so you'll need to ensure you have the namespace Umbraco.Extensions
imported. You will also need to inject UmbracoApiControllerTypeCollection
, if you want to use any of the overloads that require it.
The method overloads are:
The most consistent way to retrieve a Url is to use your controller's type, and an expression to select the action. Example of retrieving a URL in a view:
Generally a UrlHelper instance will be available on most base classes like Controllers and Views, and you shouldn't have to create it manually, but if you need to you can, by injecting IUrlHelperFactory
and IActionContextAccessor
and then use the factory like so:
A guide to implenting WebApi in Umbraco projects
This section will describe how to work with Web API in Umbraco to create REST services
Related links:
The Microsoft Web API reference can be found on the official ASP.NET Web API website.
"ASP.NET enables you to build services that reach a broad range of clients, including browsers and mobile devices. With ASP.NET you use the same framework and patterns to build both web pages and services, side-by-side in the same project."
A great resource for getting started with creating web API's using .Net Core is the official Microsoft documentation.
We have created a base API controller for developers to inherit from. This will ensure that the API controller gets routed. This does not expose any specific Umbraco-related services or objects but does inherit from the .Net Core controller base. This means that you will have access to the same things you would from a regular .Net Core controller. Dependency injection is also available to controllers. Any Umbraco-specific services or objects you might need can be injected into the constructor.
The class to inherit from is: Umbraco.Cms.Web.Common.Controllers.UmbracoApiController
There are 2 types of Umbraco API controllers:
A locally declared controller - is not routed via an Area.
A plugin based controller - is routed via an Area.
When working on your own projects you will normally be creating a locally declared controller which requires no additional steps. However, if you are creating an Umbraco package, to be distributed, you will want to create a plugin based controller so it gets routed via its own area. This ensures that the route will not overlap with someone's locally declared controller if they are both named the same thing.
It is very important that you name your controllers according to these guidelines or else they will not get routed:
All controller class names must be suffixed with "Controller" and inherit from UmbracoApiController. Some examples:
This is the most common way to create an Umbraco API controller, you inherit from the class Umbraco.Cms.Web.Common.Controllers.UmbracoApiController
and that is all. You will need to follow the guidelines specified by Microsoft for creating a Web API controller, documentation can be found on the official Microsoft documentation website.
Example:
All locally declared Umbraco API controllers will be routed under the url path of:
~/Umbraco/Api/[YourControllerName]
E.g. *~/Umbraco/Api/Products/GetAllProducts
Note that the "Controller" part of your controller name gets stripped away.
If you are creating an Umbraco API controller to be shipped in an Umbraco package you will need to add the Umbraco.Cms.Web.Common.Attributes.PluginController
attribute to your controller to ensure that it is routed via an area. The area name is up to you to specify in the attribute.
Example:
Now this controller will be routed via the area called "AwesomeProducts". All plugin based Umbraco API controllers will be routed under the url path of:
~/Umbraco/[YourAreaName]/[YourControllerName]
E.g. ~/Umbraco/AwesomeProducts/Products/GetAllProducts
For more information about areas, Urls and routing see the routing section
UmbracoAuthorizedApiController
and UmbracoAuthorizedJsonController
have been removed from Umbraco 14. Use ManagementApiControllerBase
class instead.
If you are creating a controller to work within the Umbraco backoffice then you will need to ensure that it is secured properly by inheriting from: UmbracoAuthorizedApiController
or UmbracoAuthorizedJsonController
. This controller type will auto-route your controller like the above examples except that it will add another segment to the path: 'backoffice'.
~/Umbraco/backoffice/Api/[YourControllerName]
~/Umbraco/backoffice/[YourAreaName]/[YourControllerName]
E.g. ~/Umbraco/backoffice/Api/Products/GetAllProducts
or
~/Umbraco/backoffice/AwesomeProducts/Products/GetAllProducts
for PluginController
When examining a backoffice controller response in your browser, you will see additional characters which prefix the response as JSON vulnerability protection. This is normal, and these characters are removed by AngularJS' $http
service or Umbraco's umbRequestHelper
. For more info see the issue reported on the Umbraco CMS GitHub Issue tracker.
Attribute routing uses attributes to define routes. Attribute routing gives you more control over the URIs in your web application.
To exclude any endpoint or folders in your directory from Umbraco's routing, add it to the ReservedPaths
setting in the appsettings.json
file.
For example:
For more information, see the Global Settings article.
To use attribute routing, add the Microsoft.AspNetCore.Mvc.Route
attribute to the controller or controller action you want to route. If you want to attribute route an entire controller you have to add the [action]
token in order to route to an action, for instance:
This route the controllers actions like so:
~/products/GetAllProducts
and ~/products/GetProduct
If you use the route attribute for a specific action the [action]
token is not nececary, but you can request parameters from the path in a similar manner, using the {parameterName}
syntax, for instance:
Here the GetAllProducts
endpoint will be routed normally, but the GetProduct
will be routed as ~/product
where you can optionally access it as ~/product/4
, or any other number, if a number is included as the last segment of the path, let's say 4, the action will return "Monitor model 4", otherwise it will just return "Base model Monitor".
This is not anything Umbraco specific, so to read more about attribute routing, see the routing article on the official Microsoft documentation.