When creating a WCF service application I've implemented UserNamePassValidator for custom authentication and this works as expected.
But due to the large amount of functionality on the service, I've decoupled this into different service contracts such as a stock management service, location management service, task management service etc. and I've then exposed these on different endpoints within the same service.
This seems to work fine, however what I would prefer is to authenticate with one endpoint and have this session state maintained across all of the endpoints. At present what happens is I authenticate to one, I can then access the functionality of that service contract but if I was to connect to another endpoint it requires me to authenticate again.
My current crutch solution is to pass the ClientCredentials between forms on the client side for authenticating, and although it's using Message security so they're encrypted over the wire this is obviously not an ideal solution.
Is there a solution to first part? And if not, what's the best practice for storing user entered credentials in memory (during runtime) at the client side.
You can implement a scheme similar to WS-Federation. It is kind of Federated Security for service level.
Firstly, your Authentication endpoint should be called STS (Security
Token Service). What it does is authentication and return a security
token to the client.
Secondly, STS should be trusted by all the Service Endpoints. When
invoking the endpoints you should pass in the security token that STS
provided so that the endpoints will be able to read that token and
recognize that the token was issued by a trusted STS.
I have implemented one with Thinktecture at https://github.com/khoanguyen/Test-WS-Federation but sorry that I didn't give explanation you will need to research a little bit about WS-Federation and Thinktecture and WIF. But you should know that it is possible to do.
A lightweight solution that I am using for REST services for mobile project is below:
I set up a Authentication endpoint. That endpoint hold a DSA private/public key pair. When client is authenticated, this endpoint generate a token and sign it with DSA private key. Then I combine the signature and token together and return it as a security token to the client.
At the service endpoints, I gave them the DSA public key (from the key pair of Authentication endpoint). The DSA public key is for verifying the security tokens.
When client call the service endpoints, it attaches the security token as a Header of HTTP message. Then, the service endpoints read the header to retrieve the security token -> extract the token and the signature from the security token -> use DSA public to verify it.
The strategy for generating the token depends on your need. In my case, my token contains client's username, expiration timestamp. By using DSA, the hacker can extract all the token's data but they cannot alter it because they must have the DSA private key to sign the altered token. Our job is just keeping the private key in secret and don't leave any sensitive info (e.g password) in the token.
This is very cheap way. I don't need to access DB to verify user, just ensure got a valid security token, token's data is just for extra need, you can even generate a random token and sign it. No session state needed.
Related
OpenIddict, from version 3.x, encrypts access tokens by default, but you can disable this functionality. If the encryption is left re-enabled, is it possible for the client to decrypt the token or how would the client or relying party verify the access token?
So far, I have both signing and encryption keys stored in Azure Key Vault, which is accessed and used by the OpenIddict server through RsaKeyVaultProvider.
Anyone who needs to verify an encrypted token, needs to first decrypt it. So if you want to use encryption, you would have to provide the decryption key to the client or API. You could also implement some kind of introspection endpoint, which would accept the encrypted JWT, verify it and return either claims or just confirmation that the JWT is valid. Any client or API could then call this endpoint to verify the token, and you would only have to provide the decryption key to one party.
Any APIs which are accessed with this JWT can also have a gateway in front of them, which would decrypt the JWE and pass just the signed JWS.
Also remember that usually the client shouldn't be concerned about the validity of the token. The client just sends the token to the API, and either gets a correct response or not.
Normally I wouldn't go with encrypted tokens, unless you have a strong need for them. If you want to hide contents of tokens from any onlookers I would go with using opaque access tokens and implementing the Phantom Token pattern.
I'm trying to understand how OAuth 2 works.
I don't understand this thing: if Authorization Server and Resource Server are not the same system, as in this image:
How the resource server can know who is the user and what are his permissions?
Can I retrieve these information from the Access Token or I must have a back-end comunication between Authorization Server and Resource Server?
Depends on the type of token as to how it's consumed by the resource server.
Self encoded access tokens tokens (e.g. JWT bearer tokens) will contain all the user and scope information in the token. Or some Auth systems use token introspection as detailed in Jan's answer.
This is a good introduction to the resource server and the types of token.
And a very common self encoded token is the JWT Token.
Taking the example of a self-encoded access token:
The Access Token will contain the user identifier and scopes / permissions for the token issued in the example above - which is the "implicit" grant type.
The Resource server should not need to contact the auth server. This can be one of the key benefits of Oauth 2.0 for APIs. It must trust it though. It should confirm the token has been signed by the auth server, and it may also need to be able to decrypt the token, if encrypted by the auth server.
Obviously the resource server needs to be able to access the data for the user in the token. It may be that the auth server and resource server point to the same underlying database.
Access token is usually a randomly generated string, so you cannot read any information out of it (but there may be OAuth2 implementations that use some meaningful values). The resource server must validate the access token and its scopes, not the permissions of the user who was authenticated before creating the token (resource owner). That's an important detail, because OAuth2 is a protocol for permission delegation from a resource owner to a client in form of an access token and its scopes. To do that, the resource server needs to make an HTTP request to the Token Introspection endpoint of the auth server. The JSON response contains
Boolean flag active that says whether the access token is still valid (not revokend, not expired)
Parameter scope holds its scopes granted by the resource owner
username of the resource owner
Some other useful fields.
The resource server should check that the access token is active and that it contains scopes required by the requested resource or service. It may perform some other validations (such as the requested resource is owned by the resource owner identified by the username field).
The introspection response for a given access token may be cached by the resource server (to improve performance). See the RFC for security considerations.
Access token may self-contain the authorization information in a verifiable manner (for example signed JWT). In such case, the resource server should be able to verify the authenticity (signature) and scopes of the token without calling the auth server, but then it's hard to implement the token revoke endpoint, since the resource server would accept a token even if it gets revoked at the auth server.
It can be complicated. There are many different implementations and combinations relationships between the User, Application and Resources.
Perhaps a more descriptive explanation of your architecture and relationships between the entities involved would be helpful.
If you are trying identify the User, then OAuth is not the correct protocol. YOu should look into OpenID Connect or User-Managed Access.
Generally the Resource server would only need to know the scopes to be able to provide access. Not the Identity of the user.
-jim
I'm reading up on SSO and I used this tutorial http://chris.59north.com/post/2013/04/09/Building-a-simple-custom-STS-using-VS2012-ASPNET-MVC.aspx for creating a custom STS.
If I understood correct on the STS machine is installed a certificate. The reyling party sends the thumbprint of the x509 signature. So the relying party will accept only claims of a STS with the proper certificate. Is this correct?
If so, I would like to implement that every relying party is sending a certificate to the STS which the STS got installed too. On a request the STS look up in his trusted relying party list if the sent certificate is known by the STS.
Is this implemention a good idea and is this good practice? Is there a good ressource to implement this?
thanks
implementing a custom STS is hard work. I would advise you to have a look at windows azure ACS or the Thinktecture free STS as a starting point.
This being said, having a separate certificate for a relying party is a common practice. However, the private key of this certificate is normally stored inside some database in the STS (ACS and Thinktecture both support this). The relying party only knows the public key.
The security token (SAML2 or JWT) is then signed by the acs with the security token and the relying party can use the public key (or a thumbprint) to verify the signature.
Please also notice that a SAML2 token can also be encrypted (next to being signed) and that you can use a different certificate for that.
I personally would recommend using a seperate certificate it the STS (or your organisation) has some kind of website were "anybody" can register their application as a relying party. If all your elying parties are "internal" applications I would at least consider using a single certificate to sign all security tokens. This has the advantage that you can publish the (public) key in your Federation meta data document (located at FederationMetadata/2007-06/FederationMetadata.xml). If you wish to update the key, you can update it there (by first publishing new and old key there and later only the new key). Relying parties can then update there keys based on this meta data (adfs uses a similar approach).
So bottom line : having a seperate certificate per RP is good but having a single one (for signing - not encryption) is much easier to update.
We have created a downloading client-service model application in which a WCF service is hosted on one of our servers and the client application is distributed among the partners.
Partners are provided with unique pin using which they can authenticate themselves with the WCF service and can place requests for downloading to the WCF Service.
The clients connect to the WCF Service through Windows Azure Service Bus within which we have created a namespace using which client applications can connect to the service.
Every namespace has a Default Issuer and Default Key. We have embedded this Default key in our code when connecting to the service bus.
Somebody told me that the key needs to be secured and you need to get the application signed in order to protect the embedded key. Is that true?
Do we really need to secure this key?
If yes then how? and Is there a way we can simply provide authentication in Service Bus which identifies the clients from their pins and and allows only a set of people to access the service bus namespace?
OR
I'm uselessly getting worried on such points? :)
We are using Service Bus Relay.
I have been reading about SAS and ACS and it seems according to the documentation that SAS is not supported for Relays. Following is the link:
"Support for Service Bus relays will be added in the near future."
http://msdn.microsoft.com/en-us/library/windowsazure/dn170477.aspx
I am unable to understand how to use ACS for authenticating clients. The information provided in the Windows Azure documentation are all bouncers for me and I can not relate them to anything no matter how hard I try.
If somebody has any information for my concerns then please help me with proper links and guidance.
Thanks!
EDIT!!!
I have been searching on this and the following link provides a methodology for creating an unauthenticated client:
http://msdn.microsoft.com/en-us/library/microsoft.servicebus.nettcprelaybinding.aspx
by using following tag in my client App.Config
<security relayClientAuthenticationType="None" />
I have tried this, but getting the below error:
"Generic: There was an authorization failure. Make sure you have specified the correct SharedSecret, SimpleWebToken, SharedAccessSignature, or Saml transport client credentials. MissingToken: Relay security token is required."
I'm looking more about this error. But few questions arise.
If we make the azure service bus accessible without authentication, can somebody simply misuse the service bus for their own advantage?
Do we really need to secure this key?
You store Issuer and Default Key on your server side.
To authorize on the Azure service bus, Service Bus WCF endpoint uses the Issuer and Default Key to create a token that will be signed with the Default Key that means that Default Key will never be sent to Azure.
Is there a way we can simply provide authentication in Service Bus
which identifies the clients from their pins and and allows only a set
of people to access the service bus namespace? OR I'm uselessly
getting worried on such points?
As far as I understood you have already implemented some kind of security on the WCF side.
There is another one way of doing that. You can use ACS to authentificate Clients. By Default Azure relay Service provides Support for the Simple Web Tokens.
Here is the workflow:
Client send UserName/Password( or UserName/Key) to the ACS.
ACS validates whether the credentials are valid.
ACS send the SWT token back to the Client.
Client packs the SWT token onto the HTTP request(for instance into
headers)
Client sends a request to the Web Service with the token in Header.
WCF web Service recieves the token and validates the token with the
secured shared key that was provided from ACS Namespace.(note that
this key is not sent during the communication it has to be manually
copied from the ACS Portal to the web Service config file)
If token is valid then web Service sends data to the Client.
There's a load of stuff to cover, so I'll try to keep it structured, as all good programmers should.. bear with me.
My Environment
.NET 3.5 SP1 Smart Client
Uses WCF+SOAP over HTTP to communicate to server for business logic / data access
Typically uses a custom (username+password) or Windows authentication scheme
Current work aims to extend to include a new Claims-based authentication scheme to facilitate SSO with ADFS
So far...
Main service endpoints using ws2007FederationHttpBinding bindings, configuration set up with Message security via trust/13/issuedtokenmixedsymmetricbasic256 ADFS 2.0 endpoint
Issuer endpoint configured with IssuedTokenOverTransport to HTTPS trust/13/usernamemixed ADFS 2.0 endpoint
Service has federateServiceHostConfiguration service behaviour specified
Created temporary certificate authority (CA) cert
Created temporary certificate signed by CA
Installed certificate (including private key) and made available to IIS app pool process account
Updated service WCF config to use X509 certificate
Client modified with new app’s own Client scheme/mode, programmatically sets up channel factory to ignore errors caused by temporary certificate and disables certificate revocation checks
Username/password credentials are successfully added (via standard WCF ClientCredentials object) to SOAP envelope of token requests
Token is successfully generated by usernamemixed endpoint and is returned to the client
My problem
Immediately following the token being issued, the subsequent call to issuedtokenmixedsymmetricbasic256 endpoint fails with generic error message that the security of the message could not be validated. Inspection of the SOAP envelope result gives no information at all beyond a simple ‘failed’ result enumeration value
Full tracing has been enabled on ADFS 2.0 server, but no events are logged at all in Event Log or event traces to further diagnose
Unable to configure to work in a federated manner thus far; token is successfully issues over usernamemixed endpoint in the ‘test’ environment (the internal ADFS server rather than a remote one). Use of the ‘live’ environment gives a simple unexplained 401 HTTP status code whether using usernamemixed with confirmed and valid credentials, or windowsmixed, when trying to obtain a token
Generally: Resources from Microsoft or other sources are either very scarce, very specific to one situation, and in a couple of cases, completely wrong or misleading
So ask a question already, doofus
Why does the call the issuedtokenmixedsymmetricbasic256 that WCF makes after getting the token fail? How can I diagnose the result? Other than what I've already done - enabling all trace flags in the service host config, checking the event log and event tracing data, what can I do?
Note, if you're about to suggest a link to a screencast/guide/blog/seemingly all-encompassing MSDN article, please stop. I believe I have found them all, tried them all, and what I need at this point - if you can help me please - is an answer to the above question. Not a general resource.