this post was submitted on 25 Sep 2023
33 points (94.6% liked)
Programming
17460 readers
139 users here now
Welcome to the main community in programming.dev! Feel free to post anything relating to programming here!
Cross posting is strongly encouraged in the instance. If you feel your post or another person's post makes sense in another community cross post into it.
Hope you enjoy the instance!
Rules
Rules
- Follow the programming.dev instance rules
- Keep content related to programming in some way
- If you're posting long videos try to add in some form of tldr for those who don't want to watch videos
Wormhole
Follow the wormhole through a path of communities !webdev@programming.dev
founded 1 year ago
MODERATORS
you are viewing a single comment's thread
view the rest of the comments
view the rest of the comments
This seems like a XY problem. You are asking how to do X, when actually you need to be doing Y.
Your description is either too vague, or something I have never encountered.
It seems like what you have is Service A, Service B, and a client.
Service B doesn't have access to user credentials stored in Service A, but Service B has to know that the client has provided valid credentials for Service A.
At no point can the client make a request to Service A.
The client only makes requests to Service B.
And this has to be a username/password combination.
Is that right?
Implementing security tech from 2003 that is deprecated, especially considering it's SHA1 (which was deprecated 10 years ago) is not a good idea. Like, just store the password plaintext level of bad idea.
You either have to reasses what you actually want to do to ensure it is actually secure, or you are not describing your goal well (XY problem : "how do I implement WSSE on SOAP" instead of "I'm trying to do Y")
Based on the title you're right, I asked about how to do X when probably I need to do Y, but the first and last paragraphs mention what's my requirement: a for of authentication which doesn't require to make an extra HTTP call to generate a token.
And what I mean by this is OAuth specifies the client needs to request an access token and an optional refresh token to the authorization server, afterwards the access token can be sent to the resource server (in this case my API), if the token expires the client can make another request to the authorization server with the refresh token.
Each call to the authorization server is that "extra http call" I mentioned.
Currently the only solution I found which seemed somewhat secure was WSSE, but again, I've only worked with OAuth2 and hashing passwords (or even better, using a dedicated service like keycloak), so I'm not sure what's the best option to store the data it requires or if there's a better solution.
I don't know how to be more clear, is there a way to authenticate a client to the resource server (my API) without making the client call endpoints to generate the tokens? Is there a way for the client to generate their own tokens and for me to validate them?
Is the client a web browser used by an end user? Or is it a trusted environment?
Because if it's a trusted environment (server to server) then you could add an extra field to your user table for
api_key
, and an extratokens
table to your database.Think of githubs legacy access token system (and, again, it's now legacy because it's a dated and insecure way of doing it).
Each user gets a randomly generated 16 character string as their
api_key
.Then the user is given a way to create/regenerate/delete records into the
tokens
table: a friendly name, user id relation, and finally a randomly generated 16 character string as for the token.You could even add some sort of token expiry date, to limit the timeframe of damage for a leaked key.
Another option for untrusted environments (egba we browser) is JWT. It's used a lot for microservices.
It's a token with a lifespan minted by your Auth server. Anyone can decode the token and inspect the payload, so it's not secure for storing passwords but it's great for storing user ID and perhaps access scopes. The token can be verified by anyone to ensure the token is authentic and hasn't been tampered with.
But only servers that know the JWT secret can mint them.
The issue with JWTs is that there is no way to revoke them. If you mint a jwt that's valid for 4 years, the only way to invalidate it is by having all servers share a list of revoked tokens - or by having all servers call back to the Auth server that minted the token (which probably maintains a revoke list) to check it's still valid. And, there is no way to "ban" a user if they still have a valid token.
Essentially the JWT is keys to the kingdom, and they are hard to get back.
Which is why they often have lifetimes of 5-30 minutes, and - you guessed it - are issued along with a refresh token.
Edit:
There is SRP (6a).
https://github.com/LinusU/secure-remote-password
All the SRP projects I can find haven't been updated in 5 years - not a good look for a security system.
The problem with all of these things is that they haven't been deemed secure enough or provide enough additional benefits for widespread adoption.
The money has gone into oauth, oidc, saml, jwt etc.
Except you can have a nonce in the JWT that corresponds to a field on the server.. which is revokable.
Oh, as opposed to a revocation list.
Yup, I'm an idiot