Authenticate to STS by Issued Token - wcf

I'm working on federating an application with various areas and extremely fine-grained permissions. Each of the various areas has a federated WCF endpoint to communicate back to the server. Because of the fine grained permissions, a single token containing all of the permissions can be as large as 1MB, maybe more.
Requirements dictate that the user's username and password credentials must not be held within our code base after the initial log in process. The permissions cannot be combined to create a smaller set. We are using the Thinktecture.IdentityServer for our STS implementation.
My proposed solution is to break each endpoint into its own realm in the STS, and the STS will return a token with the permission claims specified for the realm. To accomplish this I would like to have an Auth realm which is authenticated by username/password and returns a token containing a user, tenant, and subgroup IDs which could then be used as credentials for authenticating to other realms.
Setting up the STS to issue tokens specific to realms has already been implemented. The only requirement remaining is that the username/password is not kept around within our code base.
Is it possible to configure the STS to allow authentication by providing a previously issued token from a specific realm? Is there a better solution which I have not come upon?

Yes, you can authenticate to STS A using a token issued by STS B. STS A has to be configured to trust STS B as a known identity provider.
With thinktecture STS I think you can do this by configuring a new WSStar identity provider. If one realm STS adds the other realm STS as an identity provider, it should begin accepting tokens issued from that realm+certificate.
For WCF, a reasonably painless way to set up issued token channels is with the WIF CreateChannelWithIssuedToken extension method:
http://msdn.microsoft.com/en-us/library/ee517268.aspx
1MB is a very big token indeed. There may be other good reasons to split into multiple STSes in separate realms, but you might alternatively help to solve the problem by dynamically deriving permissions through a policy or permissions stores on the relying party side where your token gets consumed rather than pre-calculating all the granular permissions from the STS side. But I say this without knowing your specific application so feel free to tell me to go away :)

What you really want is re-newing an expired token. We don't support that. And also don't have plans to do that.
You could set the expiration time to a value that works for you - and then force re-login after that.
1 MB tokens are not a good idea - you either need to roundtrip that, or create session affinity. Tokens are meant to describe user identity, not to dump every possible value into them.
Why doesn't the RP load the authZ rules from the IdP via a service call?

Related

Securely using JSON web tokens to programmatically authenticate a user from one system into another

My team and I have been working on a web application for our clients that uses JSON web tokens for authentication and authorization. Using Azure AD as our identity provider, we verify a user's identity and generate a signed JWT with the user's permissions in it. The JWT then gets included in the authorization header of all subsequent requests to the APIs. Pretty standard stuff as far as JWTs go.
We're now being asked to provide the capability to link directly into our system from another third-party web application without forcing the user to reauthenticate. I'm trying to figure out if there's a way to do so without creating a massive security loophole.
The way I picture this working would be to implement an endpoint for programmatic authentication in our system that accepts a cryptographically signed payload with an API key and the user's ID or email address. The third-party system would have a private key with which to sign the payload, and we'd have a public one to verify the signature. If the request is legitimate, we'd issue a token for the specified user, and they could use that to link to whatever they like.
I'm already getting yelled at by at least one person that this is a complete joke from a security standpoint because, among other things, it completely bypasses AAD authentication. I believe the third-party system in question does use AAD for authentication, but that's not really relevant either way because we're trusting them implicitly whether they've authenticated their users or not. Either way I take his point.
I'm not a security expert and I don't claim to know whether there even is a proper way to do this kind of thing, but from my vantage it doesn't really seem all that much less secure than any other mechanism of authentication and authorization using JWTs. Is that true? Are we nuts for even trying? Is there a way to do it that's more secure? What should I know about this that I demonstrably don't already?
Thanks in advance for the help. At the very least I hope this spurs some helpful conversation.
Single Sign-On (SSO) enables users to enter their credentials once to sign in and establish a session which can be reused across multiple applications without requiring to authenticate again. This provides a seamless experience to the user and reduces the repeated prompts for credentials.
Azure AD provides SSO capabilities to applications by setting a session cookie when the user authenticates the first time. The MSAL.js library allows applications to leverage this in a few ways.
MSAL relies on the session cookie to provide SSO for the user between different applications.
Read more in this documentation.

