Example T488888
Visible to All Users

Reporting for MVC - How to Implement a Custom Authorization Service

This example illustrates how to restrict access to specific reports and documents based on an ASP.NET session, making documents available only to users that generated them. To do this, register an OperationLogger object implementing the IWebDocumentViewerAuthorizationService interface and is inherited from the base WebDocumentViewerOperationLogger class.

Documentation

Files to Review

Does this example address your development requirements/objectives?

(you will be redirected to DevExpress.com to submit your response)

Example Code

AuthorizationService/Services/OperationLogger.cs
C#
using DevExpress.XtraReports.UI; using DevExpress.XtraReports.Web.WebDocumentViewer; using System.Collections.Concurrent; using System.Web; using System; using DevExpress.XtraPrinting; using DevExpress.XtraReports.Web.ClientControls; namespace AuthorizationService.Services { public class OperationLogger: WebDocumentViewerOperationLogger, IWebDocumentViewerAuthorizationService, IExportingAuthorizationService { public override void ReportOpening(string reportId, string documentId, XtraReport report) { if (HttpContext.Current.Session == null) { return; } SaveUsedEntityId(Constants.ReportDictionaryName, reportId); SaveUsedEntityId(Constants.DocumentDictionaryName, documentId); } public override void BuildStarted(string reportId, string documentId, ReportBuildProperties buildProperties) { SaveUsedEntityId(Constants.ReportDictionaryName, reportId); SaveUsedEntityId(Constants.DocumentDictionaryName, documentId); } public override ExportedDocument ExportDocumentStarting(string documentId, string asyncExportOperationId, string format, ExportOptions options, PrintingSystemBase printingSystem, Func<ExportedDocument> doExportSynchronously) { SaveUsedEntityId(Constants.ExportedDocumentDictionaryName, asyncExportOperationId); return base.ExportDocumentStarting(documentId, asyncExportOperationId, format, options, printingSystem, doExportSynchronously); } public override void ReleaseDocument(string documentId) { } bool IWebDocumentViewerAuthorizationService.CanCreateDocument() { return CheckUserAuthorized(); } bool IWebDocumentViewerAuthorizationService.CanCreateReport() { return CheckUserAuthorized(); } bool IWebDocumentViewerAuthorizationService.CanReadDocument(string documentId) { return CheckEntityAvailability(Constants.DocumentDictionaryName, documentId); } bool IWebDocumentViewerAuthorizationService.CanReadReport(string reportId) { return CheckEntityAvailability(Constants.ReportDictionaryName, reportId); } bool IWebDocumentViewerAuthorizationService.CanReleaseDocument(string documentId) { return CheckEntityAvailability(Constants.DocumentDictionaryName, documentId); } bool IWebDocumentViewerAuthorizationService.CanReleaseReport(string reportId) { return CheckEntityAvailability(Constants.ReportDictionaryName, reportId); } public bool CanReadExportedDocument(string exportDocumentId) { return CheckEntityAvailability(Constants.ExportedDocumentDictionaryName, exportDocumentId); } bool CheckUserAuthorized() { var user = HttpContext.Current.User; if (user == null || user.Identity == null || !user.Identity.IsAuthenticated) { return false; } return true; } void SaveUsedEntityId(string dictionaryName, string id) { if (string.IsNullOrEmpty(id)) return; ConcurrentDictionary<string, bool> dictionary = null; lock (HttpContext.Current.Session.SyncRoot) { if (HttpContext.Current.Session[dictionaryName] == null) HttpContext.Current.Session[dictionaryName] = dictionary = new ConcurrentDictionary<string, bool>(); } if (dictionary == null) dictionary = ((ConcurrentDictionary<string, bool>)HttpContext.Current. Session[dictionaryName]); dictionary.AddOrUpdate(id, false, (_1, _2) => false); } bool CheckEntityAvailability(string dictionaryName, string id) { if (string.IsNullOrEmpty(id) || !CheckUserAuthorized()) return false; lock (HttpContext.Current.Session.SyncRoot) { if (HttpContext.Current.Session[dictionaryName] == null) return false; } return ((ConcurrentDictionary<string, bool>)HttpContext.Current. Session[dictionaryName]).ContainsKey(id); } void DisposeEntityRequested(string dictionaryName, string id) { if (string.IsNullOrEmpty(id)) return; lock (HttpContext.Current.Session.SyncRoot) { if (HttpContext.Current.Session[dictionaryName] == null) return; } ((ConcurrentDictionary<string, bool>)HttpContext.Current. Session[dictionaryName]).AddOrUpdate(id, true, (_1, _2) => true); } } }
AuthorizationService/Global.asax
Code
<%@ Application Codebehind="Global.asax.cs" Inherits="AuthorizationService.MvcApplication" Language="C#" %>

Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.