http-cas-client
Installation
```base $ npm install http-cas-client ```Feature
- Singing Sign On (SSO)
- CAS Proxy with axios api for POST, PUT, DELETE...
- CAS Proxy - proxiex chain checking
- Single Logout (SLO)
- Renew & gateway
- Native http module supported
- No-session mode supported
- Easy to wrap for all popular backend framework integration
- Cluster friendly //TODO
- Principal adapter for application debugging //TODO
- SMAL1.1 //TODO
- Restlet integration supported //TODO
- Conditional skip CAS authentication //TODO
- PT cache //TODO
Getting Started
CAS Client Handler for Native
Basic usage with default options for creating a cas client handler and use it in nodejs native http server. For example, ```js const http = require('http'); const httpCasClient = require('http-cas-client'); // A CAS server deployed at url http://localhost:8080. // Default prefix is '/'. const handler = httpCasClient({casServerUrlPrefix: 'http://localhost:9000/cas',
serverName: 'http://127.0.0.1'
});
http.createServer(async (req, res) => {
if(!await handler(req, res)) {
return res.end();
}
const { principal, ticket } = req;
console.log(principal, ticket);
// { user: 'test', attributes: { ... } }
// your statements...
res.end('hello world');
}).listen(80);
```
Koa2 Wrap
It can also use with popular backend framework like Koa2. For example, ```js const koaCasClient = require('http-cas-client/wrap/koa2'); const Koa = require('koa'); const bodyparser = require('koa-bodyparser'); const casServerUrlPrefix = 'http://localhost:9000/cas'; const app = new Koa(); // NOTICE: If you put bodyparser after cas client, bodyparser will not receive req.socket data. // A native body parser is used in handler. // Sometimes you need to make some adjustments for your especial case. app.use(bodyparser()); // NOTICE: Put the middleware include casClientHandler before your specific api code. // For example, put it before routes. app.use(koaCasClient({casServerUrlPrefix: 'http://localhost:9000/cas',
serverName: 'http://127.0.0.1'
})).use(ctx => {
const { principal, ticket } = ctx;
// your statements...
ctx.body = `<a href="${casServerUrlPrefix}/logout">SLO</a><pre>`
ctx.body += JSON.stringify(principal, null, 2);
ctx.body += '</pre>'
}).listen(80);
```
Under the traditional pattern, cas client NEED to use with session, especially those 'Spring mvc' project in servlet.
So there is also a way to implement with all nodejs backend frameworks. For example in Koa2,
```js
const koaSessionCasClient = require('http-cas-client/wrap/koa2-session');
const session = require('koa-session');
const Koa = require('koa');
const casServerUrlPrefix = 'http://localhost:9000/cas';
const app = new Koa();
const sessionMiddleware = session(app);
app.keys = 'koa-app';
app.use(session(app)).use(koaSessionCasClient({
casServerUrlPrefix: 'http://localhost:9000/cas',
serverName: 'http://127.0.0.1'
})).use(ctx => {
const { principal } = ctx;
// your statements...
ctx.body = `<a href="${casServerUrlPrefix}/logout">SLO</a><pre>`
ctx.body += JSON.stringify(principal, null, 2);
ctx.body += '</pre>'
}).listen(80);
```
CAS Proxy (Use ServiceTicket instance)
```js const koaSessionCasClient = require('http-cas-client/wrap/koa2-session'); const koaCasClient = require('http-cas-client/wrap/koa2'); const Koa = require('koa'); const session = require('koa-session'); const casServerUrlPrefix = 'http://localhost:9000/cas'; const app = new Koa(); app.keys = 'koa-app'; app.use(session(app)).use(koaSessionCasClient({casServerUrlPrefix: 'http://localhost:9000/cas',
serverName: 'http://127.0.0.1:2000',
client: {
proxy: {
callbackUrl: 'http://127.0.0.1:2000/callback',
receptorUrl: '/callback'
}
}
})).use((ctx, next) => {
// If req.url matches /app, skip into next middleware.
if (ctx.request.path === '/app') {
return next();
}
const { principal } = ctx;
// This is the 1st cas client.
// your statements...
ctx.body = `<p>This is proxy</p>`;
ctx.body = `<a href="${casServerUrlPrefix}/logout">SLO</a><pre>`
ctx.body += JSON.stringify(principal, null, 2);
ctx.body += '</pre>'
}).use(async ctx => {
const { ticket } = ctx;
// Proxy request some data from 2rd cas client 'http://127.0.0.1:3000'.
const response = await ticket.request('http://127.0.0.1:3000/').then(axios => {
return axios.post('/test');
});
// Proxy send the data from 2rd.
ctx.body = response.data;
}).listen(2000);
const app2 = new Koa();
app2.use(koaCasClient({
casServerUrlPrefix: 'http://localhost:9000/cas',
serverName: 'http://127.0.0.1:3000',
client: {
proxy: {
acceptAny: true,
callbackUrl: 'http://127.0.0.1:3000/proxyCallback',
receptorUrl: '/proxyCallback'
}
}
})).use(async ctx => {
//This is the 2nd cas client.
const { principal, ticket } = ctx;
// Proxy request some data from 3rd cas client 'http://127.0.0.1:4000/'.
const response = await ticket.request('http://127.0.0.1:4000/').then(axios => {
return axios.post('/test');
});
// your statements...
ctx.body = `<p>This is App</p>`;
ctx.body += `<a href="${casServerUrlPrefix}/logout">SLO</a><pre>`;
ctx.body += JSON.stringify(principal, null, 2);
ctx.body += '</pre>';
// Combine data from the 3rd.
ctx.body += response.data;
}).listen(3000);
const app3 = new Koa();
app3.use(koaCasClient({
casServerUrlPrefix: 'http://localhost:9000/cas',
serverName: 'http://127.0.0.1:4000',
client: {
proxy: {
acceptAny: true,
}
}
})).use(async ctx => {
// This is the 3rd cas client.
// your statements...
ctx.body = 'from the proxy proxy app.'
}).listen(4000);
```
Custom Wrap
//TODO But you can review 'http-cas-client/wrap/koa2.js'. Maybe you can understand how to do. At least I think that's easy. Good luck.API Referrence
Options
The origin of CAS Server is essential. The simplest form is like, ```js const httpCasClient = require('http-cas-client'); const handler = httpCasClient({casServerUrlPrefix: 'http://localhost:9000/cas',
serverName: 'http://127.0.0.1',
});
```
Full Default Options
```js // Other items are optional. const defaultOptions = {cas: 3, // CAS protocol version 1, 2, 3
client: {
service: null,
slo: true, // Use SLO?
renew: false, // CAS renew.
gateway: false, // CAS gateway
useSession: false,
method: 'GET',
// The resource path rules let cas client ignore.
ignore: [/\.(ico|css|js|jpe?g|svg|png)/],
proxy: {
acceptAny: false,
allowedChains: () => true,
callbackUrl: null,
receptorUrl: null
}
},
server: {
loginUrl: null,
// CAS Server URIs. Normally no change is required.
// Useful when use a nonstandard cas server or url re-writed.
path: {
login: '/login',
logout: '/logout',
validate: '/validate',
serviceValidate: '/serviceValidate',
proxyValidate: '/proxyValidate',
proxy: '/proxy',
p3: {
serviceValidate: '/p3/serviceValidate',
proxyValidate: '/p3/proxyValidate',
}
}
}
}
```
Why these paths? See also, CAS Protocol 3.0 Specification.