We are using LsaCallAuthenticationPackage with KERB_RETRIEVE_TKT_REQUEST of type KerbRetrieveEncodedTicketMessage.
We impersonate a Windows identity and then use LsaCallAuthenticationPackage to get the tickets.
We are able to retrieve tickets (tgt and service tickets) when using unconstrained delegation. When we try constrained delegation, the call to LsaCallAuthenticationPackage fails with: LsaStatus 2148074254: A specified logon session does not exist. It may already have been terminated
Our service receives the initial windows identity via Integrated Windows Authentication.
We have checked and rechecked the constrained delegation configuration and the SPNs ... all seem to be fine.
We have observed that with IWA, the WindowsIdentity's impersonation level changes from Delegation to Impersonation as soon as the service account is set to use constrained delegation (this may or may not be related to our problem). We are running a non-IIS hosted WCF web service which receives the identity.
We are wondering if there is some difference in the setup of the KERB_RETRIEVE_TKT_REQUEST that must be done in order to retrieve the tickets when using constrained delegation.
Alternatively, perhaps there is some WCF setup that needs to be done differently.
Thanks,
Related
I have read about various implementations of authentication and authorization for WCF, starting from reusing some built in .NET and WCF features and ending with completely custom implementations.
But there are so many factors to take into account, so I'm confused about how to implement it for my intranet business application project.
Here is what I need:
- WCF .NET 4.5 services will be hosted in IIS 7 or newer.
Most probably, ASP.NET compatibility will be disabled.
Protocol will be HTTP with BasicHttpBinding, but it might need binary serialization to minimize traffic.
WCF method will receive a custom session ID which will be checked against a user session object in a database. No .NET sessions are allowed in this project.
After receiving the ID, the service will read the corresponding user data (including authorization flags to see if the user is allowed to execute the current operation) and validate it. If data is invalid, an exception will be thrown and the WCF operation won't be executed. If validation succeeds, the identity of the user will be stored in a current operation context (and also current thread principal) so it can be accessed by various components during the WCF operation execution.
All the authentication&authorization should be done transparently before the execution of the WCF operation - without additional efforts from programmers who will create the WCF methods.
I need access to the WCF operation name being executed, when I perform the auth validations, so I can throw an exception if the user does not have permissions to execute the operation.
testers will use SoapUI, so they'll need to be able to pass the session ID through standard SOAP or HTTP headers.
Which would be the most straightforward way to implement my auth routines? Should I use a custom binding? Custom behavior? Some kind of a built-in request event handler (which one exactly, and will they work if ASP.NET compatibility is disabled)? Authorization policy (seems a bit overkill because I won't be using most of its built-in features anyway)? Something else?
You can try making use of Message Inspectors. Your session ID can be passed like a token through SOAP or HTTP Headers and will be inspected by WCF through your defined behavior before it executes the actual service operation.
You can check the articles here and here, particularly focusing on the IDispatchMessageInspector interface which offers the "AfterReceiveRequest" and "BeforeReceiveReply" methods.
Our application architecture is as follows:
1) WCF service acts as a facade layer and sits on top of Service, Business Logic and Data Access layer
2) Every client, be it an MVC/ASP.NET, or any other type of application has a ClientTag that first needs to be authenticated and issued an "access token". This token is then passed by the client with every message into the Facade layer
3) The system will be hosted on Windows Azure
This would have been easy to implement with WCF sessions like so:
1) Client initiates a call to WCF to get the token (Client to WCF Session is established, thus every subsequent communication is part of the same "conversation")
2) WCF authenticates the ClientTag, issues the token, and stores it as a local variable
3) Client stores the token in it's own Session and pass it to WCF with every request
Where it breaks down is the fact that Azure (due to its high-availability/load-balancing nature) doesn't support WCF sessions. So, the questions is how do we implement this.
One solution is to use AppFabric caching to imitate session state in WCF layer. We would store the Access Token there and then validate it against what the client passes in. The problem with this is that there is no concurrency between client and WCF. So, we would have to advance WCF session timeout on every request from the same client but we'd want to avoid updating the cache on every request (it could be hundreds/sec).
Any suggestions? Has anyone implemented anything similar to this on Azure. Any feedback would be greatly appreciated.
P.S. It's not only authentication that would happen on the server, but also custom authorization for each client. (Some client might have access to some functions, and others might not).
Thanks!
I'm in the middle of implementing something directly similar to this, but using OAuth 2.0 as the authentication architecture through ACS.
The model I'm following is shamelessly stolen copied from an MSDN sample here: https://connect.microsoft.com/site1168/Downloads/DownloadDetails.aspx?DownloadID=35417. This assumes the client has a user interface, so the user can present some kind of username and password either directly or through some third-party identity provider.
The advantage of this approach is that the WCF layer doesn't need to use any kind of session state, so there's no tedious mucking about with machine keys or whatnot. You'll still get something that can be mapped to an IPrincipal, however, so if you want you can create a custom RoleProvider and use declarative roles in the usual way.
Note the sample uses old-school ASP.NET, and has a dependency on an opaque (and possibly rather buggy) assembly Microsoft.IdentityModel.Protocols.Oauth. And, unless I'm missing something, I've not seen this released anywhere else (e.g. as part of Windows Identity Foundation) so I suspect it's rather new.
An alternative approach could again be to use ACS, this time to authenticate a SAML token, again following the OAuth 2.0 protocols. Details and sample code is here: http://msdn.microsoft.com/en-us/library/windowsazure/hh127795.aspx. That may be better suited to a system with no UI.
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...
I have a WCF self-hosted as a Windows Service.
When I start the service (under the NETWORK_SERVICE account), I can consume the service from my ASP.NET application on a different server.
However, the business rules have changed. Now I need to run the service under my own account. I am able to stop the service, and start it again under my account. No problem there.
Until I try to consume the service from my ASP.NET application on the other service. I get:
A call to SSPI failed, see inner exception
I'm relatively certain there's something I need to do security wise to eliminate this error, being new to all this I just don't know what.
Any help is greatly appreciated.
Thanks,
Jason
Usually this is a sign of a missing or misconfigured SPN, which gets in the way when you're using windows authentication (at the transport or message level) and Kerberos is being negotiated.
Notice that how/when the error manifests itself might depend on the way the hostname (or IP address) of the service host is used in the URL used by the client, since WCF will try, by default, to deduce the right SPN to use based on the URL information, unless you explicitly override it by setting the endpoint identity.
So likely all you need to do is register an SPN (using setspn.exe) for your new service and make sure your client uses an appropriate identity.
There's some more extra information on how WCF uses service identities here, here and here.
I have a web project that has Anonymous access and Integrated Windows authentication enabled. I built a WCF Data Service and since it allows only one authentication, I enabled Integrated authentication on the service. I am able to view the service in browser. However when I try to query the service for any Entity, it gives me Forbidden error. I tried to enable Anonymous access on service too, but it does not work.
Do I need to give it some other access or it is not possible to enable one authentication on the service itself keeping the project virtual directory as Anonymous and Integrated.
Update: I do no have any operations in my Data Service. For the entities, I have already set the "All" permission on all entities.
Only one authentication method is permitted on a WCF Data Service.
If you choose to go the Integrated Security route then you need to set the credentials after constructing the DataServiceContext.
Something like this would work for using the current user's Windows identity.
employeeEntities = new EmployeeDataService.EmployeeEntities(new Uri("http://.../employeedata.svc"));
employeeEntities.Credentials = CredentialCache.DefaultCredentials;