/**
 * @brief helper method to retrieve a user model of the currently authenticated user
 *
 * the function parses the authorization header of a request,
 * validates its format and ensures a proper session token is set.
 * it then takes the token and finds the user it belongs to.
 *
 * @param request a request
 * @return model of the currently authenticated user, taken from the storage
 * @throw kdbrest::exception::NoCurrentUserException
 * @throw kdbrest::exception::UserNotFoundException
 */
model::User AuthenticationApp::getCurrentUser (cppcms::http::request & request)
{
	// authentication validation
	std::string headerAuthorization = request.http_authorization ();
	std::string token;
	if (headerAuthorization.empty ())
	{
		// find token in get_parameters
		token = request.get (PARAM_TOKEN);
		if (token.empty ())
		{
			throw exception::NoCurrentUserException ();
		}
	}
	else
	{
		if (!boost::starts_with (headerAuthorization, AUTH_HEADER_PREFIX))
		{
			throw exception::NoCurrentUserException ();
		}
		token = headerAuthorization.substr (AUTH_HEADER_PREFIX.size ());
	}

	/* request seems fine, lets build the jwt */
	jwt_t * jwt;

	if (jwt_decode (&jwt, token.c_str (),
			reinterpret_cast<const unsigned char *> (
				Config::instance ().getConfig ().get<std::string> ("jwt.encryption.secret").c_str ()),
			Config::instance ().getConfig ().get<std::string> ("jwt.encryption.secret").size ()) != 0)
	{
		throw exception::NoCurrentUserException ();
	}

	std::unique_ptr<jwt_t, void (*) (jwt_t *)> jwt_ptr (jwt, jwt_free);

	// check issuer and other grants
	if (std::string (jwt_get_grant (jwt_ptr.get (), "issuer")) != std::string (ELEKTRA_REST_AUTHENTICATION_JWT_ISSUER) ||
	    jwt_get_grant_int (jwt_ptr.get (), "expires") < std::time (NULL))
	{
		throw exception::NoCurrentUserException ();
	}

	std::string username = std::string (jwt_get_grant (jwt_ptr.get (), "username"));
	if (username.empty ())
	{
		throw exception::NoCurrentUserException ();
	}

	try
	{
		model::User user = service::StorageEngine::instance ().getUser (username);
		return user;
	}
	catch (exception::UserNotFoundException const & e)
	{
		throw exception::UserNotFoundException ();
	}
}
/**
 * @brief validates the authorization header of a request()
 *
 * helper method that allows to validate whether a request contains a valid
 * session token or not. it checks for the authorization header, format and
 * validity of the token.
 * additionally the method can do checks on the authenticated users rank and
 * username (i.e. check for permissions or if is owner of something).
 *
 * @note if a rank and a username are given, it is sufficient that one of both matches the
 *       requirement in order for the validation to succeed.
 *
 * @param request a request
 * @param response a response
 * @param rank optionally the rank of a user can be checked
 * @param orUser optionally the name of a user can be checked
 * @return true if an authentication is present and the authenticated user
 *		   matches all requirements, false otherwise
 */
