Problem with WCF Ria Services RequiresRole attribute - roles

I have a User class that implemented the IUser interface and is used in the AuthenticationService of my WCF RIA app.
Whenever I apply the RequiresRole attribute to one of my operations I get Access to the operation is denied error even though WebContext.User.IsInRole("Managers") on the client side returns true.
Does anyone know why I get this error?
Thanks.

The reason WebContext.User.IsInRole returns true because the IUser has a property Roles.
This property is set with the user's roles by the server at authentication/user-load time.
The result is that while the client has no access or knowledge on the persistent storage / server entities etc. of the roles in the server, it still has the primitive info (role names) that was rather provided to him by the server.

Related

ASP.NET Core - Conditionally available dependencies

I have a written a simple ASP.NET Core service which provides information about the current user (derived from the User claims). I have another service which provides a user-specific view of a multi-tenant database.
There are some situations where I'd like this database view service to be injected into a controller, but of course I don't know if the user will have successfully authenticated or not, so I won't be able to instantiate it.
Is there an established pattern I should follow for this kind of situation?
Obviously I could throw an exception, but this'd result in a 500 error being returned where it feels like it should be the role of a controller to deem whether an operation can / cannot continue without this service being available. Or should I just have a service that boxes the value and have it be null if it couldn't be instantiated for whatever reason?
Thanks.

Architecture advice needed for WCF services

I'm currently working on a backend infrastructure and I could need some advice.
First, here is the current global architecture:
I have WCF services hosted in IIS
I have multiples databases hosted on SQL Server. One ClientData database per client and one global MasterDatabase.
MasterDatabase contains a mapping of credentials associated to a connection string. That database allows me to use the appropriate ClientData database (via Entity Framework) depending on the credentials provided.
I'm using Basic Auth over SSL.
Credentials verification are done in overridden method checkAccessCore() in my ServiceAuthorizationManager subclass. Inside that method, I fetch MasterDatabase, ensure credentials are correct (password are saved in DB using Bcrypt) and retrieve the connection string.
Once the connection string is retrieved, I create an instance of my class CustomIdentity that inherits from GenericIdentity. Using that instance I can then set the Thread.CurrentPrincipal property.
Each WCF service implementation retrieves the connection string from the CustomPrincipal in order to fetch data from the appropriate ClientData database.
My questions/thoughts are the following:
If I decide to use concurrency in my WCF services, how will I handle that due to the fact that CheckAccessCore is a method of a WCF extension that force concurrent operations to run sequentially?
http://support.microsoft.com/kb/KbView/2907010
This means that all my call will be enqueued and blocked at the checkAccessCore level.
Overriding checkAccessCore is the best way I found to intercept calls early in the call stack in order to verify user credentials.
Should I use a different way to transport the client connection string other than over the custom identity? Is it secure?
If I use concurrency, I guess the identity set into the CustomPrincipal will be overridden. If yes, how to handle that?

Accessing user name in IDispatchMessageInspector

I've implemented custom logging logic for WCF service by using IDispatchMessageInspector.
I'm logging entire SOAP request/response in the database by utilizing both AfterReceiveRequest and BeforeSendReply.
I'm using claims-based authentication which works without any issues.
However, when I attempt to access Thread.CurrentPrincipal.Identity.Name or ClaimsPrincipal.Current.Identity.Name, I get empty string always (identity is not set, thus name is blank).
Is there a way to access the identity in any way from IDispatchMessageInspector?
Thank you!
If your claim-based authentication is working, you could add the user to your claimset.
You can access your ClaimSet in a static way:
ReadOnlyCollection<ClaimSet> claimSets = ServiceSecurityContext.Current.AuthorizationContext;`
The other possibility is adding a ServiceAuthorizationManager to your service, register it in your configuration and access your ClaimSet from this class.
Hope this helps

SecurityContext.Current not working, nullexception

im using a WCF service with the users and roles being kept in the database. In my service im trying to identify whose calling the service. So i type in my WCF service
string user = ServiceSecurityContext.Current.PrimaryIdentity.Name;
but i get i nullexception object not sent to an reference, ive tried googleing it all day but cant seem to find whats wrong. Any suggestions ?
"What's wrong" is that ServiceSecurityContext.Current is returning null rather than an instance of ServiceSecurityContext.
One scenario where this occurs is if the binding is configured to use Message security with MessageCredentialType set to None.
However, I'm not aware of any comprehensive documentation listing every scenario where ServiceSecurityContext.Current can be null: as the security context is established in the channel stack it is something which depends on the specific binding configuration and security providers in use. It could also, I imagine, be affected by custom Behaviors which fiddle with message properties.
Having said that, unless you have custom code inserted into the channel stack, it is probably a safe assumption that this will only occur in cases where the binding does not require any client authentication. You should check first of all that you are using a binding configuration which will auhenticate the client and provide the kind of user name IIdentity you are expecting.

WCF Authenticate Client with database

I have a WCF service that supposed to provide service to several clients.
The WCF will have a Data-Access-Layer that will communicate with the database.
This is part of my design idea : My Design
As you can see - each client will connect to the 1st WCF service for pulling information (get product, update product), and also to the 2nd WCF service in a pub\sub manner, so it would be able to receive notifications about different things it wants.
I have a table in the database for 'Users' with all the users in the system.
(there is an administrator, a normal user and a technician).
My question is - how do I do the 'logging' in from the client to the database ?
My current idea - have a function in the services called 'Connect ( username, password )' and when a client connects - it will pass the username and password to be authenticated in the database, and only if authenticated - the client will start sending commands.
Problem with this is - anyone can write his own client that connects to my service and runs other functions without authenticating. I can solve this by saving in the service whether or not the client has authenticated.
But is there a better solution that just having a 'Connect' function in the service ?
Hope there is something simple yet effective.
You should create a custom user name and password validator that derives from the UserNamePasswordValidator abstract class and implements the Validate() method. Then you can validate the provided user name and password however you want. To learn more about setting this up, read this article.