Creating an WCF rest service to accept SAML and authenticate Windows users - c#

I have to create a WCF service that will receive a request with SAML assertion. Internally it needs to get the Windows user (caller user) and then impersonate the next call to an application. This application only supports AD users.
I tried to get a solution but in most cases I got the solution using Azure Service bus and ACS, but in my case I do not have that. My SAML is directly passed to the WCF service (exposed over internet) and this needs to validate the token, get the windows user and then proceed with the next steps using the impersonation of that user.
My ADFS is set up with a Relaying Party (that my middle ware on cloud already is using to authenticate the user).
My questions are:
Do I need to set up a trust with ADFS and WCF service? Are there any
links for that?
The SAML encryption is all encrypted. For decrypting this at y WCF do I need the same certificate which was used during ADFS setup?
Can I use the same relaying party that my middle ware uses in the setting up the trust between my WCF service and ADFS?
Any links that provide a solution would be helpful.
The diagram flow is as shown in the picture:

You can't use WCF to Azure (unless by Azure you mean a VM in Azure). It's all web API.
WCF goes straight to ADFS. This is the WS-Fed active profile e.g. this.
If the SAML token is encrypted in ADFS, it means the RP owns the private key. ADFS (in the RP encryption tab) only has the public key.
Yes, you need a separate ADFS RP for this.

Related

OpenID connect authentication via back channel communication - Getting access token from a .Net WCF service

