Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 370615
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 12, 20262026-05-12T14:02:06+00:00 2026-05-12T14:02:06+00:00

With Domain Driven Design in mind, how would you implement user Authorization in a

  • 0

With Domain Driven Design in mind, how would you implement user Authorization in a repository? Specifically, how would you restrict what data you can see by the user provided login?

Lets say we have an e-commerce Mall that stores products, where only some products are maintained by any given store manager. In this case, not all products should be seen by any given login.

Questions:

  1. Would you select all products in the Repo, then use a filter to restrict what products are returned? Like GetProducts("keyword: boat").restrictBy("myusername")?
  2. Would you read the login from the controllercontext within the repository and filter results passively?
  3. How would you store the relation between a user role and what entities it could access? Would you simply store the entity key and the role in a many-to-many table, having one record for each product that each store manager could access?

Code examples or links to code examples would be fantastic. Thank you.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-12T14:02:06+00:00Added an answer on May 12, 2026 at 2:02 pm

    The tack that I’ve taken is to use attributes on the controller action that examines the relation between the current user and the entity being requested, then either allows or disallows the action based on the results of the look up. I have a couple of different attributes depending on whether it goes through a join table or has a direct relationship. It uses reflection against, in my case the data context, but in yours the repository(ies) to get and check that the values match. I’ll include the code below (which I’ve made some efforts to genericize so it may not compile). Note you could extend this to include some notion of permission as well (in the join table).

    Code for the direct relationship attribute. It verifies that the current user is the owner of the record (the specified “id” attribute in the routing parameters matches the id of the current user in the user table).

    [AttributeUsage( AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false )]
    public class RoleOrOwnerAuthorizationAttribute : AuthorizationAttribute
    {
        private IDataContextFactory ContextFactory { get; set; }
    
        private string routeParameter = "id";
        /// <summary>
        /// The name of the routing parameter to use to identify the owner of the data (participant id) in question.  Default is "id".
        /// </summary>
        public string RouteParameter
        {
            get { return this.routeParameter; }
            set { this.routeParameter = value; }
        }
    
        public RoleOrOwnerAuthorizationAttribute()
            : this( null )
        {
        }
    
        // this is for unit testing support
        public RoleOrOwnerAuthorizationAttribute( IDataContextFactory factory )
        {
            this.ContextFactory = factory ?? DefaultFactory();
        }
    
        public override void OnAuthorization( AuthorizationContext filterContext )
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException( "filterContext" );
            }
    
            if (AuthorizeCore( filterContext.HttpContext ))
            {
                SetCachePolicy( filterContext );
            }
            else if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                // auth failed, redirect to login page
                filterContext.Result = new HttpUnauthorizedResult();
            }
            else if (filterContext.HttpContext.User.IsInRole( "SuperUser" ) || IsOwner( filterContext ))
            {
                SetCachePolicy( filterContext );
            }
            else
            {
                ViewDataDictionary viewData = new ViewDataDictionary();
                viewData.Add( "Message", "You do not have sufficient privileges for this operation." );
                filterContext.Result = new ViewResult { MasterName = this.MasterName, ViewName = this.ViewName, ViewData = viewData };
            }
    
        }
    
        private bool IsOwner( AuthorizationContext filterContext )
        {
            using (var dc = this.ContextFactory.GetDataContextWrapper())
            {
                int id = -1;
                if (filterContext.RouteData.Values.ContainsKey( this.RouteParameter ))
                {
                    id = Convert.ToInt32( filterContext.RouteData.Values[this.RouteParameter] );
                }
    
                string userName = filterContext.HttpContext.User.Identity.Name;
    
                return dc.Table<UserTable>().Where( p => p.UserName == userName && p.ParticipantID == id ).Any();
            }
    
        }
    
    }
    

    This is the code for the association attribute, i.e., there exists an association in a join table between the id in the routing parameter and the user’s id from the user table. Note that there is a dependency on the System.Linq.Dynamic code from the VS2008 Samples.

    [AttributeUsage( AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false )]
    public class RoleOrOwnerAssociatedAuthorizationAttribute : MasterEventAuthorizationAttribute
    {
        private IDataContextFactory ContextFactory { get; set; }
    
        public RoleOrOwnerAssociatedAuthorizationAttribute()
            : this( null )
        {
        }
    
        // this supports unit testing
        public RoleOrOwnerAssociatedAuthorizationAttribute( IDataContextFactory factory )
        {
            this.ContextFactory = factory ?? new DefaultDataContextFactory();
        }
    
        /// <summary>
        /// The table in which to find the current user by name.
        /// </summary>
        public string UserTable { get; set; }
        /// <summary>
        /// The name of the property in the UserTable that holds the user's name to match against
        /// the current context's user name.
        /// </summary>
        public string UserNameProperty { get; set; }
        /// <summary>
        /// The property to select from the UserTable to match against the UserEntityProperty on the JoinTable
        /// to determine membership.
        /// </summary>
        public string UserSelectionProperty { get; set; }
        /// <summary>
        /// The join table that links users and the entity table.  An entry in this table indicates
        /// an association between the user and the entity.
        /// </summary>
        public string JoinTable { get; set; }
        /// <summary>
        /// The property on the JoinTable used to hold the entity's key.
        /// </summary>
        public string EntityProperty { get; set; }
        /// <summary>
        /// The property on the JoinTable used to hold the user's key.
        /// </summary>
        public string UserEntityProperty { get; set; }
        /// <summary>
        /// The name of the route data parameter which holds the group's key being requested.
        /// </summary>
        public string RouteParameter { get; set; }
    
        public override void OnAuthorization( AuthorizationContext filterContext )
        {
            using (var dc = this.ContextFactory.GetDataContextWrapper())
            {
                if (filterContext == null)
                {
                    throw new ArgumentNullException( "filterContext" );
                }
    
                if (AuthorizeCore( filterContext.HttpContext ))
                {
                    SetCachePolicy( filterContext );
                }
                else if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
                {
                    // auth failed, redirect to login page
                    filterContext.Result = new HttpUnauthorizedResult();
                }
                else if (filterContext.HttpContext.User.IsInRole( "SuperUser" )
                         || IsRelated( filterContext, this.GetTable( dc, this.JoinTable ), this.GetTable( dc, this.UserTable ) ))
                {
                    SetCachePolicy( filterContext );
                }
                else
                {
                    ViewDataDictionary viewData = new ViewDataDictionary();
                    viewData.Add( "Message", "You do not have sufficient privileges for this operation." );
                    filterContext.Result = new ViewResult { MasterName = this.MasterName, ViewName = this.ViewName, ViewData = viewData };
                }
            }
        }
    
        protected bool IsRelated( AuthorizationContext filterContext, IQueryable joinTable, IQueryable userTable )
        {
            bool result = false;
            try
            {
                int entityIdentifier = Convert.ToInt32( filterContext.RouteData.Values[this.RouteParameter] );
                int userIdentifier = this.GetUserIdentifer( filterContext, userTable );
    
                result = joinTable.Where( this.EntityProperty + "=@0 and " + this.UserEntityProperty + "=@1",
                                          entityIdentifier,
                                          userIdentifier )
                                  .Count() > 0;
            }
            catch (NullReferenceException) { }
            catch (ArgumentNullException) { }
            return result;
        }
    
        private int GetUserIdentifer( AuthorizationContext filterContext, IQueryable userTable )
        {
            string userName = filterContext.HttpContext.User.Identity.Name;
    
            var query = userTable.Where( this.UserNameProperty + "=@0", userName )
                                 .Select( this.UserSelectionProperty );
    
            int userIdentifer = -1;
            foreach (var value in query)
            {
                userIdentifer = Convert.ToInt32( value );
                break;
            }
            return userIdentifer;
        }
    
        private IQueryable GetTable( IDataContextWrapper dc, string name )
        {
            IQueryable result = null;
            if (!string.IsNullOrEmpty( name ))
            {
                DataContext context = dc.GetContext<DefaultDataContext>();
                PropertyInfo info = context.GetType().GetProperty( name );
                if (info != null)
                {
                    result = info.GetValue( context, null ) as IQueryable;
                }
            }
            return result;
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 203k
  • Answers 203k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer Speaking as a representative of Kaazing: Eikos Partners won an… May 12, 2026 at 8:29 pm
  • Editorial Team
    Editorial Team added an answer As long as you have a connection from your WCF… May 12, 2026 at 8:29 pm
  • Editorial Team
    Editorial Team added an answer EDIT: to prevent race conditions in concurrent environments, use WITH… May 12, 2026 at 8:29 pm

Related Questions

I have been building a new application using my current understanding of domain driven
I'm thinking of implementing a Domain Driven Design approach (similar to the one described
I've read a lot of books on software design, and more and more I'm
How do you deal with validation on complex aggregates in a domain driven design?
In a domain driven design where you're going for a non-anemic domain model how

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.