pub struct StatefulAuthorizationStrategy { /* private fields */ }Expand description
Stateful authorization strategy with caching.
This strategy caches authorization decisions based on channel ID, reducing the overhead of repeated authorization checks for the same connection.
§Cache Key
The cache key is built from:
- Channel ID
- Subject key
- Resource key
- Actions (comma-separated)
- Source IP
Format: {channel_id}#{subject_key}#{resource_key}#{actions}#{source_ip}
§Cache Behavior
- Cache Hit: Returns cached result immediately
- Cache Miss: Evaluates authorization and caches the result
- TTL: Cached entries expire after configured duration
- No Channel ID: Bypasses cache and evaluates directly
§Use Cases
- Connection-based protocols (e.g., long-lived TCP connections)
- High-throughput scenarios with repeated authorization checks
- Systems where authorization policies are relatively stable
§Trade-offs
Advantages:
- Significantly reduced latency for cached requests
- Lower load on authorization provider
- Better performance for connection-based protocols
Disadvantages:
- Potential delay in policy updates (up to TTL)
- Higher memory footprint
- Cache consistency considerations
§Examples
ⓘ
use rocketmq_auth::StatefulAuthorizationStrategy;
use rocketmq_auth::AuthConfig;
let config = AuthConfig::default();
let strategy = StatefulAuthorizationStrategy::new(config, None)?;
// First evaluation: queries provider
let context = DefaultAuthorizationContext::of(subject, resource, action, ip);
context.set_channel_id("channel-123");
match strategy.evaluate(&context).await? { // Cache miss
AuthorizationDecision::Allow => proceed(),
AuthorizationDecision::Deny(reason) => reject(reason),
}
// Second evaluation: uses cache
match strategy.evaluate(&context).await? { // Cache hit
AuthorizationDecision::Allow => proceed(),
AuthorizationDecision::Deny(reason) => reject(reason),
}Implementations§
Source§impl StatefulAuthorizationStrategy
impl StatefulAuthorizationStrategy
Sourcepub fn new(
auth_config: AuthConfig,
metadata_service: Option<Box<dyn Any + Send + Sync>>,
) -> AuthServiceResult<Self>
pub fn new( auth_config: AuthConfig, metadata_service: Option<Box<dyn Any + Send + Sync>>, ) -> AuthServiceResult<Self>
Creates a new stateful authorization strategy with caching.
§Arguments
auth_config- Authorization configurationmetadata_service- Optional metadata service for provider initialization
§Returns
A new StatefulAuthorizationStrategy instance.
§Examples
ⓘ
let config = AuthConfig::default();
let strategy = StatefulAuthorizationStrategy::new(config, None)?;Sourcepub fn new_with_acl_generation(
auth_config: AuthConfig,
metadata_service: Option<Box<dyn Any + Send + Sync>>,
acl_generation: Arc<AtomicU64>,
) -> AuthServiceResult<Self>
pub fn new_with_acl_generation( auth_config: AuthConfig, metadata_service: Option<Box<dyn Any + Send + Sync>>, acl_generation: Arc<AtomicU64>, ) -> AuthServiceResult<Self>
Creates a new stateful authorization strategy bound to a shared ACL generation counter.
pub fn new_with_acl_generation_and_metrics( auth_config: AuthConfig, metadata_service: Option<Box<dyn Any + Send + Sync>>, acl_generation: Arc<AtomicU64>, metrics: AuthMetrics, ) -> AuthServiceResult<Self>
Sourcepub fn cache_size(&self) -> usize
pub fn cache_size(&self) -> usize
Gets the current cache size.
Sourcepub fn clear_cache(&self)
pub fn clear_cache(&self)
Clears the entire cache.
Trait Implementations§
Source§impl AuthorizationStrategy for StatefulAuthorizationStrategy
impl AuthorizationStrategy for StatefulAuthorizationStrategy
Source§fn evaluate<'a>(
&'a self,
context: &'a DefaultAuthorizationContext,
) -> Pin<Box<dyn Future<Output = AuthServiceResult<AuthorizationDecision>> + 'a>>
fn evaluate<'a>( &'a self, context: &'a DefaultAuthorizationContext, ) -> Pin<Box<dyn Future<Output = AuthServiceResult<AuthorizationDecision>> + 'a>>
Evaluates authorization with caching support.
If the context has a channel ID, the result is cached. Subsequent requests with the same cache key will use the cached result until it expires.
§Arguments
context- The authorization context to evaluate
§Returns
Ok(AuthorizationDecision)for a final allow or denyErr(AuthServiceError)if evaluation cannot make a decision
§Examples
ⓘ
let strategy = StatefulAuthorizationStrategy::new(config, None)?;
let mut context = DefaultAuthorizationContext::of(subject, resource, action, ip);
context.set_channel_id("channel-123");
match strategy.evaluate(&context).await? {
AuthorizationDecision::Allow => proceed(),
AuthorizationDecision::Deny(reason) => reject(reason),
}Auto Trait Implementations§
impl !Freeze for StatefulAuthorizationStrategy
impl !RefUnwindSafe for StatefulAuthorizationStrategy
impl !UnwindSafe for StatefulAuthorizationStrategy
impl Send for StatefulAuthorizationStrategy
impl Sync for StatefulAuthorizationStrategy
impl Unpin for StatefulAuthorizationStrategy
impl UnsafeUnpin for StatefulAuthorizationStrategy
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
Causes
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
Causes
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
Causes
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
Causes
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
Causes
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
Causes
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
Causes
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
Causes
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Pipes by value. This is generally the method you want to use. Read more
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
Borrows
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
Mutably borrows
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
Borrows
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
Mutably borrows
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
Borrows
self, then passes self.deref() into the pipe function.Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Immutable access to the
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
Mutable access to the
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
Immutable access to the
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
Mutable access to the
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Immutable access to the
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Mutable access to the
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
Calls
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
Calls
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
Calls
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
Calls
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
Calls
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
Calls
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
Calls
.tap_deref() only in debug builds, and is erased in release
builds.