bool AuthenticationApp::validateAuthentication (cppcms::http::request & request, cppcms::http::response & response, const int rank,
						const std::string orUser)
{
	// authentication validation
	std::string headerAuthorization = request.http_authorization ();
	std::string token;
	if (headerAuthorization.empty ())
	{
		// find token in get_parameters
		token = request.get (PARAM_TOKEN);
		if (token.empty ())
		{
			RootApp::setUnauthorized (response, "Session token missing.", "NEED_AUTHENTICATION"); // send HTTP 401
			return false;									      // not successful
		}
	}
	else
	{
		if (!boost::starts_with (headerAuthorization, AUTH_HEADER_PREFIX))
		{
			RootApp::setUnauthorized (response, "Authentication header has wrong format.", "NEED_AUTHENTICATION");
			return false; // not successful
		}
		token = headerAuthorization.substr (AUTH_HEADER_PREFIX.size ());
	}

	/* request seems fine, so lets parse the token */
	jwt_t * jwt;

	// decode it
	if (jwt_decode (&jwt, token.c_str (),
			reinterpret_cast<const unsigned char *> (
				Config::instance ().getConfig ().get<std::string> ("jwt.encryption.secret").c_str ()),
			Config::instance ().getConfig ().get<std::string> ("jwt.encryption.secret").size ()) != 0)
	{
		RootApp::setUnauthorized (response, "Session token is invalid", "NEED_AUTHENTICATION"); // send HTTP 401
		return false;
	}

	std::unique_ptr<jwt_t, void (*) (jwt_t *)> jwt_ptr (jwt, jwt_free);

	// check issuer and other grants
	if (std::string (jwt_get_grant (jwt_ptr.get (), "issuer")) != std::string (ELEKTRA_REST_AUTHENTICATION_JWT_ISSUER) ||
	    jwt_get_grant_int (jwt_ptr.get (), "expires") < std::time (NULL))
	{
		RootApp::setUnauthorized (response, "Session token is invalid", "NEED_AUTHENTICATION"); // send HTTP 401
		return false;
	}

	model::User currentUser = AuthenticationApp::getCurrentUser (request);
	if (currentUser.getRank () < rank && (orUser.empty () || orUser != currentUser.getUsername ()))
	{
		RootApp::setUnauthorized (response, "This action requires higher permissions.", "USER_INSUFFICIENT_PERMISSIONS");
		return false; // not successful
	}

	return true; // authentication successful
}
예제 #3
0
파일: soft_crypto.c 프로젝트: memre/jose-c
int
jose_soft_verify(const char *jwt, jwa_t alg, jose_context_t *ctx)
{

  assert (jwt);
  assert (ctx);
  int rc = -1;

  if (alg == HS256)
    {
      uint8_t *key;
      size_t k_len;

      assert (ctx->key_container[HS256].key);
      key = ctx->key_container[HS256].key;
      k_len = ctx->key_container[HS256].k_len;

      rc = hs256_soft_verify (jwt, key, k_len);

    }
  else if (alg == ES256)
    {
      assert (ctx->key_container[ES256].key);

      json_t *jwk = (json_t *)ctx->key_container[ES256].key;

      if (!json_is_object (jwk))
        goto OUT;

      rc = es256_soft_verify (jwt, jwk);

    }
  else if (alg == NONE)
    {
      /* check to see if alg is really set to none */
      json_t *h, *c;
      rc = jwt_decode (jwt, &h, &c);
      if (rc == 0)
        {
          const char *field = "alg";
          json_t *alg_type = json_object_get(h, field);
          if (alg_type)
            {
              rc = strncmp (json_string_value (alg_type), "none", strlen("none"));
            }
          else
            rc = -2;

          json_decref (h);
          json_decref (c);
        }
      else
        {
          syslog (LOG_DEBUG, "JOSEC: Falied to decoded JWT");
        }

    }

 OUT:
  return rc;

}
int mosquitto_auth_unpwd_check(void *user_data, const char *username, const char *password) {
  
  jwt_t *jwt;
#ifdef MQAP_DEBUG
  const char* val;
  int i_val;
#endif
  time_t now;
  int iat;
  int exp;
  unsigned char key[32] = "012345678901234567890123456789AB";

  if (username == NULL || password == NULL) {
    return MOSQ_ERR_AUTH;
  }
#ifdef MQAP_DEBUG
  fprintf(stderr, "mosquitto_auth_unpwd_check: username=%s, password=%s\n", username, password);
#endif
  if ( ! strcmp(username, "jwt") ) {

	time(&now);

	int status = jwt_decode(&jwt, password, key , sizeof(key));

	if (( status == 0 ) && (jwt != NULL) ) {
#ifdef MQAP_DEBUG	
		fprintf(stderr, "mosquitto_auth_unpwd_check:  password is a valid JWT token\n");
		val = jwt_get_grant(jwt, "iss");
     		fprintf(stderr, "mosquitto_auth_unpwd_check:  iss : %s\n", val);
		val = jwt_get_grant(jwt, "sub");
     		fprintf(stderr, "mosquitto_auth_unpwd_check:  sub : %s\n", val);
		i_val = get_js_int(jwt->grants, "iat");
     		fprintf(stderr, "mosquitto_auth_unpwd_check:  iat : %d\n", i_val);
		i_val = get_js_int(jwt->grants, "exp");
     		fprintf(stderr, "mosquitto_auth_unpwd_check:  exp : %d\n", i_val);
		val = get_js_object(jwt->grants, "aud");
     		fprintf(stderr, "mosquitto_auth_unpwd_check:  aud : %s\n", val);
     		fprintf(stderr, "mosquitto_auth_unpwd_check:  now : %d\n", (int)now);
#endif
		iat = get_js_int(jwt->grants, "iat");		
		exp = get_js_int(jwt->grants, "exp");		
		if ( (now < iat) || (now > exp) ) {
#ifdef MQAP_DEBUG
                fprintf(stderr, "mosquitto_auth_unpwd_check:  token is expired\n");
#endif
		   jwt_free(jwt);
                   return MOSQ_ERR_AUTH;
		}

		// TODO add here some other controls about iss, sub, ...

		jwt_free(jwt);
        	return MOSQ_ERR_SUCCESS;
  	} else {
#ifdef MQAP_DEBUG
		fprintf(stderr, "mosquitto_auth_unpwd_check:  password is not a valid token %d\n", status);
#endif	
	}
  } 

  return MOSQ_ERR_AUTH;
}