@Test
  public void testToStringPlaintext() throws NoSuchAlgorithmException {
    Jwt jwt = new Jwt();
    jwt.getHeader().setAlgorithm("none");
    jwt.getClaims().setExpiration(new Date(1300819380L * 1000L));
    jwt.getClaims().setIssuer("joe");
    jwt.getClaims().setClaim("http://example.com/is_root", Boolean.TRUE);

    // sign it with a blank signature
    JwtSigner signer = new PlaintextSigner();
    signer.sign(jwt);

    /*
     * Expected string based on the following structures, serialized exactly
     * as follows and base64 encoded:
     *
     * header: {"alg":"none"} claims:
     * {"exp":1300819380,"iss":"joe","http://example.com/is_root":true}
     */
    String expected =
        "eyJhbGciOiJub25lIn0.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.";

    String actual = jwt.toString();

    assertThat(actual, equalTo(expected));
  }
  @Test
  public void testParse() {
    String source =
        "eyJhbGciOiJub25lIn0.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.";

    Jwt jwt = Jwt.parse(source);

    assertThat(jwt.getHeader().getAlgorithm(), equalTo(JwsAlgorithm.NONE.getJwaName()));
    assertThat(jwt.getClaims().getIssuer(), equalTo("joe"));
    assertThat(jwt.getClaims().getExpiration(), equalTo(new Date(1300819380L * 1000L)));
    assertThat(
        (Boolean) jwt.getClaims().getClaim("http://example.com/is_root"), equalTo(Boolean.TRUE));
  }
 /** Get the JWT-encoded value of this token */
 @Override
 @Id
 @Column(name = "id")
 public String getValue() {
   // TODO Auto-generated method stub
   return jwt.toString();
 }
  @Test
  public void testGenerateHmacSignature() {
    Jwt jwt = new Jwt();
    jwt.getHeader().setType("JWT");
    jwt.getHeader().setAlgorithm("HS256");
    jwt.getClaims().setExpiration(new Date(1300819380L * 1000L));
    jwt.getClaims().setIssuer("joe");
    jwt.getClaims().setClaim("http://example.com/is_root", Boolean.TRUE);

    byte[] key = null;
    JwtSigner signer;

    // sign it
    try {
      key = "secret".getBytes("UTF-8");

      signer = new HmacSigner();
      ((HmacSigner) signer).setPassphrase(key);
      ((HmacSigner) signer).afterPropertiesSet();

      signer.sign(jwt);

      /*
       * Expected string based on the following structures, serialized exactly
       * as follows and base64 encoded:
       *
       * header: {"typ":"JWT","alg":"HS256"} claims:
       * {"exp":1300819380,"iss":"joe","http://example.com/is_root":true}
       *
       * Expected signature: iGBPJj47S5q_HAhSoQqAdcS6A_1CFj3zrLaImqNbt9E
       */
      String signature = "p-63Jzz7mgi3H4hvW6MFB7lmPRZjhsL666MYkmpX33Y";
      String expected =
          "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ."
              + signature;

      String actual = jwt.toString();

      assertThat(actual, equalTo(expected));
      assertThat(jwt.getSignature(), equalTo(signature));
      assertThat(signer.verify(actual), equalTo(true));

    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
  /** @throws Exception */
  @Test
  public void testGenerateRsaSignature() throws Exception {

    // Hard code the private/public key so as not to depend on it being in
    // the keystore...

    RSAPrivateKeySpec privateSpec =
        new RSAPrivateKeySpec(
            new BigInteger(
                "AD6E684550542947AD95EF9BACDC0AC2C9168C6EB3212D378C23E5539266111DB2E5B4D42B1E47EB4F7A65DB63D9782C72BC365492FD1E5C7B4CD2174C611668C29013FEDE22619B3F58DA3531BB6C02B3266768B7895CBDAFB3F9AC7A7B2F3DB17EF4DCF03BD2575604BDE0A01BB1FB7B0E733AD63E464DB4D7D89626297A214D7CECCD0C50421A322A01E9DCEA23443F6A9339576B31DFA504A133076394562CB57F3FDEDB26F9A82BED2F6D52D6F6BF8286E2497EF0B5C8456F32B4668F5A9F5FCD3781345DDDB749792C37238A53D18FD976C0C9D1F1E211F1A4A9AAE679C45B92D1741EF0D3C3F373232CE7FB93E9BC461E1C508A20B74E7E3361B3C527",
                16),
            new BigInteger(
                "627CDD67E75B33EA0990A8F64DEED389942A62EB867C23B274B9F9C440D2078C47089D6D136369D21E5B52B688F8797F3C54D7C1A58B6A8F7851C2C90A4DE42CEFB864328B31191ED19582AD4CA5B38BC0F2E12C9D75BB1DD946AA55A1648D0A4ADEDEED0CDBDBF24EDDF87A345225FBBB0114BCE7E78B831B5CAC197068837AB0B3F07157952A05F67A72B9852972C704B6B32A70C3BB3DEB186936B0F7D6ABE012DEB89BC2DBE1F88AE7A28C06C53D1FB2459E58D8ED266E3BFC28266981D2A5F624D36555DD64F410461ADA5D53F448BA5EEBBD4BCEC3AF53285FB394650D7B3BFB06712E081AAD160EED6E83A3EA2D092712C07A6331209F62D27184BFC9",
                16));

    KeyFactory keyFactory = KeyFactory.getInstance("RSA");

    PrivateKey privateKey = keyFactory.generatePrivate(privateSpec);

    RSAPublicKeySpec publicSpec =
        new RSAPublicKeySpec(
            new BigInteger(
                "AD6E684550542947AD95EF9BACDC0AC2C9168C6EB3212D378C23E5539266111DB2E5B4D42B1E47EB4F7A65DB63D9782C72BC365492FD1E5C7B4CD2174C611668C29013FEDE22619B3F58DA3531BB6C02B3266768B7895CBDAFB3F9AC7A7B2F3DB17EF4DCF03BD2575604BDE0A01BB1FB7B0E733AD63E464DB4D7D89626297A214D7CECCD0C50421A322A01E9DCEA23443F6A9339576B31DFA504A133076394562CB57F3FDEDB26F9A82BED2F6D52D6F6BF8286E2497EF0B5C8456F32B4668F5A9F5FCD3781345DDDB749792C37238A53D18FD976C0C9D1F1E211F1A4A9AAE679C45B92D1741EF0D3C3F373232CE7FB93E9BC461E1C508A20B74E7E3361B3C527",
                16),
            new BigInteger("10001", 16));

    PublicKey publicKey = keyFactory.generatePublic(publicSpec);

    Jwt jwt = new Jwt();
    jwt.getHeader().setType("JWT");
    jwt.getHeader().setAlgorithm("RS256");
    jwt.getClaims().setExpiration(new Date(1300819380L * 1000L));
    jwt.getClaims().setIssuer("joe");
    jwt.getClaims().setClaim("http://example.com/is_root", Boolean.TRUE);

    JwtSigner signer = new RsaSigner(JwsAlgorithm.RS256.getJwaName(), publicKey, privateKey);
    ((RsaSigner) signer).afterPropertiesSet();

    /*
     * Expected string based on the following structures, serialized exactly
     * as follows and base64 encoded:
     *
     * header: {"typ":"JWT","alg":"HS256"} claims:
     * {"exp":1300819380,"iss":"joe","http://example.com/is_root":true}
     *
     * Expected signature: dSRvtD-ExzGN-
     * fRXd1wRZOPo1JFPuqgwvaIKp8jgcyMXJegy6IUjssfUfUcICN5yvh0ggOMWMeWkwQ7
     * -PlXMJWymdhXVI3BOpNt7ZOB2vMFYSOOHNBJUunQoe1lmNxuHQdhxqoHahn3u1cLDXz
     * -xx-
     * JELduuMmaDWqnTFPodVPl45WBKHaQhlOiFWj3ZClUV2k5p2yBT8TmxekL8gWwgVbQk5yPnYOs
     * -PcMjzODc9MZX4yI10ZSCSDciwf-
     * rgkQLT7wW4uZCoqTZ7187sCodHd6nw3nghqbtqN05fQ3Yq7ykwaR8pdQBFb2L9l7DhLLuXIREDKIFUHBSUs8OnvXFMg
     */

    String signature =
        "dSRvtD-ExzGN-fRXd1wRZOPo1JFPuqgwvaIKp8jgcyMXJegy6IUjssfUfUcICN5yvh0ggOMWMeWkwQ7-PlXMJWymdhXVI3BOpNt7ZOB2vMFYSOOHNBJUunQoe1lmNxuHQdhxqoHahn3u1cLDXz-xx-JELduuMmaDWqnTFPodVPl45WBKHaQhlOiFWj3ZClUV2k5p2yBT8TmxekL8gWwgVbQk5yPnYOs-PcMjzODc9MZX4yI10ZSCSDciwf-rgkQLT7wW4uZCoqTZ7187sCodHd6nw3nghqbtqN05fQ3Yq7ykwaR8pdQBFb2L9l7DhLLuXIREDKIFUHBSUs8OnvXFMg";
    String expected =
        "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ"
            + "."
            + signature;

    signer.sign(jwt);

    String actual = jwt.toString();

    assertThat(signer.verify(actual), equalTo(true));
    assertThat(actual, equalTo(expected));
    assertThat(jwt.getSignature(), equalTo(signature));
  }
  @RequestMapping(value = "/oauth/authorize", params = "request")
  public ModelAndView authorizeRequestObject(
      Map<String, Object> model,
      @RequestParam("request") String jwtString,
      @RequestParam Map<String, String> parameters,
      SessionStatus sessionStatus,
      Principal principal) {

    Jwt jwt = Jwt.parse(jwtString);
    JwtClaims claims = jwt.getClaims();

    // TODO: validate JWT signature

    String clientId = claims.getClaimAsString("client_id");
    // Set<String> scopes = Sets.newHashSet(Splitter.on("
    // ").split(claims.getClaimAsString("scope")));

    // Manually initialize auth request instead of using @ModelAttribute
    // to make sure it comes from request instead of the session

    // TODO: check parameter consistency, move keys to constants

    /*
     * if (in Claims):
     * 		if (in params):
     * 			if (equal):
     * 				all set
     * 			else (not equal):
     * 				error
     * 		else (not in params):
     * 			add to params
     * else (not in claims):
     * 		we don't care
     */

    String responseTypes = claims.getClaimAsString("response_type");
    if (responseTypes != null) {
      parameters.put("response_type", responseTypes);
    }

    if (clientId != null) {
      parameters.put("client_id", clientId);
    }

    if (claims.getClaimAsString("redirect_uri") != null) {
      if (parameters.containsKey("redirect_uri") == false) {
        parameters.put("redirect_uri", claims.getClaimAsString("redirect_uri"));
      }
    }

    String state = claims.getClaimAsString("state");
    if (state != null) {
      if (parameters.containsKey("state") == false) {
        parameters.put("state", state);
      }
    }

    String nonce = claims.getClaimAsString("nonce");
    if (nonce != null) {
      if (parameters.containsKey("nonce") == false) {
        parameters.put("nonce", nonce);
      }
    }

    String display = claims.getClaimAsString("display");
    if (display != null) {
      if (parameters.containsKey("display") == false) {
        parameters.put("display", display);
      }
    }

    String prompt = claims.getClaimAsString("prompt");
    if (prompt != null) {
      if (parameters.containsKey("prompt") == false) {
        parameters.put("prompt", prompt);
      }
    }

    String request = claims.getClaimAsString("request");
    if (request != null) {
      if (parameters.containsKey("request") == false) {
        parameters.put("request", request);
      }
    }

    String requestUri = claims.getClaimAsString("request_uri");
    if (requestUri != null) {
      // The spec does not allow a client to send a request parameter AND
      // link to a hosted request object at the same time, so this is an error.
      // TODO: what error to throw?
    }

    // call out to the SECOAUTH endpoint to do the real processing
    return authorizationEndpoint.authorize(
        model, parameters.get("response_type"), parameters, sessionStatus, principal);
  }
 /**
  * Set the value of this token as a string. Parses the string into a JWT.
  *
  * @param value
  * @throws IllegalArgumentException if the value is not a valid JWT string
  */
 public void setValue(String value) {
   // TODO Auto-generated method stub
   setJwt(Jwt.parse(value));
 }