简介
onelogin 是一个优良的 SSO(Single Sign-On) 服务提供商,咱们能够借助 onelogin 的服务,轻松构建 SSO 程序。
之前咱们也讲过了,构建 SSO 的通用协定个别有两种,OpenID connect 和 SAML。明天咱们将会通过一个具体的例子来解说一下怎么在 onelogin 中应用 OpenID connect 中的 Authentication Flow 来进行 SSO 认证。
OpenId Connect 和 Authentication Flow 简介
OpenID Connect 是构建在 OAuth 2.0 协定之上的。它容许客户端基于受权服务器或者身份提供商(IdP)来进行用户的身份认证,并获取到用户的根本信息。
OpenID Connect 提供了 RESTful HTTP API,并应用 Json 作为数据的传递格局。
咱们能够很容易的应用 onelogin 作为 Identity Provider (IdP) 来进行 SSO 认证。
明天咱们要讲的是如何应用 onelogin 来实现 Authentication Flow。咱们晓得 OpenId Connect 有很多种模式。
明天介绍的是 Authorization Code 模式。
Authorization Code 流程的步骤如下:
客户端筹备身份认证申请,申请里蕴含所须要的参数
客户端发送申请到受权服务器
受权服务器对最红用户进行身份认证
受权服务得最终用户的对立 / 受权
受权服务器把最终用户发送回客户端,同时带着受权码
客户端应用受权码向 Token 端点申请一个响应
客户端接管到响应,响应的 Body 外面蕴含在和 ID Token 和 Access Token
客户端验证 ID Token,并取得用户的一些身份信息
onelogin 的配置工作
如果须要在咱们的应用程序中应用 onelogin,须要做一些配置工作。咱们来具体看一下。
首先咱们须要在 onelogin 中注册一个账号。
注册 onelogin 是收费的,能够配置 3 个 app 和 25 个用户。做测试应用是足够了。
注册的流程就不多讲了。注册结束之后,咱们就能够在 onelogin 中创立 app 了。
在 applications tab,咱们要应用 openid connect, 那么就搜寻 oidc:
能够看到 onelogin 能够反对多种 OIDC 的连贯协定。既然是 onelogin 的界面,当然选 onelogin 的连贯了。
输出应用程序的名字,点击 save。
在 configuration 一栏中,redirect URL 输出:http://localhost:3000/oauth/callback
这个是认证完之后,跳转回咱们本人的 app 的 URL。
而后转到 SSO 栏,拷贝 client ID 和 client Security, 批改认证形式为 POST
如果你还想创立新的 user 或者给 user 设置权限,能够自行摸索 onelogin 的高级性能。
应用应用程序连贯 onelogin
这里咱们抉择 onelogin 提供的官网 server 的例子:https://github.com/onelogin/o…
咱们下载下来该程序,将 .env.sample 重命名为 .env
批改外面的变量,次要是 OIDC_CLIENT_ID,OIDC_CLIENT_SECRET,SUBDOMAIN 和 OIDC_REDIRECT_URI 这 4 个值,都是咱们在 onelogin 做配置的时候设置的:
SUBDOMAIN=flydean-dev
OIDC_CLIENT_ID=a3446600-f263-0138-3235-122333243433
OIDC_CLIENT_SECRET=**********
OIDC_REDIRECT_URI=http://localhost:3000/oauth/callback
而后运行 npm intall; npm start 启动 nodejs 服务即可。
官网的例子是应用的 nodejs+express 框架和 Passport-OpenIdConnect 模块来和 onelogin 进行交互的。
咱们看下交互的流程。
- 用浏览器关上 http://localhost:3000,进入 app 的主页面:
- 点 login 将会跳转到 onelogin 的受权登录页面:
咱们看下网络申请:
能够看到,后面几个状态码都是 302,重定向。
从 localhost:3000 的 login 页面重定向到:
https://flydean-dev.onelogin.com/oidc/2/auth?response_type=code&client_id=a3446600-f263-0138-3235-064d76eee9d3178911&redirect_uri=http://localhost:3000/oauth/callback&scope=openid profile&state=ohC1Fi0n0YTDELBtNmePDGvb
大家能够看到,这个重定向增加了 oidc 协定中须要增加的参数,比方 respnse_type=code 代表的是应用 Authorization Code 模式。而 client_id 就是咱们配置的 client id。redirect_uri 也是配置的返回链接。
scope 示意认证范畴,state 是一个惟一标记,用来防刷。
而后又重定向到:
https://flydean-dev.onelogin.com/trust/openid-connect/v2?client_id=a3446600-f263-0138-3235-064d76eee9d3178911&grant=cbec20f1-f1d8-4733-9a6f-e98471edfc13
这一步是 onelogin 校验了上一步传来的参数,而后进行的再次跳转。
而后又重定向到:
https://flydean-dev.onelogin.com/login
这是自定义域名的登录页面。
https://flydean-dev.onelogin.com/login2/?return=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1cmkiOiJodHRwczovL2ZseWRlYW4tZGV2Lm9uZWxvZ2luLmNvbS90cnVzdC9vcGVuaWQtY29ubmVjdC92Mj9jbGllbnRfaWQ9YTM0NDY2MDAtZjI2My0wMTM4LTMyMzUtMDY0ZDc2ZWVlOWQzMTc4OTExXHUwMDI2Z3JhbnQ9Y2JlYzIwZjEtZjFkOC00NzMzLTlhNmYtZTk4NDcxZWRmYzEzIiwibm90aWZpY2F0aW9uIjp7Im1lc3NhZ2UiOiJDb25uZWN0aW5nIHRvICoqT3BlbklkIENvbm5lY3QgKE9JREMpKioiLCJpY29uIjoiY29ubmVjdGlvbiIsInR5cGUiOiJpbmZvIn0sImlzcyI6Ik1PTk9SQUlMIiwiYXVkIjoiQUNDRVNTIiwiZXhwIjoxNjAyOTIwNjM0LCJwYXJhbXMiOnt9LCJtZXRob2QiOiJnZXQifQ.hoUjh18mehtBSCINkoGOSDwJFHDBBl_nn47RMSizPfw
而后 onelogin 对参数进行加密解决,返回了大家可能看到的页面。
- 输出咱们的用户名明码
点击持续。
- 认证胜利后,调整到用户信息页面
咱们能够看到外部也是经验了一系列的转发调用工作:
咱们须要关怀的是上面的 callback:
http://localhost:3000/oauth/callback?code=2PVdwgQkNip883hql_ub9w3Byug&state=ohC1Fi0n0YTDELBtNmePDGvb
能够看到在 callback 中,咱们获取到了 code, 前面能够应用这个 code 和 onelogin 进行交互。
- 点击 profile,咱们将会尝试从 onelogin 获取到用户的信息
咱们关注下申请的链接:
http://localhost:3000/users/profile
这一步实际上会在后盾通过 code 去申请 onelogin 的用户信息。
程序中的关键步骤
这个官网的认证程序是用 nodejs 和 express 构建的,认证框架次要用的是 passport 和 passport-openidconnect。
咱们看下要害代码。
passport 配置应用 onelogin:
// Configure the OpenId Connect Strategy
// with credentials obtained from OneLogin
passport.use(new OneLoginStrategy({
issuer: baseUri,
clientID: process.env.OIDC_CLIENT_ID,
clientSecret: process.env.OIDC_CLIENT_SECRET,
authorizationURL: `${baseUri}/auth`,
userInfoURL: `${baseUri}/me`,
tokenURL: `${baseUri}/token`,
callbackURL: process.env.OIDC_REDIRECT_URI,
passReqToCallback: true
},
function(req, issuer, userId, profile, accessToken, refreshToken, params, cb) {console.log('issuer:', issuer);
console.log('userId:', userId);
console.log('accessToken:', accessToken);
console.log('refreshToken:', refreshToken);
console.log('params:', params);
req.session.accessToken = accessToken;
return cb(null, profile);
}));
从下面代码中能够看到,拿到 accessToken 之后,是寄存在 session 中的。
应用 session 存储认证信息:
app.use(session({
secret: 'secret squirrel',
resave: false,
saveUninitialized: true
}))
login 的逻辑操作:
app.get('/login', passport.authenticate('openidconnect', {
successReturnToOrRedirect: "/",
scope: 'profile'
}));
callback 的逻辑操作:
app.get('/oauth/callback', passport.authenticate('openidconnect', {
callback: true,
successReturnToOrRedirect: '/users',
failureRedirect: '/'
}))
获取用户 profile 操作:
router.get('/profile', function(req, res, next) {
request.get(`https://${ process.env.SUBDOMAIN}.onelogin.com/oidc/2/me`,
{
'auth': {'bearer': req.session.accessToken}
},function(err, respose, body){console.log('User Info')
console.log(body);
res.render('profile', {
title: 'Profile',
user: JSON.parse(body)
});
});
});
应用 session 中的 accessToken 来获取用户的信息。
总结
一个简略的 SSO 程序就搭建实现了。通过 passport 模块来获取 accessToken 信息,并存储在 session 中。
passport 模块反对很多种 Strategy,包含 openID,Local,BrowserID,Facebook,Google,Twitter 等。咱们能够应用它来适配不同的认证服务。
本文作者:flydean 程序那些事
本文链接:http://www.flydean.com/openid-connnect-with-onelogin/
本文起源:flydean 的博客
欢送关注我的公众号:「程序那些事」最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!