åäžã®Webãããžã§ã¯ãã«ã€ããŠè©±ããŠããå Žåãã¯ã©ã€ã¢ã³ããšãµãŒããŒéã®ç¹å®ã®å¯Ÿè©±ã»ãã·ã§ã³ã®ç¶æ ã«é¢ããæ å ±ã¯ããŠãŒã¶ãŒãã·ã¹ãã ã«ãã°ã€ã³ãããšãã«ãŠãŒã¶ãŒèªèšŒã䜿çšããŠç°¡åã«ç¶æã§ããŸãããããããã®ãããªç¬ç«ããã·ã¹ãã ãé²åããŠè€æ°ã®ã·ã¹ãã ã«å€ãããšãéçºè ã¯ãããã®åå¥ã®ã·ã¹ãã ã®ããããã®ç¶æ ã«é¢ããæ å ±ãç¶æãããšããåé¡ã«çŽé¢ããŸããå®éã«ã¯ããã®è³ªåã¯æ¬¡ã®ããã«ãªããŸããããããã®ã·ã¹ãã ã®ãŠãŒã¶ãŒã¯ããããããåå¥ã«å ¥åããçµäºããå¿ èŠããããŸããïŒã
æéã®çµéãšãšãã«è€éããå¢ãã·ã¹ãã ãšããããã®ã·ã¹ãã ããŠãŒã¶ãŒãšã©ã®ããã«å¯Ÿè©±ãããã«ã€ããŠã¯ã1ã€ã®è¯ãã«ãŒã«ããããŸããã€ãŸãããããžã§ã¯ãã¢ãŒããã¯ãã£ã®è€éãã«é¢é£ããåé¡ã解決ããè² æ ã¯ããŠãŒã¶ãŒã§ã¯ãªãã·ã¹ãã ã«ãããŸãã Webãããžã§ã¯ãã®å éšã¡ã«ããºã ãã©ãã»ã©è€éã§ãããã¯åé¡ã§ã¯ãããŸããããŠãŒã¶ãŒã«ã¯çµ±äžãããã·ã¹ãã ã®ããã«èŠããã¯ãã§ããã€ãŸããå€ãã®ã³ã³ããŒãã³ãã§æ§æãããWebã·ã¹ãã ã䜿çšããŠãããŠãŒã¶ãŒã¯ã1ã€ã®ã·ã¹ãã ã䜿çšããŠãããã®ããã«äœãèµ·ãã£ãŠããããèªèããå¿ èŠããããŸããç¹ã«ãSSOïŒã·ã³ã°ã«ãµã€ã³ãªã³ïŒïŒã·ã³ã°ã«ãµã€ã³ãªã³ãã¯ãããžïŒã䜿çšãããã®ãããªã·ã¹ãã ã§ã®èªèšŒã«ã€ããŠèª¬æããŠããŸãã
SSOã䜿çšããã·ã¹ãã ãäœæããã«ã¯ã©ãããã°ããã§ããïŒããã§å€ãè¯ãCookieããŒã¹ã®ãœãªã¥ãŒã·ã§ã³ãèãããããããŸãããããã®ãœãªã¥ãŒã·ã§ã³ã«ã¯å¶éããããŸããå¶éã¯ãCookieã®ã€ã³ã¹ããŒã«å ã®ãã¡ã€ã³ã«é©çšãããŸããããã¯ãWebã¢ããªã±ãŒã·ã§ã³ã®ãã¹ãŠã®ãµãã·ã¹ãã ã®ãã¹ãŠã®ãã¡ã€ã³åã1ã€ã®ãããã¬ãã«ãã¡ã€ã³ã«åéããããšã«ãã£ãŠã®ã¿åé¿ã§ããŸãã
仿¥ã®ç°å¢ã§ã¯ããã®ãããªãœãªã¥ãŒã·ã§ã³ã¯ããã€ã¯ããµãŒãã¹ã¢ãŒããã¯ãã£ã®åºç¯ãªæ¡çšã«ãã£ãŠåŠšããããŠããŸãã Webãããžã§ã¯ãã®éçºã«ããŸããŸãªãã¯ãããžãŒã䜿çšãããããŸããŸãªãµãŒãã¹ãããŸããŸãªãã¡ã€ã³ã§ãã¹ããããããšããããšãã»ãã·ã§ã³ç®¡çã¯ããè€éã«ãªããŸãããããã«ã以åã¯Javaã§äœæãããŠããWebãµãŒãã¹ããNode.jsãã©ãããã©ãŒã ã®æ©èœã䜿çšããŠäœæãéå§ããŸãããããã«ãããCookieã®æäœãé£ãããªããŸãããçŸåšãã»ãã·ã§ã³ã®ç®¡çã¯ããã»ã©ç°¡åã§ã¯ãªãããšã倿ããŸããã
ãããã®å°é£ã¯ãã·ã¹ãã ã«ãã°ã€ã³ããæ°ããæ¹æ³ã®éçºã«ã€ãªãããŸãããç¹ã«ãã·ã³ã°ã«ãµã€ã³ãªã³ã®ãã¯ãããžãŒã«ã€ããŠè©±ããŠããŸãã
ã·ã³ã°ã«ãµã€ã³ãªã³ãã¯ãããžãŒ
ã·ã³ã°ã«ãµã€ã³ãªã³ãã¯ãããžãŒã®åºæ¬ååã¯ããŠãŒã¶ãŒã倿°ã®ã·ã¹ãã ã§æ§æããããããžã§ã¯ãã®1ã€ã®ã·ã¹ãã ã«ãã°ã€ã³ããä»ã®ãã¹ãŠã®ã·ã¹ãã ã§å床ãã°ã€ã³ããªããŠãæ¿èªã§ããããšã§ããåæã«ããã¹ãŠã®ã·ã¹ãã ããã®éäžååºå£ã«ã€ããŠè©±ãåã£ãŠããŸãã
æè²ç®çã§ãNode.jsãã©ãããã©ãŒã ã«SSOãã¯ãããžãŒãå®è£ ããŸãã
ãã®ãã¯ãããžãŒãäŒæ¥èŠæš¡ã§å®è£ ããã«ã¯ããã¬ãŒãã³ã°ã·ã¹ãã ã®éçºã«è²»ãããããã¯ããã«å€ãã®åŽåãå¿ èŠã«ãªãããšã«æ³šæããŠãã ããããã®ãããå€§èŠæš¡ãããžã§ã¯ãåãã«èšèšãããç¹æ®ãªSSOãœãªã¥ãŒã·ã§ã³ããããŸãã
SSOãã°ã€ã³ã¯ã©ã®ããã«æ§æãããŠããŸããïŒ
SSOå®è£ ã®äžå¿ã¯ããŠãŒã¶ãŒãèªèšŒããããã®æ å ±ãåãå ¥ããããšãã§ããåäžã®ç¬ç«ããèªèšŒãµãŒããŒã§ããäŸ-ã¡ãŒã«ã¢ãã¬ã¹ããŠãŒã¶ãŒåããã¹ã¯ãŒããä»ã®ã·ã¹ãã ã¯ããããã«ãã°ã€ã³ããããã®çŽæ¥çãªã¡ã«ããºã ããŠãŒã¶ãŒã«æäŸããŸããããããã¯ãèªèšŒãµãŒããŒãããŠãŒã¶ãŒã«é¢ããæ å ±ãåä¿¡ããããšã«ããã鿥çã«ãŠãŒã¶ãŒãæ¿èªããŸãã鿥èªèšŒã¡ã«ããºã ã¯ãããŒã¯ã³ã䜿çšããŠå®è£ ãããŸãã
ãããsimple-ssoãããžã§ã¯ãã®ã³ãŒããªããžããªã§ããããã®å®è£ ã«ã€ããŠã¯ããã§èª¬æããŸããNode.jsãã¬ãŒã ã¯ãŒã¯ã䜿çšããŠããŸãããå¥ã®ãã®ã䜿çšããŠåããã®ãå®è£ ã§ããŸããã·ã¹ãã ãæäœãããŠãŒã¶ãŒã®ã¢ã¯ã·ã§ã³ãšããã®ã·ã¹ãã ãæ§æããã¡ã«ããºã ãæ®µéçã«åæããŠã¿ãŸãããã
ã¹ããã1
ãŠãŒã¶ãŒãã·ã¹ãã äžã®ä¿è·ããããªãœãŒã¹ã«ã¢ã¯ã»ã¹ããããšããŸãïŒãã®ãªãœãŒã¹ããSSOã³ã³ã·ã¥ãŒããŒãããsso-consumerããšåŒã³ãŸãããïŒãSSOã³ã³ã·ã¥ãŒããŒã¯ããŠãŒã¶ãŒããã°ã€ã³ããŠããªãããšãæ€åºããèªåã®ã¢ãã¬ã¹ãã¯ãšãªãã©ã¡ãŒã¿ãŒãšããŠäœ¿çšããŠããŠãŒã¶ãŒããSSOãµãŒããŒãïŒãsso-serverãïŒã«ãªãã€ã¬ã¯ãããŸããæ£åžžã«èªèšŒããããŠãŒã¶ãŒã¯ããã®ã¢ãã¬ã¹ã«ãªãã€ã¬ã¯ããããŸãããã®ã¡ã«ããºã ã¯ãExpressããã«ãŠã§ã¢ã«ãã£ãŠæäŸãããŸãã
const isAuthenticated = (req, res, next) => {
// , ,
// - SSO-
// URL URL,
// ,
const redirectURL = `${req.protocol}://${req.headers.host}${req.path}`;
if (req.session.user == null) {
return res.redirect(
`http://sso.ankuranand.com:3010/simplesso/login?serviceURL=${redirectURL}`
);
}
next();
};
module.exports = isAuthenticated;
ã¹ããã2
SSOãµãŒããŒã¯ããŠãŒã¶ãŒããã°ã€ã³ããŠããªãããšãæ€åºãããŠãŒã¶ãŒããã°ã€ã³ããŒãžã«ãªãã€ã¬ã¯ãããŸãã
const login = (req, res, next) => {
// req.query url,
// , sso-.
//
//
const { serviceURL } = req.query;
// URL.
if (serviceURL != null) {
const url = new URL(serviceURL);
if (alloweOrigin[url.origin] !== true) {
return res
.status(400)
.json({ message: "Your are not allowed to access the sso-server" });
}
}
if (req.session.user != null && serviceURL == null) {
return res.redirect("/");
}
// -
//
if (req.session.user != null && serviceURL != null) {
const url = new URL(serviceURL);
const intrmid = encodedId();
storeApplicationInCache(url.origin, req.session.user, intrmid);
return res.redirect(`${serviceURL}?ssoToken=${intrmid}`);
}
return res.render("login", {
title: "SSO-Server | Login"
});
};
ããã§ã»ãã¥ãªãã£ã«ã€ããŠã³ã¡ã³ãããŸããSSOãµãŒããŒãžã®èŠæ±ãã©ã¡ãŒã¿ãŒã®åœ¢åŒã§
ãã§ãã¯ã
serviceURLãŸããããã«ããããã®URLãã·ã¹ãã ã«ç»é²ãããŠãããã©ãããããã³ãã®URLã衚ããµãŒãã¹ãSSOãµãŒããŒã®ãµãŒãã¹ã䜿çšã§ãããã©ããã確èªã§ããŸãã
SSOãµãŒããŒã®äœ¿çšãèš±å¯ãããŠãããµãŒãã¹ã®URLã®ãªã¹ãã¯æ¬¡ã®ããã«ãªããŸãã
const alloweOrigin = {
"http://consumer.ankuranand.in:3020": true,
"http://consumertwo.ankuranand.in:3030": true,
"http://test.tangledvibes.com:3080": true,
"http://blog.tangledvibes.com:3080": fasle,
};
ã¹ããã3
ãŠãŒã¶ãŒã¯ããã°ã€ã³èŠæ±ã§SSOãµãŒããŒã«éä¿¡ããããŠãŒã¶ãŒåãšãã¹ã¯ãŒããå ¥åããŸãã

