Created
August 16, 2021 16:35
-
-
Save jsCommander/857ca389436888c3977d46d4b29984b5 to your computer and use it in GitHub Desktop.
kerberos_sso.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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