I'm trying to get information how to authenticate and authorize a user from a backend WCF service using OpenID Connect configuration rather than using a client application (like Angular / .Net MVC web application).
Can this be achieved using "Authorization Code Flow"?
If yes, could one please guide me, how this can be achieved as we will not be able to configure the re-direction URL for a backend service to get the access token.
If not, could one please tell me how this can be achieved? I did read that this can be achieved by back channel communication (i.e. https://openid.net/specs/openid-connect-backchannel-1_0.html. If one can help me with the tutorial document that is available in internet that would be really helpful.
The link you mention is about back-channel logout: a communication from your OpenID provider toward your backend to notify your backend of a user ending her/his session at the OpenID provider. I do not see how this could be used to authenticate a user.
It feels somewhat odd that you are trying to authenticate a user from a backend service. The whole idea behind OAuth and OpenID is to pass a credential allow with your request to the backend. The backend must verify that credential but should not involve in gathering and issuing that credential, it should rely on a trusted party (the OpenID provider) to issue those credentials.

REST API using Windows authentication

I am implementing a REST Web API for a service that will be hosted on Windows now (and on Linux in the future).
We are going to support custom credentials + token/refresh token using OAuth 2.0 and OIDC (via Identity Server 4), but we want to support also Windows authentication to allow integration with Active Driectory.
For clients which use windows authentication, is it better to authenticate once and get token/refresh token mechanism (as we do for credentials authentication) or is it better to authenticate each single request?
The latter option might be less performant as it needs to go through the challange every time?
My personal feeling is that if you're having identityserver4 in play already and the fact you've stated you will host the API on Linux in future that you should handle the AD integration in your identity server and have your API only worry about access tokens issued by said service.
I'd then recommend using ADFS (recent versions support OIDC out of the box) for the actual authentication of AD users and have your identity server act as an authentication gateway. If configured correctly you can achieve true SSO (i.e. the user is not required to re-enter their domain credentials) for any user already signed into the domain on their PC.
This just covers authentication however - how will you be doing authorization within this API?

Securing WCF Service Call Between Server Applications with Federated Security

I've got two MVC sites that use the same STS for authentication. I need to create a WCF service as part of one of the sites that allows the other site to retrieve data.
These sites could be on different machines accessible over the internet (although currently they're on the same machine) and the WCF service should only be able to be accessed from the client site. The authentication token used to log into the client site should be passed through to the WCF service.
I've been looking at the different WS-Security options available (Transport, Message etc) and it's not quite sinking in 100%, and I feel like I'd end up implementing something that seemed secure but wasn't actually secure due to a lack of understanding. Any help much appreciated.
Edit:
My first attempt was with transport layer security and setting the WCF service virtual directory with require SSL in IIS. However that left me with an error of:
"The remote certificate is invalid according to the validation procedure."
And I had no way of ensuring that a specific client was connecting to the service, only that a client had a certificate from a trusted CA. At least as far as I know. I'm probably missing something vital here.
The authentication token used to log into the client site should be
passed through to the WCF service.
In this case you should be requesting an "ActAs" token from the STS:
The WCF service should be configured as a Relying Party of the STS.
The MVC site should call back to the STS and request an ActAs token specific to the WCF service.
The MVC site uses the ActAs token to call the service.
The motivation for the complexity: Delegation, or traversing multilayer architectures
Since you mentioned WS standards:
Requesting Delegation (ActAs) Tokens using WSTrustChannel (as opposed to Configuration Madness)
Not knowing your STS its hard to say more, but Googling "ActAs token" will probably give you what you need.

WCF User Authentication & Authorization

I need to find a way to authenticate/authorize users in a WCF-service. I'm using an external authentication service which stores the credentials of the users.
Eg. "Bob uses our loginmethod, we send the credentials to the authentication service, the service lets us know if these credentials are correct."
If Bob sends another request, we need to know if Bob is already authenticated.
Now a session is being created on the client, but it needs to move to the server-side. We can not rely on clients for security.
Can this be solved by using security cookies or do any of you have a better suggestion?
EDIT! I can only use the authentication server and do not have access to it
The problem you are describing is a well-known one that had (at least) two standardized solutions.
Federation using WS-Trust
The first option is a SOAP based one that uses active federation based on WS-Trust. In this solution:
Your client provides credentials to the authentication service
If the credentials are valid, the authentication service returns a signed (and encrypted) token to the client. It is encrypted so that any information contained in the token remains confidential - even the client cannot read it. It is encrypted with a public key belonging to the your WCF service. It is signed with a private key belonging to the authentication service.
The client submits the signed/encrypted token to your WCF service. The service can decrypt it because it holds the private key for decryption. It can trust it because it is signed by the authentication service.
Based on the content of the decrypted token, the service can establish the client identity and make an authorization decision.
In this model, the usual terminology is:
Your authentication service the Security Token Service
Your WCF service is the Relying Party
your client is the Client
This sounds complex, but it is very well supported in .Net and WCF using Windows Identity Foundation. There are many samples available much of it (maybe all) can be done via WCF configuration rather than code.
This is well suited to scenarios where the clients are crypto-capable (like your .Net clients) and where good frameworks exist (like WIF). It is not so good for low spec clients such as browsers and some phones, or where you are not in control of the clients.
It is commonly used in enterprise scenarios, including enterprise-to-enterprise federation. It is used less often in internet scenarios.
the strengths of it are
It is standardised and therefore generally well supported by frameworks
It means that your WCF service never has to handle the client credentials (= more secure)
It makes it pretty easy to switch to different authentication services (because it is standardised). For example, on-premise AD and Windows Azure AD both support this, as do other independent identity services
An overview can be found here:
http://msdn.microsoft.com/en-us/magazine/ee335707.aspx
And Google will show you lots more walkthroughs and examples.
Federation using OAUth 2
In this solution:
The client displays some UI provided by the authentication service (generally a web page)
The user enters their credentials in that UI and the authentication service authenticates and eventually returns a token to the client. The nature of the token is not standardised, nor is whether it is encrypted. Generally it will be at least signed.
The client submits the token with each request to the WCF service
The WCF service authenticates the token as in the previous solution
In the OAuth terminology:
Your authentication service is the Authorization Server
Your WCF service is the Resource Owner
Your client is the Client
Again, this sounds complex, but it is reasonably well supported in .Net. Probably not as well as the WS-Trust approach though at the moment. It is supported by Windows Azure AD and on the client side, using the Windows Azure Authentication Library. May other services use this approach - e.g. Facebook.
This works well where
Your client is low spec or not crypto-capable (e.g. a browser or some phones)
You do not control the client (e.g. a third party application is accessing your service)
It is very commonly used in internet application where you as an owner of the WCF service don't necessarily know the users or the clients. It is a less complete standard in some ways (e.g. it does not define exactly how the authentication happens) and as a result, it is less easy to switch to alternative authorisation servers.
The strengths of it are:
It is simpler and therefore has wider platform support
It is growing in popularity and therefore the library support is getting better all the time
The user never enters their credentials into your UI, only into the auth server, so it is more likely to be trusted (in internet scenarios)
It has a built in way of controlling the scope of the permissions granted to the client, and revoking those permissions, so again it is more trusted in an internet scenario
The official .Net support for this is in the Windows Azure AD Authentication library
http://msdn.microsoft.com/en-us/library/windowsazure/jj573266.aspx
There are other, open source components too, such as DotNetOpenAuth
http://dotnetopenauth.net/
Which solution would be best for you depends mainly on the nature of your authentication service I would say. And on whether you are in an enterprise or internet scenario. If the auth. service could be easily adapted to be a WS-Trust Secure Token Service (STS), then that would be a good route. If adding some web UI to the auth. service is feasible, the OAuth might be better.
Or, if neither option is feasible, you could just borrow the patterns form one approach and use that without going for the full standard.
Good luck!

Single sign-on for a .NET desktop application (Google, Yahoo, Facebook ...)

I need to provide a login mechanism in my application. I'd would like to provide login for the most common IPs, such as Google, Yahoo!, Facebook, Microsoft Live and others.
My application is a Desktop application written in C#, so is not a Web application.
Do you know any library or framework that I could use to achieve this purpose.
Must I implement a sign-on mechanism for each provider?
NOTE: I know that Microsoft provides a unique sign-on mechanism in Azure, but I'm not interested in this Azure service.
OpenAuth will do what you need, but it can be complicated to use. There are an abundance of resources to help you, though. Here is a link to an article describing the process of using OAuth, and there is an excellent SO answer Here with code samples you can use to get started.
You will need to register with the services you'd like to use for sign on and receive a key for them. Quoted from the linked article:
Register your app with the service that you are developing it for. e.g. Twitter, Twitpic, SoundCloud etc. You will receive a consumer key and secret.
You, the developer of the app then initiates the OAuth process by passing the consumer key and the consumer secret
The service will return a Request Token to you.
The user then needs to grant approval for the app to run requests.
Once the user has granted permission you need to exchange the request token for an access token.
Now that you have received an access token, you use this to sign all http requests with your credentials and access token.
Though you will need a key from each provider, the method of authentication will be the same, so you will not actually need to implement separate sign on code specific to each service provider.

Categories