Managing blocked users in ASP.NET Core 2.1 API which uses JWT

I have been using JWT to authenticate the users for the HTTP endpoints in my ASP.NET Core 2.1 API project. I have configured the authentication service and everything is going on well.
while generating the token, I usually set the expiry to 24 hours. My problem is, what if the user is blocked by the admin after issuing the token. Now that the token is issued the authentication middleware will simply authenticate the request.
So, I thought I need to intercept every request to make a backend call to know whether the user is blocked or not. I can do this at every endpoint level, but it is not so efficient I think.
What are the optimal solutions for this issue, which is quite common? Are there better ways to solve it than what I thought?
When you choose to use a JWT then accept the nature of the JWT. This means that the only way to have 'real-time' information is to expire the token when the information becomes obsolete. Set the lifetime of the access token to a small window, like less than five minutes. This way you know the information is always valid and you don't have to change anything about the current handling. This is 'almost real-time', as the changes become effective within five minutes.
The advantage of a short lifetime is that this also increases the security of your website. When the token is compromised, it can only be used for a short time.
You'll have to add support for a refresh token, because you don't want the user to login every five minutes. So when the access token expires use a refresh token to request a new access token. This will only work for apps that can keep a secret. Because the refresh token is very powerful and you don't want it to fall into the wrong hands. You can use one-time only refresh tokens to limit the risks and add strategies to detect different behaviour. For more details read my answer here.
You can also choose to remove authorization claims from the JWT and move authorization to your middleware, where you can real-time check the permissions of the user. In that case the JWT only includes the user claims that identify and model the user. Claims that are not likely to change very often. As a result the access token doesn't have to be short-lived, but for security reasons I think this is still advisable.
The minimal requirement is a sub or userid claim. This is enough to identify the user and grant the user access to the website.
I think the Policy Server is a good example of a possible middleware authorization implementation. Here the middleware reads permissions from a json file and adds permissions as claims to the identity. Where policies decide what the user is allowed to do. Also implement resource-based authorization.
An alternative is to use reference tokens, as implemented by IdentityServer. IdentityServer stores the contents of the token in a data store and will only issue a unique identifier for this token back to the client. The API receiving this reference must then open a back-channel communication to IdentityServer to validate the token.
The advantage here is that you can revoke the reference token at any time, using the revocation endpoint.

Federated security, Single Sign On and security token sharing

In Single Sign On (SSO) scenario if all applications are running in same domain/company,
Is the same Security Token shared among all applications (relying parties) which get users authenticated from the same common identity provider / Security Token Service? What is the default behavior of any STS?
E.g. User A logs on to application X. After some time, she tries to access the application Y. Since she is already authenticated by the same STS and if the token issued to her is still not expired, she won't have to provide credentials while accessing application Y.
My understanding is that it may be possible if the token contains ALL the claims which would be required by all relying parties / applications. But is it a good practice?
Can token's (which was issued when user logged on to application X) expiry time be extended/reset when user A connects to application Y?
WIF implies ADFS usually,
Yes as long as all RP are using the same STS.
No - in ADFS, each RP has its own claims configuration. So the token produced is different (although you could simply copy the configuration if you wanted).
In WIF, yes. You need to use the "sliding token" mechanism.

Is OAuth 2.0 redundant/unnecessary if the client is the same as the resource owner?