ãã°ã€ã³ããŒãž
ã¹ããã4
SSOèªèšŒãµãŒããŒã¯ããŠãŒã¶ãŒã®æ å ±ãæ€èšŒããããèªäœãšãŠãŒã¶ãŒã®éã«ã»ãã·ã§ã³ãäœæããŸããããããããããã°ããŒãã«ã»ãã·ã§ã³ãã§ããæ¿èªããŒã¯ã³ã¯ããã«äœæãããŸããããŒã¯ã³ã¯ã©ã³ãã ãªæåã®æååã§ãããã®æååãã©ã®çšåºŠæ£ç¢ºã«çæããããã¯éèŠã§ã¯ãããŸãããéèŠãªããšã¯ãåããããªè¡ãç°ãªããŠãŒã¶ãŒã«å¯ŸããŠç¹°ãè¿ãããªãããšããããŠãã®ãããªè¡ã¯åœé ããã®ãé£ãããšããããšã§ãã
ã¹ããã5
SSOãµãŒããŒã¯ãèªèšŒããŒã¯ã³ãååŸããŠãæ°ãããã°ã€ã³ãããŠãŒã¶ãŒã®éä¿¡å ã«æž¡ããŸãïŒã€ãŸããããŒã¯ã³ãSSOã³ã³ã·ã¥ãŒããŒã«æž¡ããŸãïŒã
const doLogin = (req, res, next) => {
// .
// ,
// userDB - , ,
const { email, password } = req.body;
if (!(userDB[email] && password === userDB[email].password)) {
return res.status(404).json({ message: "Invalid email and password" });
}
//
const { serviceURL } = req.query;
const id = encodedId();
req.session.user = id;
sessionUser[id] = email;
if (serviceURL == null) {
return res.redirect("/");
}
const url = new URL(serviceURL);
const intrmid = encodedId();
storeApplicationInCache(url.origin, id, intrmid);
return res.redirect(`${serviceURL}?ssoToken=${intrmid}`);
};
ç¹°ãè¿ããŸãããããã€ãã®ã»ãã¥ãªãã£äžã®æ³šæïŒ
- ãã®ããŒã¯ã³ã¯åžžã«äžéã¡ã«ããºã ãšèŠãªãå¿ èŠããããå¥ã®ããŒã¯ã³ãååŸããããã«äœ¿çšãããŸãã
- JWTãäžéããŒã¯ã³ãšããŠäœ¿çšããŠããå Žåã¯ããã®äžã«ã·ãŒã¯ã¬ãããå«ããªãããã«ããŠãã ããã
ã¹ããã6
SSOã³ã³ã·ã¥ãŒããŒã¯ããŒã¯ã³ãåãåããSSOãµãŒããŒã«æ¥ç¶ããŠããŒã¯ã³ã確èªããŸãããµãŒããŒã¯ããŒã¯ã³ããã§ãã¯ãããŠãŒã¶ãŒæ å ±ãå«ãå¥ã®ããŒã¯ã³ãè¿ããŸãããã®ããŒã¯ã³ã¯ãSSOã³ã³ã·ã¥ãŒããŒããŠãŒã¶ãŒãšã®ã»ãã·ã§ã³ãäœæããããã«äœ¿çšããŸãããã®ã»ãã·ã§ã³ã¯ããŒã«ã«ãšåŒã°ããŸãã
ExpressããŒã¹ã®SSOã³ã³ã·ã¥ãŒããŒã§äœ¿çšãããããã«ãŠã§ã¢ã³ãŒãã¯æ¬¡ã®ãšããã§ãã
const ssoRedirect = () => {
return async function(req, res, next) {
// , req queryParameter, ssoToken,
// , .
const { ssoToken } = req.query;
if (ssoToken != null) {
// ssoToken , .
const redirectURL = url.parse(req.url).pathname;
try {
const response = await axios.get(
`${ssoServerJWTURL}?ssoToken=${ssoToken}`,
{
headers: {
Authorization: "Bearer l1Q7zkOL59cRqWBkQ12ZiGVW2DBL"
}
}
);
const { token } = response.data;
const decoded = await verifyJwtToken(token);
// jwt,
// global-session-id id ,
// .
req.session.user = decoded;
} catch (err) {
return next(err);
}
return res.redirect(`${redirectURL}`);
}
return next();
};
};
SSOã³ã³ã·ã¥ãŒããŒããèŠæ±ãåä¿¡ããåŸããµãŒããŒã¯ããŒã¯ã³ã®ååšãšæå¹æéã確èªããŸããæ€èšŒãããããŒã¯ã³ã¯æå¹ãšèŠãªãããŸãã
ãã®å ŽåãSSOãµãŒããŒã¯ãããŒã¯ã³ã®æ€èšŒã«æåããåŸããŠãŒã¶ãŒã«é¢ããæ å ±ãå«ãçœ²åæžã¿JWTãè¿ããŸãã
const verifySsoToken = async (req, res, next) => {
const appToken = appTokenFromRequest(req);
const { ssoToken } = req.query;
// ssoToken .
// ssoToken - , .
if (
appToken == null ||
ssoToken == null ||
intrmTokenCache[ssoToken] == null
) {
return res.status(400).json({ message: "badRequest" });
}
// appToken -
const appName = intrmTokenCache[ssoToken][1];
const globalSessionToken = intrmTokenCache[ssoToken][0];
// appToken , SSO-
if (
appToken !== appTokenDB[appName] ||
sessionApp[globalSessionToken][appName] !== true
) {
return res.status(403).json({ message: "Unauthorized" });
}
// ,
const payload = generatePayload(ssoToken);
const token = await genJwtToken(payload);
// ,
delete intrmTokenCache[ssoToken];
return res.status(200).json({ token });
};
ããã«ããã€ãã®å®å šäžã®æ³šæããããŸãã
- ãã®ãµãŒããŒãèªèšŒã«äœ¿çšãããã¹ãŠã®ã¢ããªã±ãŒã·ã§ã³ã¯ãSSOãµãŒããŒã«ç»é²ããå¿ èŠããããŸãããµãŒããŒã«ãªã¯ãšã¹ããéä¿¡ãããšãã«ç¢ºèªããããã«äœ¿çšãããã³ãŒããå²ãåœãŠãå¿ èŠããããŸããããã«ãããSSOãµãŒããŒãšSSOã³ã³ã·ã¥ãŒããŒéã®çžäºäœçšãæŽçãããšãã«ãããé«ãã¬ãã«ã®ã»ãã¥ãªãã£ãå®çŸã§ããŸãã
- ã¢ããªã±ãŒã·ã§ã³ããšã«ç°ãªãããã©ã€ããŒããããã³ããããªãã¯ãrsaãã¡ã€ã«ãçæãããããããããããã®ãããªãã¯ããŒã䜿çšããŠç€Ÿå ã§JWTãæ€èšŒã§ããããã«ããããšãã§ããŸãã
ããã«ãã¢ããªã±ãŒã·ã§ã³ã¬ãã«ã®ã»ãã¥ãªãã£ããªã·ãŒãå®çŸ©ãããã®éäžã¹ãã¬ãŒãžãæŽçã§ããŸãã
const userDB = {
"info@ankuranand.com": {
password: "test",
userId: encodedId(), // , .
appPolicy: {
sso_consumer: { role: "admin", shareEmail: true },
simple_sso_consumer: { role: "user", shareEmail: false }
}
}
};
ãŠãŒã¶ãŒãã·ã¹ãã ã«æ£åžžã«ãã°ã€ã³ãããšããŠãŒã¶ãŒãšSSOãµãŒããŒéãããã³ãŠãŒã¶ãŒãšåãµãã·ã¹ãã éã§ã»ãã·ã§ã³ãäœæãããŸãããŠãŒã¶ãŒãšSSOãµãŒããŒéã§ç¢ºç«ãããã»ãã·ã§ã³ã¯ãã°ããŒãã«ã»ãã·ã§ã³ãšåŒã°ããŸãããŠãŒã¶ãŒãšããŠãŒã¶ãŒã«ãµãŒãã¹ãæäŸãããµãã·ã¹ãã ãšã®éã«ç¢ºç«ãããã»ãã·ã§ã³ã¯ãããŒã«ã«ã»ãã·ã§ã³ãšåŒã°ããŸããããŒã«ã«ã»ãã·ã§ã³ã確ç«ããããšããŠãŒã¶ãŒã¯å€éšãªãœãŒã¹ã«éãããããµãã·ã¹ãã ãªãœãŒã¹ãæäœã§ããããã«ãªããŸãã
ããŒã«ã«ããã³ã°ããŒãã«ã»ãã·ã§ã³ã®èšå®
SSOã³ã³ã·ã¥ãŒããŒãšSSOãµãŒããŒã®ã¯ã€ãã¯ãã¢ãŒ
SSOã³ã³ã·ã¥ãŒããŒãšSSOãµãŒããŒã®æ©èœã«ã€ããŠç°¡åã«èª¬æããŸãã
âSSOã³ã³ã·ã¥ãŒããŒ
- SSOã³ã³ã·ã¥ãŒããµãã·ã¹ãã ã¯ããŠãŒã¶ãŒãSSOãµãŒããŒã«ãªãã€ã¬ã¯ãããããšã«ãã£ãŠãŠãŒã¶ãŒãèªèšŒããŸããã
- ãã®ãµãã·ã¹ãã ã¯ãSSOãµãŒããŒããæž¡ãããããŒã¯ã³ãåãåããŸãã
- ãµãŒããŒãšå¯Ÿè©±ããŠãããŒã¯ã³ã®æå¹æ§ãæ€èšŒããŸãã
- 圌女ã¯JWTãåãåããå ¬ééµã䜿çšããŠãã®ããŒã¯ã³ãæ€èšŒããŸãã
- ãã®ãµãã·ã¹ãã ã¯ããŒã«ã«ã»ãã·ã§ã³ã確ç«ããŸãã
âSSOãµãŒããŒ
- SSOãµãŒããŒã¯ãŠãŒã¶ãŒã®ãã°ã€ã³æ å ±ãæ€èšŒããŸãã
- ãµãŒããŒã¯ã°ããŒãã«ã»ãã·ã§ã³ãäœæããŸãã
- æ¿èªããŒã¯ã³ãäœæããŸãã
- æ¿èªããŒã¯ã³ãSSOã³ã³ã·ã¥ãŒããŒã«éä¿¡ãããŸãã
- ãµãŒããŒã¯ãSSOã³ã³ã·ã¥ãŒããŒããæž¡ãããããŒã¯ã³ã®æå¹æ§ãæ€èšŒããŸãã
- ãµãŒããŒã¯ããŠãŒã¶ãŒæ å ±ãšãšãã«SSOJWTãã³ã³ã·ã¥ãŒããŒã«éä¿¡ããŸãã
äžå åããããã°ã¢ãŠãã®æ§æ
SSOã®å®è£ æ¹æ³ãšåæ§ã«ãSSOãã¯ãããžãŒãå®è£ ã§ããŸããããã§ã¯ã次ã®èæ ®äºé ãèæ ®ããå¿ èŠããããŸãã
- ããŒã«ã«ã»ãã·ã§ã³ãååšããå Žåã¯ãã°ããŒãã«ã»ãã·ã§ã³ãååšããå¿ èŠããããŸãã
- ã°ããŒãã«ã»ãã·ã§ã³ãååšããå Žåãå¿ ãããããŒã«ã«ã»ãã·ã§ã³ãååšããããšãæå³ããããã§ã¯ãããŸããã
- ããŒã«ã«ã»ãã·ã§ã³ãç Žæ£ãããå Žåãã°ããŒãã«ã»ãã·ã§ã³ãç Žæ£ããå¿ èŠããããŸãã
çµæ
ãã®çµæãã·ã¹ãã ã«çµ±åã§ããã·ã³ã°ã«ãµã€ã³ãªã³ãã¯ãããžã®æ¢æã®å®è£ ã倿°ããããšã«æ³šæããŠãã ããããããã¯ãã¹ãŠãç¬èªã®é·æãšçæããããŸãããã®ãããªã·ã¹ãã ãæåããç¬ç«ããŠéçºããããšã¯ãåã·ã¹ãã ã®ç¹æ§ãåæããå¿ èŠãããå埩ããã»ã¹ã§ããããã«ã¯ããã°ã€ã³æ¹æ³ããŠãŒã¶ãŒæ å ±ã®ä¿åãããŒã¿ã®åæãªã©ãå«ãŸããŸãã
ãããžã§ã¯ãã¯SSOã¡ã«ããºã ã䜿çšããŠããŸããïŒ
