WCF - How to design service authorization per operation OperationContract - c#

My task is to put an authorization policy to existing / legacy wcf services. Currently there is no authorization in the system. Basichttp based custom binding is being used to handle security. ( The client is sending username / pwd in encrypted form and on the server side, database check is performed upon receiving request. At this point an expirable token is generated in and put to server memory for further security checks) Moral of the story, everything is implemented in a custom way (security features of the framework like STS, certificates and etc. are not utilized) In the service layer no authentication check is done according to client identity. Theoretically, every client can perform every operation as long as he /she has a valid username / pwd pair.
As I said, my task is to implement an authorization policy on this legacy system.
I am relatively new to wcf and my feeling is that authentication and authorization is VERY TIGHTLY COUPLED in wcf.
It seems that there are various alternatives ( http://msdn.microsoft.com/en-us/library/ff648151.aspx ) like :
*Using the ASP.NET Role Manager for role authorization,
*using the SQL Server role provider for role authorization,
and etc.
I feel that custom authorization policy would be the most suitable alternative for me but the custom samples
http://msdn.microsoft.com/en-us/library/ms731774(v=vs.110).aspx also seem to be mixing authentication policy with authorization policy. I could not find a working good sample that implements a custom authorization without any special authentication policy. As you can guess, in the current legacy system security is handled in a custom way and I can not change that i.e I can not use any ws-* bindings.
What I am thinking as a possible solution is:
1) Create a custom attribute that implements ParameterInspector or MessageInspector
2) Decorate all the existing operationcontracts with this new custom attribute
3) In BeforeCall or AfterReceiveRequest methods, apply the custom authentication logic (This custom logic will most likely be associate users with roles and roles with allowed operations).
Rejecting the request will be by throwing an exception and showing the message appropriately in the client side.
My question is, how elegant is this approach? Considering the other restrictions of the legacy system are there more elegant alternatives? Am I missing some parts or are authentication and authorization really very tightly coupled in wcf?

In the old days, basically you could use declarative programming to decorate each operation implementation with PrincipalPermissionAttribute with role name, then in Web.config you plugin ASP.NET MembershipProvider and RoleProvider etc. And if you want more fine grained policy control, you could write a few IAuthorizationPolicy implementations, as you had already found our in those MSDN references in your question.
So you expect more elegant alternatives, even if your purposed designs might be working. Being elegant:
Adequate security
Least codes
Least complexity in application
Easy to evolve
This article "Authentication and Authorization with ASP.NET Identity 2.0 for WCF Services" might give you some light.
And there exists many articles about the reasons why using Identity 2.0.

I would use an external authorization framework altogether and then apply a MessageInspector. The externalized authorization architecture would be as follows:
Externalized authorization management is about decoupling your business logic from your authorization logic. It's great when building new apps efficiently and it's great when updating legacy apps - especially web services where you can easily intercept a flow. Have a look at Gartner's report on externalized authorization.
For your problem more at hand, I recommend you use XACML, the eXtensible Access Control Markup Language. It's an OASIS standard that provides you with:
a policy language to define policy-based access control authorization
a flexible architecture with the notions of:
a policy enforcement point or PEP which intercepts your flow and protects your WCF services. In your case you should use a PEP that implements a MessageInspector
a policy decision point or PDP which receives the requests from the PEP and produces decisions based on the policies it is configured with.
a request/response scheme which defines how the PEP and PDP talk together.
Here's a diagram that sketches out the way you would want your system:
If you need a .NET PDP, you can get one from Axiomatics (disclaimer: this is the company I work for).
HTH

Related

Is there a way to secure microservice endpoints with Jwt without using an APi Gateway architecture

