Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: support authorization via auth proxy #1856

Open
1 task done
Jipok opened this issue Feb 21, 2024 · 0 comments
Open
1 task done

Enhancement: support authorization via auth proxy #1856

Jipok opened this issue Feb 21, 2024 · 0 comments
Labels
enhancement New feature or request

Comments

@Jipok
Copy link

Jipok commented Feb 21, 2024

What features would you like to see added?

Option FORWARD_AUTH_HEADER

More details

There are various authorizing reverse proxies. Here are two examples:
https://github.com/oauth2-proxy/oauth2-proxy
https://github.com/Jipok/Jauth
They take care of authentication, authorization, registration, etc. They are easy to support for the developer - all that is needed is to process the configured header(most often this is Remote-User or X-Forwarded-User) where the username is specified. They are also convenient for the user, since there is no need to remember/store extra login/password pairs, provide a single entry point for their own services and increase security.

I'm not good at coding in js, but I was able to implement a simple way that works for me:
Just one change in:

const refreshController = async (req, res) => {
const refreshToken = req.headers.cookie ? cookies.parse(req.headers.cookie).refreshToken : null;
if (!refreshToken) {
return res.status(200).send('Refresh token not provided');
}

const refreshController = async (req, res) => {
  const refreshToken = req.headers.cookie ? cookies.parse(req.headers.cookie).refreshToken : null;
  
  // Handle Remote-User from auth proxy
  if (!refreshToken && process.env.FORWARD_AUTH_HEADER) {
    let forwardedUserName
    const headerName = process.env.FORWARD_AUTH_HEADER.toLowerCase()
    if (req.headers.hasOwnProperty(headerName)) {
      forwardedUserName = req.headers[headerName];
    } else {
      return res.status(500).send('FORWARD_AUTH_HEADER('+headerName+') not provided');
    }
    // If user doesn't exist, register them
    let user = await User.findOne({ username: forwardedUserName }, '_id').lean();
    if (!user) {
      //determine if this is the first registered user (not counting anonymous_user)
      const isFirstRegisteredUser = (await User.countDocuments({})) === 0;
      const newUser = await new User({
        provider: 'local',
        email: forwardedUserName + '@local.none',
        password: crypto.randomBytes(Math.ceil(10)).toString('hex'),
        name: forwardedUserName,
        username: forwardedUserName,
        avatar: null,
        role: isFirstRegisteredUser ? 'ADMIN' : 'USER',
      });
      const salt = bcrypt.genSaltSync(10);
      const hash = bcrypt.hashSync(newUser.password, salt);
      newUser.password = hash;
      await newUser.save();
    }
    user = await User.findOne({ username: forwardedUserName }, '_id').lean();
    const token = await setAuthTokens(user._id, res);
    return res.status(200).send({ token, user });
  }
  
  if (!refreshToken) {
    return res.status(200).send('Refresh token not provided');
  }
...

I understand that this code hardly corresponds to the complex architecture of the project. But it works for me and I hope someone can implement it correctly. The changes that really need to be made are resetting the jwt token if it is expired/incorrect so that the code can issue a new one automatically instead of showing the user the login page.

Documentation example: https://support.getgrist.com/install/forwarded-headers/#forwarded-headers

Which components are impacted by your request?

Endpoints

Pictures

screencast.mp4

Code of Conduct

  • I agree to follow this project's Code of Conduct
@Jipok Jipok added the enhancement New feature or request label Feb 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant