How to handle security / authentication in a DNN based web interface

I am creating a REST API for the DotNetNuke 6 site using the DNN MVC service infrastructure. However, I do not have a background for authentication, so I don’t even know where to start.

Basically, we want our customers to be able to make GET requests for their portal data, and we want some customers (but not all) to receive simple POST updates to their user data.

I am trying to find information, but the problem is that I am not sure what I am looking for. DNN has different logins and roles, but I'm not sure what and how they affect. I have heard about things like oAuth, but my understanding of this is at a very basic level. I do not know what I need or not, and if and how it applies to DNN. Can someone point me in the right direction?

UPDATE : Based on the answer below about binding it to a module and further research, here's what I did:

I created a module only for this service, and I added two special permissions for it: "APIGET" and "APIPOST". I assigned them to some test roles / test accounts in DNN. I wrote a special authorize attribute, which, given the module identifier, checks if the current user has the necessary permission (through roles or directly). As far as I can tell, the tab identifier in my case does not matter.

It seems to work with both a web browser (based on the DNN account I logged in to) and with a php script that sends an HTTP request with username / password.

Authorize attribute:

using DotNetNuke.Entities.Modules; using DotNetNuke.Entities.Portals; using DotNetNuke.Security; using DotNetNuke.Security.Permissions; using System.Web; public class MyAuthorize : DotNetNuke.Web.Services.AuthorizeAttributeBase { public const string AuthModuleFriendlyName = "MyAuthModule"; public const string GETPermission = "APIGET"; public const string POSTPermission = "APIPOST"; public string Permission { get; set; } protected override bool AuthorizeCore(HttpContextBase context) { ModuleController mc = new ModuleController(); ModuleInfo mi = mc.GetModuleByDefinition(PortalController.GetCurrentPortalSettings().PortalId, AuthModuleFriendlyName); ModulePermissionCollection permCollection = mi.ModulePermissions; return ModulePermissionController.HasModulePermission(permCollection, Permission); } } 

Controller: ("mytest" is the endpoint for GET and POST)

 public class MyController : DnnController { [ActionName("mytest")] [AcceptVerbs(HttpVerbs.Get)] [DnnAuthorize(AllowAnonymous = true)] [MyAuthorize(Permission = MyAuthorize.GETPermission)] public string myget(string id = "") { return "You have my permission to GET"; } [ActionName("mytest")] [AcceptVerbs(HttpVerbs.Post)] [DnnAuthorize(AllowAnonymous = true)] [MyAuthorize(Permission = MyAuthorize.POSTPermission)] public string mypost(string id = "") { return "You have my permission to POST"; } } 
+8
restful-authentication dotnetnuke
source share
4 answers

The primary way to bind a service in the DNN Services Framework to DNN permissions is to associate the permissions with the module instance. That is, you need users of your service to determine which module they are calling from / about (by sending ModuleId and TabId to the request [headers, request line, cookie, form]), then you can specify what permissions they need this module to take a specific action in the service.

You can use the SupportedModules attribute in your service and pass a comma-separated list of module names to make sure that only your own modules are allowed. Then add the DnnModuleAuthorize attribute at the service or individual activity level to indicate what permission the user requires in this module. In your example, you can also add the AllowAnonymous attribute to the GET actions and have one DnnModuleAuthorize in the service, for the POST methods (and everything else). Note that you cannot put the AllowAnonymous attribute on the controller; he will revoke the powers put into effect, which makes it impossible to make actions more restrictive.

You will also want to add the ValidateAntiForgeryToken attribute for POST actions to protect against CSRF attacks.

If you do not have a module that, naturally, associates its permissions with your service, you can create it only for this purpose, solely to show yourself as a permission management utility.

After you figure out the above authorization part, DNN will take care of authentication using cookie forms (for example, AJAX scripts will take care of automatically) or using basic or digest authentication (for scripts other than AJAX). However, if you are doing non-AJAX, you need to figure out a way to check the anti-fake token only when it is applied.

+8
source share

The service structure in DNN is what you need. It allows you to provide a REST API that connects directly to DNN security.

Here are some articles to help you get started:

Note that there are several differences in DNN 6 and DNN 7 when using Framework Services:

+4
source share

I just wanted to notice that the DnnModuleAuthorize attribute accepts the PermissionKey parameter for user permissions so you can do these things:

  [DnnModuleAuthorize(PermissionKey = "DELETEDATA")] [HttpPost] public HttpResponseMessage DeleteData(FormDataCollection data) 

It doesn't seem like you can provide your own error message so that you can instead wrap the body of the method this way and leave your own permissions attribute:

  [DnnModuleAuthorize(AccessLevel = SecurityAccessLevel.View)] [HttpPost] public HttpResponseMessage DeleteData(FormDataCollection data) { var errorMessage = "Could not delete data"; if (ModulePermissionController.HasModulePermission(ActiveModule.ModulePermissions,"DELETEDATA")) { // do stuff here } else { errorMessage = "User does not have delete permission"; } var error = new HttpResponseMessage(HttpStatusCode.BadRequest) { Content = new StringContent( errorMessage) }; return error; } 
+2
source share

Just wanted to add @Richards comment for using [DnnModuleAuthorize(PermissionKey = "DELETEDATA")] for user permissions.

The full attribute must be:

 [DnnModuleAuthorize(PermissionKey = "DELETEDATA", AccessLevel = SecurityAccessLevel.Edit)] 

Leaving it blank does nothing, as shown here: https://github.com/dnnsoftware/Dnn.Platform/blob/f4a5924c7cc8226cfe79bbc92357ec1a32165ada/DNN%20Platform/Library/Security/Permissions/PermissionProvider.cs#

+1
source share

All Articles