I am trying to implement role-based authentification to the REST WCF service . I read a lot of information on this theme but didn't got a clear understanding of what I have to do.
I understand how to restrict an access to the service using the [PrincipalPermission] attribute but don't know how to check whether the user belong to the certain role or not.
Therefore I will be very grateful if somebody can direct me to the right way (e.g. make a roadmap what should I do to achive this goal).
Let me describe this situation. I have a remote services which hosted on the server A and ASP.Net MVC client hosted on the server B.
All of these rest services has an access to the database where I can read an information whether the user has access to the service or not.
OK, Tequila, IMO what you really want, based on your description, is a normal, REST WCF service with a Login(ID as string, PWD as string) method that (perhaps) returns a SessionID. This Login() or SessionID() check method would then preceed access to all of your other methods. And since it's a webHTTPBinding -- effectively a stateless web service -- you'll need to check the SessionID or ID/Password before each request is processed.
So the workflow would be something like this:
1) client sends Login() request to host
2) host checks ID/Password against DB, creates SessionID in DB that times out after x hours, forcing new Login(). SessionID is returned in response to client,.
3) In all subsequent requests, client must provide that SessionID. That SessionID would be checked on the DB, returning stored information about the client (Role, name, ID, address ... whatever is useful) before the remainder of the request is processed.
There are methods for authenticating users BEFORE the request gets to your working code (like client authentication using Forms or client certificates (see http://msdn.microsoft.com/en-us/library/ff405740.aspx)). This shifts the Login() / SessionID check to a method executed BEFORE the request hits your main program, but the steps are basically the same.
And since passing ID/Pwd in clear text over the web is a no-no, you'd want to implement SSL on your web service (see http://msdn.microsoft.com/en-us/library/ff650785.aspx)
Everything I've describe is basically platform independent, so if you'll have iOS or Android clients, there's nothing in what I've described that would prohibit those OSs from successfully interacting with your web service.
Good luck.
Related
I have a big system. This system consist of client desktop app and many wcf services. Each of wcf service have it's own logic and isolate it from client code. One of the services is authorization service. It's main task is to authenticate user and let all other services to know what user is logged on without additional stuff. For example, as i think i should at the start of client to make authentification of the user, check it's login and password and next generate some token and use this token in all requests to other services to let any service know what user is working with it. Well, firstly, i wanted to use claims authentification, but it is quite complicated for realization. Now an idea of my algorithm is to generete some kind of token, put it into the header of any request and pass to services. Service will send this token to the authorization service and service will check it.
The question is: is there any more beautiful and more easy for realization algorithm to let any service know which user is now working with him? Or maybe wcf have some standard solution for this problem?
Update 1. I can't use active directory and any windows default authorization mechanism. I have my own database of users, their roles and permissions. I need just to let other services to know the name of the user. I need to write this mechanism once and let other developers to use it in any wcf service of our system. Is it a bad idea to send a login in every request?
Overview of the architecture (unfortunately I am not able to change this in any regard):
.net mvc site that requires authentication, lives on "Machine A"
wcf data service that handles authentication against an "authentication file", lives on "Machine B"
I created a custom principal (inheriting IPrincipal) and custom authorize attribute (inheriting AuthorizeAttribute) to do a couple of unique checks required of this system (similar to checking for roles). Every public controller action, with the exception of those in the "LoginController", have my custom Authorize attribute.
In my controller action to handle login request, which has the "AllowAnonymous" attribute, I post a request to the data service on Machine B and it just hangs. I've debugged the service and I can see that it receives the requests, does its work, and sends a response. The site on Machine A doesn't appear to receive the response.
Here is what I have tried to do so far:
I created a little app on Machine C to post the same data to the data service, the process runs to completion and the app on Machine C receives a response.
I have rolled back to a revision that doesn't contain any of the authentication restrictions, tried posting the same data, still no response received.
I have disabled all the security software I am able to on Machine A to see if the response was being captured by firewall or something, no luck.
If I simulate authentication then other calls to the data service for non-authentication data from the site receive responses and behave as expected.
So if you have any suggestions of other things to try, or if you would like more detail (I unfortunately cannot share code) I will do my best to provide it.
Thanks
The issue here was that there were nested async calls. When i move the async call to the data service out of the async method that was calling it it works just fine.
I have a server-client project written in c#.
I want to change the client side to a web client so we can open it with the browser. So I decided to make a WCF rest service that will replace the server side. The binding that I am using for the service is webHttpBinding.
My problem is with the behavior of the service. The service data (vars etc..) is initialize after every call. If i add the [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
it doesn't change anything. If I use [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)], it works but I guess that the service instance will be the same for every client.
I have a simple html web page that get a username and password from the client and post it to the service. The service check the Login info with the user database and response. My problem is that i can't save the user status as logged in or not because after every post/get method the service is reset.
what should I do?
This is a pretty standard issue you have to deal with when trying to maintain a session over HTTP, which is what webHttpBinding is using. Even if you try to force it to have a session, it won't. RESTful services don't work that way.
A high level overview of what you have to do is have the service create a token it gives the client upon initial authentication (probably to be stored in a cookie), which the client will then send back with each request. The service can then use that token to check if the client is logged into a particular account with each request. You probably want to make tokens expire after a certain duration (might be 1 month, 1 week, 1 day, 10 minutes, depending on your application).
You can find some more information here:
RESTful Authentication
SPA best practices for authentication and session management
Authentication, Authorization and Session Management in Traditional Web Apps and APIs
i need to build this architecture and i need some orientation on "how should i build". I've read many docs and examples but i can't find and figure how to do trying to be efficient and secure:
External app (android app, ios app) where users, after a login, can access to their personal info and manage the account (updating personal data, showing personal documents related to their account and much more). The username / pwd input must be done only 1 time.
A public wcf service will receive their actions and will call to a another internal wcf service. It will work like a 'bridge'.
The internal wcf service will get the request and do the operations needed (logical and db operations). This will return data to the external wcf service and this one to the client (obvious).
UserName/PWD are stored in a database.
WCF services can only be accessed with the correct credentials and are IIS hosted.
So i find many problems/questions:
I don't know HOW and WHERE should I build the AUTH (internal, external, both?). How can i manage a session between wcf services and app clients to avoid sending credentials every time?
The client app needs to send credentials every time? This means every service requires to SELECT the database for checking the username?
SOAP? Rest Services? It doesn't care? (on internal wcf, external wcf, both?).
I need work with asp.NET sessions or i really don't need? I don't see how services that needs username/pwd that are called frequently and repeatedly are efficient without old asp.net sessions.
Thanks for your help and orientation.
Regards!
If someone interested... seems Routing Service seems to fit for my design and can solve my problem after some tests i have done.
I’m building a webservice and having some troubles witch option I should choose. Therefor I was hoping someone could point me in the right direction. I found many articles but none of them have more or less the options then I want.
What I want the webservice to do:
Client should get a WSDL derived from the ASMX file. Within that service there is one unauthenticated webmethod called “Authenticate(string Username, String Password)” that returns a custom AuthenticationSoapHeader. The AuthenticationSoapHeader is exactly and preferably same as the System.Web.Security.FormsAuthenticationTicket class that is used in the webapplication.
http://www.codeproject.com/Articles/4398/Authentication-for-Web-Services-using-SOAP-headers
http://www.codeproject.com/Articles/27365/Authenticate-NET-Web-Service-with-Custom-SOAP-Head
I’m thinking of using the articles above to implement this and changing the username password combination for a ticket that will be encrypted including a datetime stamp to expire the ticket. My questions.
Would this be considered a best practice? If not, what better option do I have.
Is using WSE3 “Microsoft Webservice Enhancement” necessary?
Is WCF a better option if your kinda new to webservices?
The soap requests go over Https SSL and do not need further encryption on the client side. Thank you in advance.
Best regards,
Danny
I can't answer all these questions, but I can answer a few: IMO WCF is all you need as a tool set for this project, based on your description. WCF has a number of different flavors (http, TCP, etc.) and each has several different options for how you implement security.
WCF has options for user/pwd authentication, or you can construct a custom method, or you can construct a Login() function that takes a UserID and Password as parameters, returning a boolean. There are also options that allow you to authenticate BEFORE the main program receives the request. That's what the built-in UserID/Password authentication does.
If you implement SSL on the host, assuming you're using an http-centric binding, you won't need anything on the client side for encryption as the WCF software will take care of that, once you have both the Host and Client software configured properly. In effect, your WCF client app will behave like a browser, handing all the nasty cert stuff under the covers.
WCF also lets you a) run your web service as a stand-alone windows service (called "self hosted"), or b) allows you to configure your web service behind IIS, which has some advantages. WCF will also provide a WSDL for your clients if needed.
There are some other nice things about WCF; if 10,000 concurrent users hit your web service at 8 am on Monday, WCF automatically queues the requests it can't handle, processing them in order as it can. I've slammed our testing web service with numbers like that, and the program never broke down, processing >150 logins and file uploads / second. WCF is also works fine with Java, iOS and Android.