I am working on a spring-boot microservice application, user management module and The AuditTrail service module to be specific and I am tasked to create and Secure endpoints with jwt and other microservices (which can be .net, Django etc) are to use this token to secure endpoints. i have finished building the user management system but now i'm stuck cause I don't know how to go about validating jwt on other microservice systems and i have been instructed not to use the Api gateway architecture.
I am thinking to expose maybe an api/vi/auth/authenticate endpoint that other microservices can call but I'm not sure if there is a better way. maybe share the jwt secret and algo used to create token with the other microservices and every microservice just validates a token by it self. the later approach involves writing boilerplate code as far as I can see but I don't know if these are my only options and what flaws they might have to see if it is something I am able to manage.
As long as you sign the JWT with an asymmetric algorithm (e.g. RSA ECDSA etc.) can have the auth server save the private key to itself, and only share the public one with the services
do note that if you don't go to the server, you have a risk of a token being revoked and the service not knowing that - so you want to keep the token expiration short
To manage authentication in the microservice ecosystem you need an independent microservice authentication which could be SSO (single sign-on). The best practice and most secure way is using Oath and OpenId for this approach and To not invent the wheel from scratch, you can use some standard production like IdentityServer4 (more complicated but full-featured) of OpenIdDict(more simple) and lots of other, which provide both of authentication and authorization in a secure and standard way for you.
They provide an Access token which is JWT with lots of claims to handle your scenarios easily. Also, they have a standard URL address that exposes their URLs (for example URL/.well-known/openid-configuration which you can see here to see real result ) .
I suggest to implement a serious project following the standards of the industry.

IdentityServer and user management- should those concerns be kept separate?

Since IdentityServer's object is to provide authentication and authorization via implementing OIDC and OAuth2 it makes sense to me that user management (CRUD operations) is done separately, maybe in it's own assembly (these seem like two different concerns).
In a production scenario how do you go about separating these two concerns? I see two general options here:
There is a separate identity proverider (ASP.NET Identity Core) project/solution that exposes an API to create, update and delete user entities within its storage. IdentityServer calls this API when authenticating a user.
The user CRUD action endpoints reside within IdentityServer's host project. IdentityServer has direct access to the DbContext of the identity provider's database and implements all necessary user management operations.
The second approach is obviously the easier to implement, but I think that could mean uneccesary redeployments of the auth server if there are functionality changes regarding to the CRUD user operations.
Also what about functionality like forgotten password, email validation and so on. Where is the proper place for it? With IdentityServer or with the separate IdentityProvider (and IdentityServer calling its API).
I've seen a couple of StackOverflow questions in regard to this, but nowhere could I find a sound sample or good reasoning, everything was vaguely described.
P.S The IdentityProvider will be ASP.NET Identity Core

IdentityServer4 storing users in a database without EF and handling massive Authorization scenarios

I'm building a core mvc application to support several sub applications so they can run on several IIS servers
I don't like using EF much due to the complications of the migration especially in production, therefore I need to write my own User handling mechanism and I'd like to know what are my best options if I need to have a massive role or authorization checks that might reach to thousands of roles. I need to secure stuff like:
APIs
Controllers
Clients or Whole MVC/JS Web Apps and Mobile Devices Clients
User Specific access (ex: User can access his own division data, some with read some with write)
.. and lots of lots of authorization scenarios that will work with (User.IsInRole method or the Authorize Attribute) across this multi-server/domain solution.
I need your guidance on how to achieve this following the best practices.
Regarding not using EF. All the "stores" in IDS4 are abstractions so you can implement your own for each IDS4 entity (rather than using the EF bolt on) and likewise you can implement your own IProfileService and IClaimsService to use whatever backend you'd like.

Identity Server(OAuth2) implementation with integration to legacy systems(Forms Auth, ADFS,AD)

