Using JWT with Active Directory authentication in

2020-05-26 15:08发布

问题:

I am building an intranet web application consisting of an Angular frontend and a Node.JS backend. The application needs to use the corporate Active Directory for authentication and authorization.

I'm considering how to best implement this in a secure way. I am planning to use the Active Directory node module for actually communicating with the AD to authenticate when the user logs in, and to check security group membership for certain restricted actions, etc.

However, I am not quite sure what is the best way to authorize my backend endpoints. The AD module does not offer any token/ticket, even though I suppose Kerberos is used for the actual authentication process. In other authenticated apps I've developed I've generated a jsonwebtoken when the user logs in, and then passed and verified that token in each backend route, is that a good idea also when authenticating against AD?

EDIT: Second part of question spawned to separate thread: Best practices for server-side handling of JWT tokens

Also, I have a more general concern, regarding what the best practice is for actually verifying tokens. Suppose that the "secret" used for JWT generation is compromised (in my scenario many people may have access to the source code of the system, but not to the system itself). Am I right in believing that a malicious user could then, with only this information, generate a token on behalf of any given user, and without ever authenticating with AD use that token in my API requests? A token is typically generated using jwt.sign(payload, secretOrPrivateKey, options). Alternatively, suppose a malicious user could get hold of an actual token (before it has expired). To me it seems like instead of having to know a user's username and password, the security is now reduced to having to know the username and the JWT secret. Is this a valid concern and what should I do to prevent this?

My best hope so far is using a server side session to store information about the current user after logging in, so that even if a token is maliciously generated and used when accessing backend endpoints, it would fail unless the user has actually gone through the login route, authenticated with AD and stored some information in the session as a result of this.

I also considered actually authenticating with AD in each API endpoint, but that would require the AD username/password to be sent in every request, which in turn would require that sensitive information would have to be stored in the client's sessionstorage or localstorage, which is most likely a bad idea.

So, questions:

1) Is it reasonable to combine AD authorization with JWT as bearer token or what is the preferred way to build a secure backend + frontend utilizing AD for authentication?

2) If JWT is a good idea, what is the best practice for securing endpoints using JWT? Is using a server side session reasonable?

Interestingly enough I have found tons of examples on how to best implement token based authentication (in general, or with NodeJS specifically), but many of them seem flawed in one way or another.

回答1:

1) Is it reasonable to combine AD authorization with JWT as bearer token or what is the preferred way to build a secure backend + frontend utilizing AD for authentication?

It is reasonable, but if you are already using Kerberos and AD to initially authenticate the user, you might consider using s4u2proxy constrained delegation which allows the service to present the user's service ticket to the KDC and acquire (subject to authorisation checks) a ticket for a backend service (and repeat for as many services are necessary).

If you have a lot of backend services that need to be contacted, a single JWT bearing all the authorization claims needed for all the services to enforce authorization policy may be a better option.

2) If JWT is a good idea, what is the best practice for securing endpoints using JWT? Is using a server side session reasonable?

General key security practices apply:

  • Never store keys in the clear in non-volatile storage, anywhere.
  • Ideally do not store encrypted keys in attached storage on the server where, if the server is compromised, they would be subject to offline attack. Make them available to the host only at server startup.
  • Ensure key material resides in secure memory so that it cannot be swapped to disk (and/or use encrypted swap).
  • Use public key algorithms so that no secret key need exist on multiple hosts.
  • Consider using a hardware security module (HSM).