public override ClaimsIdentityCollection ValidateToken(SecurityToken token)
		{
			SimpleWebToken swt = token as SimpleWebToken;
			if (swt == null)
			{
				throw new SecurityTokenValidationException("The received token is of incorrect token type.Expected SimpleWebToken");
			}

			// check issuer name registry for allowed issuers
			string issuerName = null;
			if (base.Configuration.IssuerNameRegistry != null)
			{
				issuerName = base.Configuration.IssuerNameRegistry.GetIssuerName(token);
				if (string.IsNullOrEmpty(issuerName))
				{
					throw new SecurityTokenValidationException("Invalid issuer");
				}
			}

			// retrieve signing key
			var clause = new SwtSecurityKeyClause(swt.Issuer);
			var securityKey = Configuration.IssuerTokenResolver.ResolveSecurityKey(clause) as InMemorySymmetricSecurityKey;

			if (securityKey == null)
			{
				throw new SecurityTokenValidationException("No signing key found");
			}

			// check signature
			if (!swt.SignVerify(securityKey.GetSymmetricKey()))
			{
				throw new SecurityTokenValidationException("Signature verification of the incoming token failed.");
			}

			// check expiration
			if (DateTime.Compare(swt.ValidTo, DateTime.UtcNow) <= 0)
			{
				throw new SecurityTokenExpiredException("The incoming token has expired. Get a new access token from the Authorization Server.");
			}

			// check audience
			if (base.Configuration.AudienceRestriction.AudienceMode != System.IdentityModel.Selectors.AudienceUriMode.Never)
			{
				var allowedAudiences = base.Configuration.AudienceRestriction.AllowedAudienceUris;

				if (!allowedAudiences.Any(uri => uri == swt.AudienceUri))
				{
					throw new AudienceUriValidationFailedException();
				}
			}

			var id = new ClaimsIdentity("SWT");

			foreach (var claim in swt.Claims)
			{
				claim.Value.Split(',').ToList().ForEach(v => id.Claims.Add(new Claim(claim.ClaimType, v, ClaimValueTypes.String, issuerName)));
			}

			return new ClaimsIdentityCollection(new IClaimsIdentity[] { id });
		}
		public string WriteToken(SecurityToken token)
		{
			var swt = token as SimpleWebToken;

			if (swt == null)
			{
				throw new InvalidOperationException("token");
			}

			var sb = new StringBuilder();

			CreateClaims(swt, sb);

			sb.AppendFormat("Issuer={0}&", HttpUtility.UrlEncode(swt.Issuer));
			sb.AppendFormat("Audience={0}&", HttpUtility.UrlEncode(swt.AudienceUri.AbsoluteUri));
			sb.AppendFormat("ExpiresOn={0:0}", swt.ValidTo.ToEpochTime());

			var unsignedToken = sb.ToString();

			// retrieve signing key
			var clause = new SwtSecurityKeyClause(swt.Issuer);
			var key = Configuration.IssuerTokenResolver.ResolveSecurityKey(clause) as InMemorySymmetricSecurityKey;

			if (key == null)
			{
				throw new InvalidOperationException("No signing key found");
			}

			var hmac = new HMACSHA256(key.GetSymmetricKey());
			var sig = hmac.ComputeHash(Encoding.ASCII.GetBytes(unsignedToken));

			var signedToken = String.Format("{0}&HMACSHA256={1}",
				unsignedToken,
				HttpUtility.UrlEncode(Convert.ToBase64String(sig)));

			return signedToken;
		}