In section 1.1 of RFC 6749, there are four roles: resource owner, resource server, client, and authorization server.
Does OAuth become redundant or unnecessary if the client and the resource owner are the same entity?
For example, I have a closed API and a front-facing web server. (The front-facing web server would be both the client and the resource owner.) I am trying to decide whether to switch to OAuth 2 authentication instead of using the current username/password authentication method. Is there any added security for moving to OAuth 2 if the API remains closed to third-party applications? (That is, no third-parties will ever have access to the API.)
Thanks!
In the case where the Resource Owner and Client/Resource Server roles coincide OAuth 2.0 may become less relevant from a security point of view, since one of the primary objectives of OAuth not to expose primary credentials of the user to the client becomes moot. That is also the reason why the so-called Resource Owner Password Credentials grant is considered to be a legacy/deprecated flow.
However, it may still make sense to follow the OAuth 2.0 pattern for a number of reasons:
the ability to leverage a standardized protocol through stock libraries and
frameworks without relying on custom code
the fact that in your case the Resource Server is still made strictly OAuth 2.0 compliant, dealing with Clients presenting access tokens, irrespective of what the Client/Resource Owner relationship/implementation is; this would make it easier to allow for 3rd-party client access in a future scenario
the fact that you concentrate verification of user credentials on a single path between Client and Authorization Server so each of your Resource Servers don't need to be bothered by checking user credentials individually, possibly dealing with different authentication mechanisms
and perhaps most importantly, also security-wise: once the user has authenticated through the Client using his primary credentials, the Authorization Server can issue a refresh token as well as an access token; the Client can store and use the refresh token to a new access token when the old one expires; this frees the Client from storing the primary user credentials if it wants to keep accessing the API for a long period of time without requiring explicit user interaction and authentication and makes the resulting system less vulnerable for leakage/loss of user credentials since the user credentials (password) are not stored in the Clients
If you have the following issue then you should use OAuth;
Let's say you a Gmail like web mail provider. Some of your users are using a third party app which logs in into your user's account and auto replies certain emails for you. Or you are Facebook like social network web site where some of your users use a third party app which analyzes your friend networks and prints a 2D graph for you. In this case your users are giving away their usernames and passwords. How would they prevent a certain third party app accessing their account after they gave away their username and password? Simply by changing their password. Now you have another problem; other third party apps won't be able to access the user's account. Then the user have to re-give away his password to other apps he trusts. Now this is problem too because it is not user friendly. OAuth is simply a temporary password that your user gives away to a third party app developer. He can revoke it whenever he wants without changing his own password.
Other than that OAuth is unnecessary. Just use a session cookie if you are not going to have third party app developers. It is a random string stored in user side. And on the server side will have whatever you want. Just look how PHP sessions are used and stored on server side. You can define their lifespan and refresh time automatically from php.ini.

Need help understanding WCF Security Architecture

So I've been banging my head against the wall for the past couple days trying to understand how WCF's security architecture worked. I have a goal in mind and I'm not sure that I'm going in the right direction.
The System
We use a combination of Active Directory and databases to manage our authentication and authorization. Client applications typically use their Windows credentials to authenticate and the applications checks against database tables to see if those users are allowed to authenticate and then if they are authorized to use the resources they are requesting. The current setup has each client directly communicating with the database to do these checks.
The Goal
We want to use a Security Token Service to authenticate the client and provide "high level" authorizations for top level resources. The services that provide data or perform actions would operate if the supplied SecurityToken was valid. Additionally, the token, if it did not contain a particular right, would query the token service to see if the user did have rights that were not loaded when the token was initially created. (We have over 300 rights in our database, and that could lead to rather hefty tokens for users with many rights)
What I Don't Understand
1) I understand the token creation process, but I'm a little lost on how the client gets, stores and sends the token to the services it intends to use. Does each "worker" service require a unique token (i.e. call to CalculatorService requires one version of the token and the SaveResultService require a new token to be generated?) Can I manually request, save and send tokens?
2) On the "worker" service side, what is the process by which the token is verified? Does my "worker" service have to contact the Token Service for verification of the token? Or does it just read the token and assume, if it is properly signed, that the token is genuine and operate from that perspective?
3) Is it possible to encrypt my tokens manually and store them on the client side for use while they are valid (thus avoiding authentication attempts on every service call) and so that a web client can save the token between page loads and reuse it on successive calls?
Thanks for helping with my lack of understanding
You should go through the samples for Windows Identity foundation - It providers the classes and implementations required to wrap claims that you can use or query for auth and authz.
http://msdn.microsoft.com/en-us/library/ee517291.aspx
What you are looking for is a durable token cache. - Tokens have lifetimes and usually require renewal and WIF does the renewal under the hood for most scenarios.
You can manually request and attach tokens and pool the proxies using WIF.