Context:
There are a few threads here on Stack and on Bing that talk about WCF and session sharing with ASP.NET. None satisfy my issue fully. So here goes:
I have an MVC site which also has a few services in the RouteTable under the path "/services". This all works really nice. I can call Controller actions and WCF service methods both.
I have enabled WIF and Federated Authentication with the Windows Azure Access Control Service (ACS). This also works nicely. I can login using Facebook, Google etc. and a session is clearly established on my site. I can call the MVC controller actions and the WCF methods. Inside the body of those the IPrincipal for the current user is set to my current session.
Now I want to be a good boy and use a custom ClaimsAuthenticationManager and a custom ClaimsAuthorizationManager. A weird problem now occurs:
The setup:
For this scenario I am logged in. I have a session. I can confirm this inside of the method bodies of my MVC controller methods and my WCF service methods. This means we can leave the custom ClaimsAuthenticationManager out of this since it is not being touched when I already have a session.
It's the custom ClaimsAuthorizationManager which causes my headache.
When I make a call to the MVC site I am authenticated with my session inside of the ClaimsAuthorizationManager.CheckAccess method AND also inside of the body of my MVC controller actions. So far so good.
The problem:
When I make a call to the WCF services I am NOT authenticated with my session inside of the ClaimsAuthorizationManager.CheckAccess method but I am authenticated (suddenly) as I hit my breakpoint inside of the WCF service method.
This just does not make any sense! It seems my session is not inflated inside of the ClaimsAuthorization manager but further down the pipeline when I hit my own WCF code the session is in place!
How can this be?
Cheers,
Magnus
It might be the Stackoverflow's problem, but when I copied your config into notepad++ I saw some junk characters in the AuthenticationManager type value:.
As the rest of the question goes, do you have <clear /> element before the elements that you show here?
Related
I am new to authentication and authorization concepts. I wrote an authenticate method in my wcf servcice. Methods in wcf service will get called only by authenticated users with specific roles. How does the security context automatically get loaded before each request to wcf service?
Since you are looking to reach the authenticated identity, then the following link should be helpful:
http://msdn.microsoft.com/en-us/library/aa347790.aspx
EDIT: If you want to automate this, you should write a wrapper for your service host (i.e: a class that inherits from ServiceHost) to encapsulate that inside your service host rather than having to write it over and over again.
I'm getting increasingly frustrated with doing the authentication right. Usually I'm using terms that I'm not familiar with so answerers misunderstand my questions. Its not helped bu the fact that this is a case with many implementations.
So now I'm going to try to explain the facts and requirements surrounding my project so that I might get a pointer towards a good solution.
I will have a Database that includes the information I need. Included in this info will be the usernames and salted hash of passwords. This database will be connected to a WCF web service that supplies the data to other front end projects.
One of the front end projects is a asp.net MVC 3 web site that users will use to log in and such. Now the default in such a project is some sort of SQlMembership that is not right in this case as this site is not connected to the database (it might not even be a MSQL database).
Here are implementations that I looked at but couldn't quite figure how to use correctly.
1) Write my own MembershipProvider in the MVC project that would query the WebService for validation. Here I mean that it would just call some methods for all its needs. Not liking it for security issues, client side solution.
2) Validata using a service side MembershipProvider but then I would have to send userName Password with each action and I can't store password for security reasons.
3) Then I discovered something called WCF authenticationService http://msdn.microsoft.com/en-us/library/system.web.applicationservices.authenticationservice.aspx and it seemed to be what I need but I'm having problem understanding how it works. I wan't it to be part of my service but it seems to be a dedicated service. Also its not really explaining how it authenticates (I need to have a custom authentication based on my table, not some default table created for me). Here is a post Should authentication be in a separate service for wcf? with same problem that I'm not sure how got solved.
Can the WCF authentication service be the right tool for me?
Can you answer this for someone who doesn't know asp.net, web or service terminology?
EDIT
Here is one solution that I was hoping for but not sure if exists.
The WCF Service exposes a MembershipProvider, RoleProvider, ProfileProvider that are defined in the service.
In the MVC web.config under membership\providers\add the MembershipProvider is added along with a endpoint towards the service. Same with RoleManager etc.
So when I call MembershipProvider in the MVC project to validate user it automatically calls the service and checks there and when it happens upon a Authorize attribute it as well checks the RoleProvider in the service automatically.
I would however also want to restrict the service calls themselves, even if they are inside a [Authorized] attribute method it might not be so in other clients that reference the web service. Would love if when a call comes from a website the service would automatically have access to the forms.authentication cookie.
I am not clear as to what you want to authenticate exactly, if the user login in, or the user accessing you service. Also, I am not sure how you mean for an answer about WCF Security not to use service terminology nor how you expect to solve this without knowing asp.net. I'll do my best though.
If you are authenticating a user login in, you can implement your own MembershipProvider and have a service request credentials and return the authenticated user.
Once authenticated, you can assign each user a GUID. This GUID is the ID which will travel with each message (encoded in the message header) and validate the user to call the service method.
This doesn't involve transport security, which you should configure if you want your message to be secure over the wire, yet this is a different matter, not involving authentication.
Hope this can somehow help you. I tried to make it the least technical possible and left out anything too complicated. Hope this helps somehow...
My server side contains WCF4 REST services and I'm going to add RIA services for my future SL4 application. Currently I'm doing Basic authentication like this:
var auth = HttpContext.Current.Request.Headers.GetValues("Authorization");
And so on.. You get the idea.. I call this on every request. If header not present or I can't validate UN/Password - I do this:
outgoingResponse.Headers.Add("WWW-Authenticate: Basic realm=\"Secure Area\"");
That got me by so far but I'm refactoring my server side. Implementing IoC for linked services. Created custom ServiceHost, ServiceHostFactory, InstanceProvider and all is well.
Now I need to figure how to properly handle authentication and authorization with WCF so I don't have to manually inspect headers. I do have my custom MembershipProvider so there have to be some method that get's UN/PW to process.
Any pointers? I looked at http://www.codeproject.com/KB/WCF/BasicAuthWCFRest.aspx but it uses RequestInterceptor and it is not available in WCF4. I found ServiceAuthenticationManager and ServiceAuthorizationManager but there is no samples available on how to code and wire those..
Can anybody suggest which way I should go?
Try to use this custom HTTP module. It will add new authentication mode to IIS and it will allow you using custom credentials validation.
I had all types of issues using the built-in annotations for WCF in a recent SOAP/C# project. I know this isn't the best solution, but for my purposes, I enabled basic authentication in IIS7 for my application, disabled anonymous authentication and created Active Directory users for the external clients that would call the web service endpoints. I then changed the application's permissions in IIS7 (it uses file system permissions) to allow a group containing those users.
This moves authentication outside your application, which may not be what you want, but does allow you to easily add users via the IIS7 console and deployment tools that can copy those permissions. The advantage is that you don't have to redeploy your application for permission changes. The disadvantage is you can't do fine grained permission control per function.
Here's the end game... I need a wcf service application with username/password security over ssl. Pretty basic stuff, but I'm at my wit's end trying to make this work. I'm trying to implement the HOWTO guide from microsoft's patterns and practices as listed here:
How to: Use Username Authentication with Transport Security in WCF Calling from Windows Forms.
I've follwed each of the steps exactly... except steps 9 - 12. Those steps implement a custom authentication and authorization class. I'm having errors both with the implmentation of these custom classes and without.
First, without the custom classes... Without the custom authorization and authentication I can compile my wcf project and create the service reference in the console client application. When I run my console application it works, but when I decorate my wcf method to restrict the permissions, it appears that the client is never passing the credentials to the wcf service. If it leave the decoration off the method and step trace into the wcf method, if find that the ServiceSecurityContext.Current.PrimaryIdentity.Name is blank. I'm decorating with:
[PrincipalPermission(SecurityAction.Demand, Role = "sysadmin")]
(and yes, I've used the ASP.net configuration to create the role and the account in that role.)
Second, with the custom classes... If I include the HttpModules element as listed in step 10, I get an error stating that IIS express 7.5 doesn't do it this way any more and I need to move the configuration. With a little bit of hunting I found that I needed to move the item to . But it still complains that is can't reference the module. If I leave out the authentication module and try to just reference the authorization module, I get the same error.
I tried to include the entire web.config, but this editor didn't want to take it all. Suffice it to say that it's exactly like the msdn article except for moving the module tag.
I have written an IIS module (base IHttpModule) that does some custom (OpenAuth) authentication before preceding to my WCF REST service.
I have extended GenericPrincipal to track my user, with an IIdentity, and set
the context.User field to my new principal:
application.context.User = principal
However, when I receive the context in WCF (next step down the pipeline), the User shows up as a "default" unauthenticated WindowsPrincipal (not the GenericPrincipal that i set).
I see lots of stuff on the net about making this work (including aspNetCompatibilityEnabled="true" for serviceHostingEnvironment, playing with OperationContext, etc...) But nothing I have tried seems to work.
Two questions:
Is there a way to get this to work (or am I just barking up the wrong tree here).
What would be the canonical way to do this, or maybe the more "WCF" way to handle this custom authentication.
Thanks
You have to set your principal identity during the authorization phase in WCF. This requires a custom Authorization Policy. I suggest you read this article for more info. I've not tried to do this with a custom HttpModule and REST, but I have successfully done so with the default authentication schemes.