On an Azure Mobile App Services server side app using MVC 5, Web API 2.0, and EF Core 1.0, controllers can be decorated like so to implement token based authentication:
// Server-side EF Core 1.0 / Web API 2 REST API
[Authorize]
public class TodoItemController : TableController<TodoItem>
{
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
DomainManager = new EntityDomainManager<TodoItem>(context, Request);
}
// GET tables/TodoItem
public IQueryable<TodoItem> GetAllTodoItems()
{
return Query();
}
...
}
I want to be able to do something similar on the client side where I decorate a method with something like [Authorize] from above, perhaps with a, [Secured], decoration, below:
public class TodoItem
{
string id;
string name;
bool done;
[JsonProperty(PropertyName = "id")]
public string Id
{
get { return id; }
set { id = value;}
}
[JsonProperty(PropertyName = "text")]
public string Name
{
get { return name; }
set { name = value;}
}
[JsonProperty(PropertyName = "complete")]
public bool Done
{
get { return done; }
set { done = value;}
}
[Version]
public string Version { get; set; }
}
// Client side code calling GetAllTodoItems from above
[Secured]
public async Task<ObservableCollection<TodoItem>> GetTodoItemsAsync()
{
try
{
IEnumerable<TodoItem> items = await todoTable
.Where(todoItem => !todoItem.Done)
.ToEnumerableAsync();
return new ObservableCollection<TodoItem>(items);
}
catch (MobileServiceInvalidOperationException msioe)
{
Debug.WriteLine(#"Invalid sync operation: {0}", msioe.
}
catch (Exception e)
{
Debug.WriteLine(#"Sync error: {0}", e.Message);
}
return null;
}
Where [Secured] might be defined something like this:
public class SecuredFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Check if user is logged in, if not, redirect to the login page.
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
// Check some globally accessible member to see if user is logged out.
}
}
Unfortunately, the above code only works in Controllers in MVC 1.0 applications and above according to the Microsoft article on "Creating Custom Action Filters": https://msdn.microsoft.com/en-us/library/dd381609(v=vs.100).aspx
How do I implement something like a "Custom Action Filter" that allows me to use the "[Secured]" decoration in a Mobile App Service client instead of the server? The answer will help me create custom authentication from the client side and keep the code in one location without complicating the implementation, i.e., it is a cross-cutting concern like performance metrics, custom execution plans for repeated attempts, logging, etc.
Complicating the scenario, the client also implements Xamarin.Forms for iOS and has to be a functional Ahead of Time pattern due to iOS's requirement for native code, JIT is not yet possible.
The reason attributes work in the scenarios you describe is because other code is responsible for actually invoking the methods or reading the properties, and this other code will look for the attributes and modify behaviour accordingly. When you are just running C# code, you don't normally get that; there isn't a native way to, say, execute the code in an attribute before a method is executed.
From what you are describing, it sounds like you are after Aspect Oriented Programming. See What is the best implementation for AOP in .Net? for a list of frameworks.
In essence, using an appropriate AOP framework, you can add attributes or other markers and have code executed or inserted at compile time. There are many approaches to it, hence why I am not being very specific, sorry.
You do need to understand that the AOP approach is different from how things like ASP.Net MVC works as AOP will typically modify your runtime code (in my understanding anyway and I'm sure there are variations on that as well).
As to whether AOP is really the way to go will depend on your requirements, but I would proceed with caution - it's not for the faint of heart.
One completely alternative solution to this problem is to look at something like Mediatr or similar to break your logic into a set of commands, which you can call via a message bus. The reason that helps is that you can decorate your message bus (or pipeline) with various types of logic, including authorization logic. That solution is very different from what you are asking for - but may be preferable anyway.
Or just add a single-line authorisation call as the first line inside each method instead of doing it as an attribute...
What you are more generally describing in known by a few different names/terms. The first that comes to mind is "Aspect Oriented Programming" (or AOP for short). It deals with what are known as cross cutting concerns. Im willing to bet you want to do one of two things
Log exceptions/messages in a standardized meaningful way
Record times/performance of areas of your system
And in the generala sense, yes C# is able to do such things. There will be countless online tutorials on how to do so, it is much too broad to answer in this way.
However, the authors of asp.net MVC have very much thought of these things and supply you with many attributes just as you describe, which can be extended as you please, and provide easy access to the pipeline to provide the developer with all the information they need (such as the current route, any parameters, any exception, any authorization/authentication request etc etc)
This would be a good place to start: http://www.strathweb.com/2015/06/action-filters-service-filters-type-filters-asp-net-5-mvc-6/
This also looks good: http://www.dotnetcurry.com/aspnet-mvc/976/aspnet-mvc-custom-action-filter
Related
I'm learning dependency injection, because I don't want my BE to look spaghety no more. I have a good understanding of Asp.Net Core and EF Core. I just never learned dependecy injection properly. I'm playing around with an idea. Let's say, that I create an EmailSenderService (and IEmailSenderService with it). I do the same for CustomLogger and WeatherRepository. Here are the implementations:
Program.cs:
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddScoped<ICustomLogger, CustomLogger>();
builder.Services.AddScoped<IEmailSenderService, EmailSenderService>();
builder.Services.AddScoped<IWeatherRepository, WeatherRepository>();
// Add swagger
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) {
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
}
CustomLogger.cs
public interface ICustomLogger
{
public void Log(string logText);
}
public class CustomLogger : ICustomLogger
{
public void Log(string logText) => System.Diagnostics.Debug.WriteLine(logText);
}
EmailSenderService.cs
public interface IEmailSenderService
{
public void SendMail(string email, string text);
}
public class EmailSenderService : IEmailSenderService
{
public void SendMail(string email, string text) => System.Diagnostics.Debug.WriteLine($"TO: {email}, TEXT: {text}");
}
WeatherForecastModel.cs
public struct WeatherForecastModel
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}
WeatherRepository.cs
public interface IWeatherRepository
{
public WeatherForecastModel[] GetRandomSample();
}
public class WeatherRepository : IWeatherRepository
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
public WeatherForecastModel[] GetRandomSample() =>
Enumerable.Range(1, 5).Select(index => new WeatherForecastModel
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
}).ToArray();
}
WeatherForecastController.cs
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private readonly ICustomLogger _customLogger;
private readonly IEmailSenderService _emailSenderService;
private readonly IWeatherRepository _weatherRepository;
public WeatherForecastController(ICustomLogger customLogger, IEmailSenderService emailSenderService, IWeatherRepository weatherRepository)
{
_customLogger = customLogger;
_emailSenderService = emailSenderService;
_weatherRepository = weatherRepository;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecastModel> Get()
{
_customLogger.Log("Started function GetWeatherForecast");
WeatherForecastModel[] results = _weatherRepository.GetRandomSample();
_customLogger.Log("Started sending mail.");
_emailSenderService.SendMail("some.mail#domain.com", $"Summary of the first result: {results[0].Summary}");
_customLogger.Log("Ended sending mail.");
_customLogger.Log("Ended function GetWeatherForecast");
return results;
}
}
Now, with the whole implementation, in place, I don't like it. Like visually. I do not want to see logging and email sending logic inside of my controller. This is the fundamentaly issue, I'm trying to solve with this question. I could (I implemented it for testing) inject logger inside the EmailSenderService and inside the WeatherRepository and log there, howerver, I do not like that either. I do not want to see logging inside of my logic. So, I thought about something I called LogAwareEmailSenderService. Here is impelementation:
public class LogAwareEmailSenderService : IEmailSenderService
{
private readonly ICustomLogger _customLogger;
private readonly IEmailSenderService _emailSenderService;
public LogAwareEmailSenderService(ICustomLogger customLogger, IEmailSenderService emailSenderService)
{
_customLogger = customLogger;
_emailSenderService = emailSenderService;
}
public void SendMail(string email, string text)
{
_customLogger.Log($"Started sending email to: {email}, containing text: {text}");
_emailSenderService.SendMail(email, text);
_customLogger.Log($"Done sending email to: {email}, containing text: {text}");
}
}
Basically, what I'm trying to achieve, is: Take my original EmailSenderService, then inject it into my LogAwareEmailSenderService. The idea is, that now, I should be able to inject this LogAwareEmailSenderService into my controller without the need to change my controller at all (just remove my previous logging logic), right? And If I achieve this, I can go on and continue, to make something like LogAndEmailAwareWeatherRepository, that will inject LogAwareEmailSenderService and instead of sending mail and logging function start inside of the controller. I will just call LogAndEmailAwareWeatherRepository, that will log these things, and send the email, resulting in controller only calling the important, _weatherRepository.GetRandomSample() -- This call will do the logging and sending mail, using the previously described abstractions.
However, in the first place, I am unable to inject the EmailSenderService inside the LogAwareEmailSenderService. I want them both to be scoped. I trid this approach (in my Program.cs):
builder.Services.AddScoped<IEmailSenderService, EmailSenderService>();
builder.Services.AddScoped<IEmailSenderService, LogAwareEmailSenderService>();
however I got circular dependency error:
'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: DependencyInjectionExample.Services.EmailSenderService.IEmailSenderService Lifetime: Scoped ImplementationType: DependencyInjectionExample.Services.EmailSenderService.LogAwareEmailSenderService': A circular dependency was detected for the service of type 'DependencyInjectionExample.Services.EmailSenderService.IEmailSenderService'.
DependencyInjectionExample.Services.EmailSenderService.IEmailSenderService(DependencyInjectionExample.Services.EmailSenderService.LogAwareEmailSenderService) -> DependencyInjectionExample.Services.EmailSenderService.IEmailSenderService)'
So, I got some questions:
Am I going about this right? Like, is what I described above, the normal approach to things?
Where should I put my Logging logic? When doing this, I also thought about caching things, meaning, that I would have something like CacheAwareWeatherRepository, that would only care about the caching implementation and then call the WeatherRepository to get data and return them, while caching them.
How to implement my solution?
I still don't understand some parts of dependecy injection, are there any articles/books that helped you personally understand it?
If you've got here, thank you, I know it is long, however I wanted to describe my problem, possible solutions, and questions clearly.
If you have any questions, about anything, please feel free to ask me in comments, or email me (if it's long question) to dibla.tomas#email.cz. I would really like to get to the bottom of this.
PS: This is not about implementation of bussiness logic, or anything like this, this is only for getting data, logging it, caching it and doing abstractions above data access. I implemented this, with idea that you would have one interface and then layers of abstractions. One for getting the actual data (fAb), One for logging the fact (sAb) implementing fAb, One for caching data (tAb) implementing sAb, One for logging the fact of caching (qAb) implementing tAb. And so on.
Am I going about this right? Like, is what I described above, the normal approach to things?
There's not a right/wrong, but what you're describing is an accepted pattern, called the decorator pattern. One service adds behaviors around another one while implementing the same interface.
Where should I put my Logging logic?
Depends on what you mean by "logging logic." The true logic of your logging (opening files and writing to them, e.g.) is already abstracted away behind the logger interface, as it should be.
If you like to have generic messages logged every time a public method is entered or exited, then you can do that with an aspect-oriented Fody Weaver to avoid repetitive code.
The lines of code that decide what to output as a log message, on the other hand, are mostly going to be specific to your implementation. The most useful diagnostic messages are probably going to be ones that need to know contextual information about your specific implementation, and that code needs to be embedded within the implementation code itself. The fact that you "visually don't want to see" calls to the logging service in your controller code is something you should get over. Diagnostic logging is a cross-cutting concern: a responsibility inherent to every class regardless of what their "single responsibility" is supposed to be.
How to implement my solution?
The DI registration method can take a delegate that lets you be more specific about how the type is resolved.
builder.Services.AddScoped<EmailSenderService>(); // allow the next line to work
builder.Services.AddScoped<IEmailSenderService>(p => new LogAwareEmailSenderService(
p.GetRequiredService<ICustomLoggerService>(),
p.GetRequiredService<EmailSenderService>()));
I still don't understand some parts of dependecy injection, are there any articles/books that helped you personally understand it?
Technically not the sort of question we're supposed to be asking on StackOverflow, but I learned from Mark Seeman's Dependency Injection in .NET (affiliate link). It's kind of old now, so library-specific details are outdated, but the principles are enduring.
I thought it might be worth mentioning the Scrutor library which lets you easily specify the decoration setup. For example, you could have:
builder.Services.AddScoped<IEmailSenderService, EmailSenderService>();
builder.Services.Decorate<IEmailSenderService, LogAwareEmailSenderService>();
Edit: the Decorator pattern is a great way to honour Single Responsibility while enabling the Open/Closed principle: you're able to add new decorators to extend the capabilities of your codebase without updating the existing classes.
However, it comes with the cost of a somewhat more involved setup. The Scrutor library takes care of the decoration so that you don't need to manually code how the services are composed. If you don't have many decorators, or you don't have many levels of decoration, then that advantage might not be useful to you.
The scanning capability is not related to the decorator setup: it's simply another capability that allows one to add classes to the service collection without manually the classes (sort of auto-discovery). You can do this via reflection.
Here's an example of the decorator setup if you also had caching:
builder.Services.AddScoped<IWeatherRepository, WeatherRepository>();
builder.Services.Decorate<IWeatherRepository, DiagnosticsWeatherRepositoryDecorator>();
builder.Services.Decorate<IWeatherRepository, CachedWeatherRepositoryDecorator>();
You could do this manually:
builder.Services.AddScoped<WeatherRepository>();
builder.Services.AddScoped(provider => new DiagnosticsWeatherRepositoryDecorator(provider.GetRequiredService<WeatherRepository>()));
builder.Services.AddScoped<IWeatherRepository>(provider => new CachedWeatherRepositoryDecorator(provider.GetRequiredService<DiagnosticsWeatherRepositoryDecorator>)));
It becomes a bit more involved if the constructors take other parameters. It's completely possible, but really verbose.
I thought I'd also share some advice regarding your 5th question; my experience of dependency injection frameworks is that:
The frameworks are simply a key-value map; if a class needs interface A, then create class B.
Sometimes it's just a key; that happens when you only need to let the framework know that class C exists.
Whenever a class needs to be created, the map of all classes and all interface/class to class mappings are consulted, and whatever the map lists is created.
It seems like you're aware, but these frameworks also manage the lifetime of the objects it creates. For example, a scoped lifetime is linked to the duration of the http request. This means that an IDisposible object created by the framework, will be deposed once the request ends.
In your case:
builder.Services.AddScoped<IEmailSenderService, EmailSenderService>();
builder.Services.AddScoped<IEmailSenderService, LogAwareEmailSenderService>();
The second statement actually overwrites the mapping of the first statement: you can only have one key (in this case IEmailSenderService) in the collection. So when the framework tried to create LogAwareEmailSenderService it saw that LogAwareEmailSenderService needs an IEmailSenderService but the only one it knows about is LogAwareEmailSenderService.
This is why we only list the interface once when we manually tied up the decorated classes. When the Scrutor library is used, it re-maps the types allowing you to list the interface multiple times.
I am developing an Asp.net MVC application, and I have created an error handling system that forces me to create the following code per function in my BLL.
try
{
...
_unitOfWork.Save(nameof(Function));
}
catch
{
if (rollbackTo != null)
{
_unitOfWork.RollbackToSave(rollbackTo);
}
else
{
_unitOfWork.Rollback();
}
throw;
}
this basically allows me to manage my transactions per request, and manage the transaction's error handling without my Controllers knowing about the actual way that this is being done - it only allows it to decide whether or not the transaction will continue (rollbackTo parameter)
What I am wondering is, is there a way for me not to have to write this piece of code over and over? I thought about just throwing an exception, and then handle it in my pipeline - but since I need to return a valueable response to the user, and not just a 500 code - this isn't really an option. I thought about maybe creating a base class that calls and abstract method - and implementing it per function - but that won't work either, since the parameters can change. Any Ideas?
Yes, this is fairly standard.
For example, in the base class
public void DoSomethingAndRollbackThenThrow(Action<IUnitOfWork> action)
{
try
{
...
action(_unitOfWork);
}
catch
{
if (rollbackTo != null)
{
_unitOfWork.RollbackToSave(rollbackTo);
}
else
{
_unitOfWork.Rollback();
}
throw;
}
}
And then you can call it from derived class like so
public void DoSomethingSpecific()
{
base.DoSomethingAndRollbackThenThrow(unitOfWork => {
_unitOfWork.Save(nameof(Function));
});
}
You can use an AOP(Aspect Oriented Programming) framework.
You can "weave" some functionalities to your methods with just implementing for one time and adding some attributes.
More about AOP:
https://en.wikipedia.org/wiki/Aspect-oriented_programming
An easy-to-use open source AOP Framework:
https://github.com/AntyaDev/KingAOP
There are also a bunch of alternatives (both commercial and open source). Google may give you good results about alternatives.
In principal this looks like a simple job, but I wonder if anyone can take me through the basic steps?
I have an application API, implemented as a C# class library project in the application solution. People can thus write their own conventional .Net applications using this API by referencing the dll directly.
I now need to make exactly the same functionality available as a web service so applications can be written to remotely access the same API over http. Ideally I would just like to tag the API classes and methods with appropriate web service attributes, but I suspect there is more to it than that. I also must have the API dll continue to work as an API for desktop applications as it does at present.
Is this do-able? If so, what are the steps I need to take?
The web service can be composed mostly of wrapper methods. Take the simple case...
If your API method in the assembly is
public void DoFoo(string bar)
Then your web API method (your choice of implementation, such as WebAPI, ASMX web service, etc) will look like
public void DoFoo(string bar) {
// ... initialization or validation
try {
refToDll.DoFoo(bar);
} catch (Exception e) {
// implementation specific return of error.
}
}
If you have mostly static methods or those taking primitive types, that becomes more easy. If your API has types defined, this becomes harder. You will need to change the type signature and reimplement methods. Without your API it would be difficult to make specific suggestions. However, there are several options. If you had
public class BazClass {
public string GetScore() {
return scores.Sum();
}
}
You basically need to ensure that the remote side (the web API) can reconstruct the context from your client side. You have to pass in a serializable instance or other representation of BazClass and let the remote API work on it. It just doesn't exist otherwise. You could also create a bunch of methods that store state on the server and you work with a "handle" on the client side, or object reference, but that will have to be a design decision (just look at interop with native libraries, and handles, and translate to cross network). Example:
public string BazGetScore(Transport.BazClass baz) {
// Depending on the framework and class (all public getters/setters)?
// your framework may allow for transparent serialization
BazClass bazReal = bazFactory(baz);
string score = bazReal.GetScore();
return score;
}
How much of your source API is based on interfaces? This may make the creation of a Proxy class much more transparent to your end user. If you have
public class Baz : IBaz { ... }
Then you can create a Proxy class that acts just like an IBaz but calls the remote API instead of acting locally. Depending on your framework and tooling, this may be able to be facilitated by the tools.
namespace RemoteAPIProxy {
public class Baz : IBaz {
public string GetScore() {
// initialization of network, API, etc
Transport.Baz baz = new Transport.Baz.From(this);
string score = CallRemoteAPI("BazGetScore", baz);
return score;
}
}
}
In summary, you may have to make some intermediate classes depending on if you need to support state, non-public methods, or full scope. The "how" can mostly be considered just another wrapper, but you need to be conscious of how you get your local state over the wire and into the context of the remote API. Use interfaces, serialization helpers, and lightweight transport objects for state to help with the "glue". Remember, the only "I" in "API" is for "Interface", so you might want to make sure you have some. Good luck!
I have a situation in a project I am currently working on at work that has left my mind restless the entire weekend. First, I need to explain my scenario, and the possible solutions I have considered.
I am writing a composite WCF service that will be aggregating a large amount of external API's . These API's are arbitrary and their existence is all that is needed for this explanation.
These services can be added and removed throughout the period of development. My WCF service should be able to consume the services using several methods (REST,SOAP,etc). For this example, I am focusing on communicating with the external APIS by manually creating the requests in code.
For example, we might have two API's ServiceX and ServiceY.
ServiceX is consumed by POST ing a web request with the data in the request body specifically.
ServiceY is consumed by POST ing a web request with the data appended to the URL(Yes...I know this should be a GET, but I didn't write the external API, so don't lecture me about it.)
In order to avoid redundant, duplicate code, I have wrapped the web requests using the command pattern, and am using a factory to build the requests.
For ServiceX, the data needs to be encoded and put into the request body, as oppose to ServiceY where the data needs to be iterated over and placed on the Post string.
I have a class structure like the following:
public abstract class PostCommandFactory
{
public ICommand CreateCommand();
}
public class UrlPostCommandFactory:PostCommandFactory
{
public ICommand CreateCommand()
{
//Initialize Command Object Here
}
}
public class BodyPostCommandFactory:PostCommandFactory
{
public ICommand CreateCommand()
{
//Initialize Command Object Here
}
}
public interface ICommand
{
string Invoke();
}
public class UrlPostCommand:ICommand
{
public string Invoke()
{
//Make URL Post Request
}
}
public class BodyPostCommand:ICommand
{
public string Invoke()
{
//Make Request Body Post Request
}
}
This allows me to cleanly separate the way that I am binding data to the request when they need to be send out, and essentially, I can also add additional classes to handle GET requests. I am not sure if this is a good use of these patterns. I am thinking an alternative might be using the Strategy pattern and specifying strategy objects for the different Request methods I might need to use. Such as the following:
public class RequestBodyPostStrategy:IPostStrategy
{
public string Invoke()
{
//Make Request Body POST here
}
}
public class UrlPostStrategy:IPostStrategy
{
public string Invoke()
{
//Make URL POST here
}
}
public interface IPostStrategy
{
string Invoke();
}
public class PostContext
{
pubic List<IPostStrategy> _strategies;
public IPostStrategy _strategy;
public PostContext()
{
_strategies = new List<IPostStrategy>();
}
public void AddStrategy(IPostStrategy strategy)
{
_strategies.Add(strategy);
}
public void SetStrategy(IPostStrategy strategy)
{
_strategy = strategy;
}
public void Execute()
{
_strategy.Invoke();
}
}
I am starting to think the Strategy pattern may be the cleaner solution.
Any thoughts?
I would use both.
Command is best practice for encapsulating requests and hiding implementation details. You should probably use it even if you only have one kind of request, as it promotes cleaner code. Essentially it's good practice to consider "what is the absolute minimum the rest of my code needs to know about how requests are executed and handled", which will lead you to the Command pattern.
Strategy is basically configuring your system at runtime with a general, consitent way to handle some ascpect of the operation, in this case generating the requests. This is also a good practice for testing, as you can substitute a test implementation of your strategy/request factory to fake actual connections etc.
Based on the examples for Command and Strategy that you have given, the Command pattern example looks exactly like a Strategy which I guess lead you to Strategy. I would also go with Strategy but would like to add that there's more to Command pattern than what you have included in the example. You should ask yourself questions like:
Do these Commands need to be stored and should be executed later point in time?
Is there a Invoker that needs to invoke these commands without caring about Command internals?
Would you want to have functionality of grouping different Commands together and executing them?
If this is the case then you should choose Command Pattern.
I'm implementing a secure WCF service. Authentication is done using username / password or Windows credentials. The service is hosted in a Windows Service process. Now, I'm trying to find out the best way to implement authorization for each service operation.
For example, consider the following method:
public EntityInfo GetEntityInfo(string entityId);
As you may know, in WCF, there is an OperationContext object from which you can retrieve the security credentials passed in by the caller/client. Now,authentication would have already finished by the time the first line in the method is called. However, how do we implement authorization if the decision depends on the input data itself? For example, in the above case, say 'admin' users(whose permissions etc are stored in a database), are allowed to get entity info, and other users should not be allowed... where do we put the authorization checks?
Say we put it in the first line of the method like so:
CheckAccessPermission(PermissionType.GetEntity, user, entityId) //user is pulled from the current OperationContext
Now, there are a couple of questions:
Do we validate the entityId (for example check null / empty value etc) BEFORE the authorization check or INSIDE the authorization check? In other words, if authorization checks should be included in every method, is that a good pattern? Which should happen first - argument validation or authorization?
How do we unit test a WCF service when authorization checks are all over the place like this, and we don't have an OperationContext in the unit test!? (Assuming I'm tryin to test this service class implementation directly without any of the WCF setup).
Any ideas guys?
For question 1, it's best to perform authorization first. That way, you don't leak validation error messages back to unauthorized users.
BTW, instead of using a home-grown authentication method (which I assume is what your CheckAccessPermission is), you might be able to hook up to WCF's out-of-the-box support for ASP.NET role providers. Once this is done, you perform authorization via OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.IsInRole(). The PrimaryIdentity is an IPrincipal.
About question #2, I would do this using Dependency Injection and set up your service implementation something like this:
class MyService : IMyService
{
public MyService() : this(new UserAuthorization()) { }
public MyService(IAuthorization auth) { _auth = auth; }
private IAuthorization _auth;
public EntityInfo GetEntityInfo(string entityId)
{
_auth.CheckAccessPermission(PermissionType.GetEntity,
user, entityId);
//Get the entity info
}
}
Note that IAuthorization is an interface that you would define.
Because you are going to be testing the service type directly (that is, without running it inside the WCF hosting framework) you simply set up your service to use a dummy IAuthorization type that allows all calls. However, an even BETTER test is to mock the IAuthorization and test that it is called when and with the parameters that you expect. This allows you to test that your calls to the authorization methods are valid, along with the method itself.
Separating the authorization into it's own type also allows you to more easily test that it is correct in isolation. In my (albeit limited) experience, using DI "patterns" give you vastly better separation of concerns and testability in your types as well as leading to a cleaner interface (this is obviously open to debate).
My preferred mocking framework is RhinoMocks which is free and has very nice fluent interface but there are lots of others out there. If you'd like to know more about DI here are some good primers and .Net frameworks:
Martin Fowler on DI
Jeremy Miller on DI
Scott Hanselman's List of DI Containers
My personal favorite DI container: The Castle Project Windsor Container
For question 1, absolutely do authorization first. No code (within your control) should execute before authorization to maintain the tightest security. Paul's example above is excellent.
For question 2, you could handle this by subclassing your concrete service implementation. Make the true business logic implementation an abstract class with an abstract "CheckPermissions" method as you mention above. Then create 2 subclasses, one for WCF use, and one (very isolated in a non deployed DLL) which returns true (or whatever you'd like it to do in your unit testing).
Example (note, these shouldn't be in the same file or even DLL though!):
public abstract class MyServiceImpl
{
public void MyMethod(string entityId)
{
CheckPermissions(entityId);
//move along...
}
protected abstract bool CheckPermissions(string entityId);
}
public class MyServiceUnitTest
{
private bool CheckPermissions(string entityId)
{
return true;
}
}
public class MyServiceMyAuth
{
private bool CheckPermissions(string entityId)
{
//do some custom authentication
return true;
}
}
Then your WCF deployment uses the class "MyServiceMyAuth", and you do your unit testing against the other.