Skip to main content

AuthenticationFuture

Type Alias AuthenticationFuture 

Source
pub type AuthenticationFuture<'a> = Pin<Box<dyn Future<Output = AuthServiceResult<()>> + 'a>>;
Expand description

Authentication strategy trait.

This trait defines the contract for authentication strategies in RocketMQ. Implementations of this trait provide specific authentication mechanisms (e.g., AK/SK, token-based, mTLS).

§Thread Safety

Implementations must be thread-safe (Send + Sync) to allow concurrent authentication requests.

§Object Safety

This trait is object-safe, meaning it can be used behind a trait object (Box<dyn AuthenticationStrategy> or Arc<dyn AuthenticationStrategy>).

§Error Handling

Authentication failures should return an AuthServiceError with a bounded failure kind. Never use panic! or unwrap() in production implementations.

§Examples

§Basic Implementation

ⓘ
use rocketmq_auth::AuthenticationStrategy;
use rocketmq_auth::AuthServiceResult;

struct AllowAllAuthenticationStrategy;

impl AuthenticationStrategy for AllowAllAuthenticationStrategy {
    fn authenticate(&self, _context: &dyn AuthenticationContext) -> AuthServiceResult<()> {
        // Allow all authentication attempts (for testing only!)
        Ok(())
    }
}

§AK/SK Authentication

ⓘ
use rocketmq_auth::AuthenticationStrategy;
use rocketmq_auth::DefaultAuthenticationContext;
use rocketmq_auth::{AuthFailureKind, AuthOperation, AuthServiceError, AuthServiceResult};

struct AkSkAuthenticationStrategy {
    user_provider: Arc<dyn UserProvider>,
}

impl AuthenticationStrategy for AkSkAuthenticationStrategy {
    fn authenticate(&self, context: &dyn AuthenticationContext) -> AuthServiceResult<()> {
        // Downcast to DefaultAuthenticationContext
        let ctx = context.as_any()
            .downcast_ref::<DefaultAuthenticationContext>()
            .ok_or_else(|| AuthServiceError::new(AuthOperation::Authenticate, AuthFailureKind::InvalidInput))?;

        // Extract username and signature
        let username = ctx.username()
            .ok_or_else(|| AuthServiceError::new(AuthOperation::Authenticate, AuthFailureKind::Unauthenticated))?;
        let signature = ctx.signature()
            .ok_or_else(|| AuthServiceError::new(AuthOperation::Authenticate, AuthFailureKind::Unauthenticated))?;

        // Retrieve user from provider
        let user = self.user_provider.get_user(username.as_str())
            .map_err(|source| AuthServiceError::with_source(AuthOperation::Authenticate, source.kind(), source))?;

        // Validate signature
        if !verify_signature(ctx.content(), user.password(), signature) {
            return Err(AuthServiceError::new(AuthOperation::Authenticate, AuthFailureKind::Unauthenticated));
        }

        Ok(())
    }
}

Aliased Type§

#[repr(transparent)]
pub struct AuthenticationFuture<'a> { /* private fields */ }