Skip to content

Instantly share code, notes, and snippets.

@jsCommander
Created August 16, 2021 16:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jsCommander/857ca389436888c3977d46d4b29984b5 to your computer and use it in GitHub Desktop.
Save jsCommander/857ca389436888c3977d46d4b29984b5 to your computer and use it in GitHub Desktop.
kerberos_sso.ts
import kerberos from "kerberos";
import { NextFunction, Request, Response } from "express";
import config from "../../config";
import ldap from "../../utilities/ldap";
import { processRawUser } from "./ldapAuth";
import { AuthResponseError } from "../../utilities/errorModels";
import { RequestWithUser } from "interfaces";
import jwt from "jsonwebtoken";
import { getLogger } from "../../utilities/logger";
const log = getLogger("auth");
const kerbServer = kerberos
.initializeServer(config.sso.gssServer)
.then(kerb => {
log.info("kerberos sso server was initialized");
return kerb;
})
.catch(err => {
log.error("can't create kerberos server, detail: %j", err);
});
export const ssoAuth = async (req: Request, res: Response, next: NextFunction) => {
const request = req as RequestWithUser;
log.debug("get sso request");
if (process.platform.includes("win")) {
return next(new Error("sso auth not working on windows platform"));
}
// first request
if (!request.headers.authorization) {
log.debug(`recive first request for sso-auth`);
log.debug('send "Negotiate" header to client ');
res.set("WWW-Authenticate", "Negotiate");
res.status(401).send();
} else {
log.debug(`recive second request for sso-auth`);
try {
const challenge = request.headers.authorization.replace("Negotiate ", "");
log.debug("recive auth token: %s", challenge);
const kerb = await kerbServer;
if (!kerb) {
return next(new AuthResponseError({ debug: "can't get kerberos server" }));
}
const someToken = await kerb.step(challenge);
res.setHeader("WWW-Authenticate", "Negotiate " + someToken);
log.debug("send token from kerberos server to client: %s", someToken);
if (kerb.contextComplete && kerb.username) {
const index = kerb.username.indexOf("@");
const username = kerb.username.slice(0, index);
log.debug(`get username:${username} from kerberos`);
const rawUser = await ldap.findUser(username);
const user = processRawUser(rawUser);
log.debug("try to sing user token");
const token = jwt.sign(user, config.token.secret, {
expiresIn: config.token.maxAge,
});
user.token = token;
res.json({ data: user });
log.info("user %s was authorized by sso, token: %s was sended to client", user.name, token);
} else {
res.status(401).send();
}
} catch (err) {
next(err);
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment