Giter VIP home page Giter VIP logo

cas-client's Introduction

http-cas-client

Build Status NPM Downloads NPM Version

A complete implement of CAS Client middleware for Node.js, support CAS 1.0, 2.0+, 3.0+ protocol.

CAS(Central Authentication Service) is a single-sign-on / single-sign-off protocol for the web.

We suppose you are already familiar with the CAS protocol, if not, please read this document before you use this.

Installation

$ 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,

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,

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,

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)

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,

const httpCasClient = require('http-cas-client');
const handler = httpCasClient({
	casServerUrlPrefix: 'http://localhost:9000/cas',
	serverName: 'http://127.0.0.1',
});

Full Default Options

// 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.

Customs Options for Special Purposes

You can also override all items of options for your special cas server. And use chained multiple options arguments to create handler,

const casClientHandler = httpCasClient(options1, options2, ...);

Store

Store is an event emitter.

Method

//TODO

Event

//TODO

CAS Client Cluster

Shared Ticket Store

Sync ST store

In Frontend

In Backend

Debug

Because CAS protocol is complicated, we remove this option. We recommend you to always log every step that what CAS client do on your production environment.

Setting env.DEBUG="cas,cas:*";

License

MIT

cas-client's People

Contributors

dependabot[bot] avatar docs-kdu3 avatar gmy987 avatar lichaozhy avatar miniland1333 avatar nregina-hbs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

cas-client's Issues

Update NPM release with #5

When you have time, please update the NPM release for this package with the dependency updates from #5. Then I will be able to update my own repositories and finally get rid of the dependabot alerts!

Thank you again.

URL 报错

image
大兄弟,你自己用得怎么样? 我用你的有这个报错.

sample code does not work with https

I tried using the native Node.js sample code, but our CAS server didn't like that my app was running http instead of https. I tried simply switching to require('https') and using:

const https_options = {
    key: fs.readFileSync('key.pem'),
    cert: fs.readFileSync('cert.pem')
}

    https.createServer(https_options, (req, res) => {

but I get an "unexpected identifier" error regarding "handler" in the if (!await handler) line.

Do you have an suggestion for how to use the native https module to work?

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.