We are currently building a RESTful API(.Net Core, IdentityServer 4, EF6). We have released an MVP version of it.
It also references a WCF service. This WCF service orchestrates all other calls to other internal (Legacy systems) and other integration components.
(Possibly wrong) Overview diagram of the implementation is as follows:
One of the main things we are stuck with is figuring out how to integrate different authentication and authorization systems using Identity Server...
Particularly internal service to service calls. Do we use the same IdentityServer to perform multiple functions?(public consumer authorisation & authentication AND internal service-to-service authorisation).
Traditionally we have used different WCF security configurations (Transport, TransportWithMessageCredentials...and so on), adding Forms, AD, ADFS and Service Accounts. We need to be sure we are making the right calls for making a reusable IdentiyServer implementation.
In short, Our challenge is how do you perform internal service authorization?
Is it good practice to have a central Identity Server implementation that handles both public facing requests and internal (multihop)service-to-service authorization?
Do you recommend splitting and having separate identity servers for internal service-to-service authorization from those that handle public-facing API requests?
Or do we even go further as to split and create a different identity server for each application use case?
Here are my thoughts on a solid implementation plan.
Is it good practice to have a central Identity Server implementation that handles both public facing requests and internal (multihop)service-to-service authorization?
Reasons to have shared implementation:
Simpler Solution
Reasons to have separate implementation:
Different security requirements for external vs. internal users/clients
External Outage wouldn't impact internal users/clients
Recommendation:
In the short term use an implementation that will service both with the goal
to split them out into External and Internal focus areas.
Do you recommend splitting and having separate identity servers for internal service-to-service authorization from those that handle public-facing API requests?
Recommendation:
Long term yes. See above as to why.
Or do we even go further as to split and create a different identity server for each application use case?
Recommendation:
No, creating an separate identity server for each client/use case would be harder to manage in the long term. You would create separate clients for each application/scenario. (i.e. Mobile Client, MVC web site, Internal Server to Internal Server, External API/Service to Internal API/Service [Think of B2B interfaces])
You will want to learn about the client types and how to allow extension grants, which is when a clients credentials to be used when a direct API call needs to call a secondary API as the user.
First off I would say you are going to have to bang your head on the wall a lot.
I think an ideal situation is where you only support one Identity Provider such as Active Directory. Microsoft would have you believe their solution is easy but it is not. That is why if you have to support a legacy Identity provider as well as a new system in parallel you will suffer more.
A secondary solution would be to keep the legacy Identity Provider system and implement the new API through it. I guess it must be a custom solution that is hosted on your own resources. That has the disadvantage to come with no built in capabilities and every new need must be built from scratch.
Honestly if you can isolate the legacy (or remove it) from your new system you will get huge benefits long term for maintenance and malleability.
I would look at code samples before making a decision. Better know deal breakers before spending weeks in any direction.
Here's my point of view for above problem
A Separate Identity Server for internal service
There are more pros in separation of identity server for internal service i.e.
Outage & Configuration changes in future won't affect consumers.
For Testing Purpose, a separate identity server is best if you are trying to support legacy applications
New Server has long term benefits & Security Enhancements.

Authorization & User info in a Service Layer (.NET application)

I am currently working with an enterprise application in a .NET environment (n-layered) and I would like to know the best way to manage authentication / authorization + data filtering in my BussinessLayer (BL). We will use that BL from several interfaces (ASP.NET applications and WebServices) and I think that my ServiceLayer should do the job but I just can't find the best way.
I suppose it could be something like this:
(1) User gets authenticated (ASP.NET web client), perhaps using FormsAuthentication.
(2) ASP .NET code (Controller / CodeBehind) instanciate a Service to get some user case done, passing somehow the 'User'.
(3) Service method checks if 'User' exists (authentication) and his roles (authorization) to verify that he can call that method. If not authenticated or authorized an exception is thrown.
(4) Service uses repositories + other services + whatever it needs to get the job done. If some kind of fine-grain filtering is required (for example the User only has permissions over some projects) the service applies it automatically.
What I want is to get a ServiceLayer isolated from 'the web stuff' (not accesing session...) but who knows the User calling its methods to act correctly. Also I don't know how to match that work with ASP .NET authentication in a good manner...
I am thinking in suministrating the 'User' in the Service ctor, so that its methods have the 'context' they need, could that work?... I would appreciate some indications or existing code snippets on that.
Thank you for your help...
First of all, Authentication and Authorization are two separate things. Your question implies that you already know this, but I just wanted to be explicit about it.
Authentication should happen at the application boundary (e.g. Forms Authentication in a web application).
The default approach is that the Authentication module sets Thread.CurrentPrincipal upon successful authentication.
In general, IPrincipal is the standard basis for modeling user context in .NET. For example, HttpContext.User is an IPrincipal.
In your Domain Model and Data Access modules, you can use Thread.CurrentPrincipal to implement Authorization logic. This allows you to vary Authentication and Authorization independently of each other.
For me, I think it is both simpler, and more extensible if you let the client layers (your website/services) do the authentication and leave the BL to contain just the business logic.
If you need a reference to the current user in the BL, you could consider an interface to 'wrap' some of the user identity information and this could be passed from the various UI layers.

Categories