so i have the next problem. I have a controller and some user roles. I'm using string when i have [Authorize(Roles="Admin")] but i want to use an enum like that because if i change the name of role i will modify in one single place.
I already tried Roles=UserRoles.Admin.ToString(), where UserRoles is my enum but i'm getting an error. I already read aricles from here but seems that no one helps me to solve my problem.
Could you help me with any suggestion?
Create a custom AuthorizeAttribute like this:
using System.Collections.Generic;
using System.Web.Mvc;
namespace MyApp.Whatever
{
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
public CustomAuthorizeAttribute(params UserRoles[] userRoles)
{
Roles = string.Join(",", userRoles);
}
}
}
Then you can use it as you would usually use the AuthorizeAttribute, like this:
using System.Web.Mvc;
namespace MyApp.Whatever
{
[CustomAuthorize(UserRoles.Admin, UserRoles.Whatever)]
public class MyController : Controller
{
...
}
}
This can be done, but you need to do a little work.
Create you own custom attribute implementing IAuthorizationFilter (as AuthorizeAttribute does)
Accept your enumeration in its constructor (or via a property)
Forward operations to a contained instance of AuthorizeAttribute
(The whole filter mechanism is extensible to allow this kind of thing.)
However, what I have done in the past, to deal with this is to define a series of constant strings which are passed to the attribute's instances. Thus keeping the names central.
Related
I was implementing repository decorator pattern on my project as:
[Auditable]
public class Product
{
public int Id {get; set;}
public string Name {get; set;}
}
I got this idea from the following link.
https://efpatterns.codeplex.com/discussions/282699
But couldn't successfully implemented. Then I start learning about decorator pattern and DataAnnotation because the way Auditable attribute on Product entity is somewhat similar in DataAnnotation and decorator pattern. So my question is are they same thing.? If they are the same then how would I implement Auditable repository pattern (more on link) on my project.
That's not the decorator pattern as originally described by the Gang Of Four.
The decorator pattern is an inheritance technique to add functionality to existing classes. The pattern works by creating a set of subclasses which each provide a specific type of functionality on top of the base class.
Then you compose a combination by passing the existing instance as inner object to a subclass instance:
public class SecurityToken
public class ExpiringToken : SecurityToken;
public class RpcSecurityToken : SecurityToken;
So if you would like to have a token which is remote and will expire after an amount of time:
var token = new RpcSecurityToken(new ExpiringToken(new SecurityToken("sds")));
What you do is to just decorate a class with an attribute, which not is the same thing.
The decorator pattern is a mechanism of taking a base implementation of a given interface as extending its behavior without modification of original implementation.
Its similar to inheriting from a base class, however it has more flexibility. For example, a decorator class can be applied to any other class that implements the same interface, there is no restriction to only extending a single base class. They can also be chained together etc...
e.g
public interface IThing
{
void AMethod()
}
public abstract class ThingDecorator : IThing
{
private IThing inner;
public ThingDecorator(IThing inner)
{
this.inner = inner;
}
public virtual void AMethod()
{
this.inner.AMethod();
}
}
Inheriting from ThingDecorator and applying your own extension to the virtual AMethod will add behavior (decorate) the inner instance that is passed in. As the inner instance is coupled to an interface it can be any implementation of that interface.
In your example, you could inherit ThingDecorator as AuditThingDecorator, and override AMethod and include Audit features before you call the base.AMethod()
This is different to just applying an attribute to a class. I think you are trying to apply behavior with an attribute. Attributes can only apply behavior to the class if there is a container, or some other part of the system that can read them and actually apply given behavior. With DataAnnotations, there are other classes that read these attributes and apply behavior (for example, within ASP.NET MVC, the DefaultModelBinder use some of the attributes to provide validation when binding the model).
This is a AOP (apsect orientated programming) approach. One way to apply this (and a way I tend to use) is to use Castle.Core and create interceptors that can automatically implement interface methods or extend virtual methods and read attributes from the Methods/properties that are intercepting, and then apply behavior:
http://docs.castleproject.org/Tools.DynamicProxy-Introduction.ashx
They are both essentially proxies of a given type, however the Decorator pattern above is not dynamic, they are created within code, and the AOP approach can apply behavior at runtime.
I would like to add attributes to my controller methods which can be inspected using reflection.
I can see how to do this by writing a filter, and I will write an empty filter if that's the only way to achieve what I want, but all I really want is a reflection-visible attribute that can be used to generate documentation. Example:
[OperatorFriendlyDescription("Begin a new message from a letter template and set initial properties.")]
public ActionResult Create(string editorName, int mastKey, ...)
Is there a way to get my OperatorFriendlyDescription attribute without writing a new filter?
(Alternatively, is there some other approach or documentation feature that would allow me to set an operator friendly name for individual controller methods and retrieve this with reflection?)
There is no magical way you can use an OperatorFriendlyDescription attribute without defining it, but if it doesn't need Filter functionality, don't inherit from FilterAttribute.
If you look at the declaration of the MVC FilterAttribute, you will see it is just a specialized System.Attribute.
public abstract class FilterAttribute : Attribute, IMvcFilter
From the MSDN documentation we can verify System.Attribute is the base for all attributes.
Since you have no special functionality needed, inherit from that instead.
An example Attribute in C#
public class ArbitraryAttribute: Attribute
{
public string ArbitraryData { get; private set; }
public ArbitraryAttribute(string arbitraryData)
{
ArbitraryData = arbitraryData;
}
}
Yes. Any attribute that allows being placed on that type of method/class/property, etc., can be used. This class has to inherit from System.Attribute or another class that inherits from that.
VB example, should be very similar in C#. This one can only be placed on methods due to the attribute target attribute. leave off the AttributeUsage attribute for the attribute to be used anywhere.
<AttributeUsage(AttributeTargets.Method)>
Public Class OperatorFriendlyDescription
Inherits System.Attribute
Public Property Description As String
Public Sub New(description As String)
Me.Description = description
End Sub
End Class
I recently asked this question and have successfully setup my custom authorize attribute.
But now I have hit another wall regarding api calls. I need these calls to also be authorized in the same fashion as the action calls. I understand that there is a difference between System.Web.Http and System.Web.Mvc Authorize attributes. So I have created a separate Api specific attribute that basically does the same thing. However, I am having trouble setting the User - principal and identity like i do in the original attribute.
My attributes simply check for some values in a cookie to authorize the request, once the attribute has read the cookie I was storing the decrypted cookie information within a custom principal/identity setup. In my Api call, when I go to retrieve this information from the identity my cast fails and i receive a null value.
This is how I store the information
Api
HttpContext.Current.User = new MyPrinciple(new MyIdentity(decCookie.Name, decCookie.UserData));
Action
filterContext.RequestContext.HttpContext.User = new MyPrinciple(new MyIdentity(decCookie.Name, decCookie.UserData));
How I retrieve the desired information I assumed would be the same
(User.principal.Identity as MyIdentity).MyData;
Questions
Do I really need to have 2 separate attributes
For the Api attribute how can I easily store the information for later use within the controller. Or basically can I not actually get/set the Identity this way for these calls?
EDIT #1
I found how to properly access my cookie value from my ApiController, I was simply missing a reference to System.Web >_<. So question #2 has been solved! but #1 still remains.
Web API and MVC have nothing in common (technically) - even when they look the same. You need two separate attributes.
You can only inherit in one class from in c#, and each authorizeattribute lives in its own namespace, so you can't do it in a single class.
You could hold it in a common namespace and then call a common class to do the lifting.
Possible solution (untested)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
namespace Common.Attributes
{
public class CustomAuthorize : System.Web.Mvc.AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (!HttpContext.Current.Request.IsAuthenticated || (HttpContext.Current.User as User) != null)
return;
filterContext.HttpContext.User = Authorize.ExtractIdentity(filterContext.HttpContext);
}
}
public class CustomHttpAuthorize : System.Web.Http.AuthorizeAttribute
{
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
base.OnAuthorization(actionContext);
if (!HttpContext.Current.Request.IsAuthenticated || (HttpContext.Current.User as User) != null)
return;
System.Threading.Thread.CurrentPrincipal = Authorize.ExtractIdentity(filterContext.HttpContext);
}
}
}
public static class Authorize
{
public static IIdentity ExtractIdentity(HttpContext context)
{
// do your magic here
}
}
}
Background
I am trying to move business logic out from the controllers into their own services.
Controller
public class AccountController : Controller
{
private readonly IAccountService _accountService;
public AccountController(IAccountService accountService)
{
_accountService = accountService;
}
....
}
I'm using Unity to inject dependencies. I'd like to use the Url.GenerateUrl() helper method within the implementation of IAccountService but Url is a property against the controller.
I looked at the MVC source to see how this is done but it requires me to access the RequestContext from outside of the controller, and I don't know how to do that.
Question
How do I access the RequestContext from outside the controller? If that won't solve my problem, how do I solve the problem given my setup?
This might not be quite right because I'm unable to test it at the moment, but I think that you can do something like this in .NET 4+:
using System.Web;
using System.Web.Mvc;
// ...
var helper = new UrlHelper(HttpContext.Current.Request.RequestContext);
string url = helper.GenerateUrl(/* ... */);
It might make more sense to pass the context from the controller to your IAccountService implementation rather than grabbing it directly from HttpContext.Current.
However i'd like to use the Url.GenerateUrl helper methods within my implementation of IAccountService
Simply pass this information as parameter. Example:
public ActionResult Index()
{
var someUrl = Url.Action("about");
_accountService.Foo(someUrl);
}
Now you no longer need UrlHelper inside your service classes. Everything that needs interacting with MVC infrastructure shouldn't be placed in your service classes. They shouldn't depend on any Request, Response, Session, ... It's the controller's responsibility to work with those objects and glue them together with your service classes.
I have a search form that can search in different provider.
I started out by having a base controller
public SearchController : Controller
{
protected readonly ISearchService _searchService
public SearchController(ISearchService searchService)
{
_searchService= searchService;
}
public ActionResult Search(...)
{
// Use searchService to query and return a view.
}
}
And child controllers
TwitterController : SearchController
{
...
}
NewsController : SearchController
{
...
}
I use StructureMap to insert all my dependencies in the controller. With this setup, I was able to change the SearchService depending on the type of the controller being instanciated.
x.For<ISearchService>().ConditionallyUse(o =>
{
o.TheDefault.Is.OfConcreteType<NewsSearchService>();
o.If(c => c.ParentType == typeof(TwitterController))
.ThenIt.Is.OfConcreteType<TwitterSearchService>();
...
});
That even allowed me to set different Views for each controller, (just putting the corresponding folder (Twitter, News...) and the Parent controller is still handling all the Search, with a simple
return View(results)
which is displaying the correct view specific to twitter, news, or other
Now that was cool and looked great, I a single form and the different views are displayed in tabs on the same page. That's where it starts to get complicated with this approach. The form has to post to /Twitter to search in twitter, to /News to search in news... which means I should change the action parameter of the form depending on which tab I am and display the correct tab on when the form returns depending on.. the url? craziness follows.
If you have built something like this already or know what's the best approach to this, please advices are welcome.
Now I think I would have less pain using a parameter in the form and posting to a single controller. I am thinking of injecting the correct SearchService depending on this parameter. What would be the best approach? I thought of using a model binder,
So I would have my ActionMethod that look like this:
public ActionResult Search(ISearchService service, Query query)
{
var results = service.Find(query);
}
But I think would need to make a call like this in the ModelBinder
ObjectFactory.GetInstance(...);
Based on the querystring parameter that describe which provider to use, and that doesn't seem more elegant to me. I feel stuck, help :(.
Whenever you need to vary a dependency based on a run-time value, Abstract Factory is the general solution.
Instead of injecting ISearchService into your Controllers, inject an ISearchServiceFactory:
public SearchController : Controller
{
private readonly ISearchServiceFactory searchServiceFactory;
public SearchController(ISearchServiceFactory searchServiceFactory)
{
if (searchServiceFactory == null)
{
throw new ArgumentNullException("searchServiceFactory");
}
this.searchServiceFactory = searchServiceFactory;
}
public ActionResult Search(...)
{
// Use searchServiceFactory to create an ISearchService based on
// run-time values, and use it to query and return a view.
}
}
It is not entirely clear to me which run-time value you need to vary on, but assuming that it's the Query, ISearchServiceFactory might be defined like this:
public interface ISearchServiceFactory
{
ISearchService Create(Query query);
}
I was trying to figure out how to use the abstract factory pattern and still let structuremap resolve all the dependencies of my components.
I believe that is the way I am going to implement it, but I submit this here to get some feedback if someone would read this.
As explain in the previous answer, I do not want to build the whole object graph depending on which provider I need in the Abstract factory.
ie :
class StatServiceFactory : IStatServiceFactory
{
public IStatService Create(string provider)
{
switch(provider)
{
case "blog":
return new StatService(IFacetRepository,ISearchManager,IConfigManager,BooleanQueryBuilder);
//How to resolve the Config, the SearchManager, and BooleanQueryBuilder?
//Add more abstract factories? It starts to get messy in my opinion...
}
}
}
What I can do is have the abstract factory use my container to create an instance of my search managers depending on a parameter (coming from the querystring in my case)
Structuremap allows to create named instances this way :
x.For<ISearchManager>().Use<AbcSearchManager>().Named("Abc");
x.For<ISearchManager>().Use<DefSearchManager>().Named("Def");
I need a way to inject the container in my Abstract factory.
I would probably wrap the container in a wrapper defined like this. That would keep me from leaking Structuremap into my project. I dont need more that those 2 features within the abstract factory anyway, but it is not necessary:
public interface IContainerWrapper
{
object GetInstance<T>();
object GetNamedInstance<T>(string key);
}
and the implementation :
public class ContainerImpl : IContainerWrapper
{
private readonly Container _container
public ContainerImpl(Container container)
{
_container = container;
}
...
}
And setup StructureMap to resolve dependencies to my abstract factory like that :
x.For<IContainer>.Use(new ContainerImpl(this));
x.For<IFactory>.Use<Factory>()
My factory would be then much simpler and would create my instance like that :
public class SearchmanagerFactory
{
private readonly IContainerWrapper _container;
public SearchmanagerFactory(IContainerProvider containerProvider)
{
_container = containerProvider;
}
public ISearchManager Create(string provider)
{
//eed to handle the bad input for provider.
return (ISearchManager)
_container.Resolve<ISearchManager>(provider);
}
}
That seems pretty clean this way :).
Thoughts?
This is more an extensive comment than an answer to explain why an AbstractFactory seems complicated. Here is something that looks closer from the reality:
class StatServiceFactory : IStatServiceFactory
{
public IStatService Create(string provider)
{
switch(provider)
{
case "blog":
return new StatService(IFacetRepository,ISearchManager,IConfigManager,BooleanQueryBuilder);
//How to resolve the Config, the SearchManager, and BooleanQueryBuilder?
//Add more abstract factories? It starts to get messy in my opinion...
}
}
}
The FacetRepository is the same for any provider, but the SearchManager changes, the ConfigManager changes, and the BooleanQueryBuilder is an abstract class with different implementation for different provider (because every API doesnt use the same keyword for their queries) All those dependencies are currently resolved by structuremap, based on the type of the controller.
I would really like to keep the benefit of StructureMap here, rather than using factories all the way, for each different pieces.'
Please see my edit at the end of my question for another suggestion to my problem.