aws_smithy_runtime/client/auth/
no_auth.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6//! The [`NoAuthRuntimePlugin`] and supporting code.
7
8use crate::client::identity::no_auth::NoAuthIdentityResolver;
9use aws_smithy_runtime_api::box_error::BoxError;
10use aws_smithy_runtime_api::client::auth::static_resolver::StaticAuthSchemeOptionResolver;
11use aws_smithy_runtime_api::client::auth::{
12    AuthScheme, AuthSchemeEndpointConfig, AuthSchemeId, AuthSchemeOption,
13    AuthSchemeOptionResolverParams, AuthSchemeOptionsFuture, ResolveAuthSchemeOptions,
14    SharedAuthScheme, SharedAuthSchemeOptionResolver, Sign,
15};
16use aws_smithy_runtime_api::client::identity::{Identity, SharedIdentityResolver};
17use aws_smithy_runtime_api::client::orchestrator::HttpRequest;
18use aws_smithy_runtime_api::client::runtime_components::{
19    GetIdentityResolver, RuntimeComponents, RuntimeComponentsBuilder,
20};
21use aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugin;
22use aws_smithy_runtime_api::shared::IntoShared;
23use aws_smithy_types::config_bag::ConfigBag;
24use std::borrow::Cow;
25
26/// Auth scheme ID for "no auth".
27pub const NO_AUTH_SCHEME_ID: AuthSchemeId = AuthSchemeId::new("noAuth");
28
29/// A [`RuntimePlugin`] that registers a "no auth" identity resolver and auth scheme.
30///
31/// This plugin can be used to disable authentication in certain cases, such as when there is
32/// a Smithy `@optionalAuth` trait.
33///
34/// Note: This plugin does not work out of the box because it does not configure an auth scheme option resolver
35/// that recognizes the `noAuth` scheme.
36#[doc(hidden)]
37#[non_exhaustive]
38#[derive(Debug)]
39#[deprecated(since = "1.9.5", note = "Use `NoAuthRuntimePluginV2` instead")]
40pub struct NoAuthRuntimePlugin(RuntimeComponentsBuilder);
41
42#[allow(deprecated)]
43impl Default for NoAuthRuntimePlugin {
44    fn default() -> Self {
45        Self::new()
46    }
47}
48
49#[allow(deprecated)]
50impl NoAuthRuntimePlugin {
51    /// Creates a new `NoAuthRuntimePlugin`.
52    pub fn new() -> Self {
53        Self(
54            RuntimeComponentsBuilder::new("NoAuthRuntimePlugin")
55                .with_identity_resolver(
56                    NO_AUTH_SCHEME_ID,
57                    SharedIdentityResolver::new(NoAuthIdentityResolver::new()),
58                )
59                .with_auth_scheme(SharedAuthScheme::new(NoAuthScheme::new())),
60        )
61    }
62}
63
64#[allow(deprecated)]
65impl RuntimePlugin for NoAuthRuntimePlugin {
66    fn runtime_components(
67        &self,
68        _: &RuntimeComponentsBuilder,
69    ) -> Cow<'_, RuntimeComponentsBuilder> {
70        Cow::Borrowed(&self.0)
71    }
72}
73
74/// A [`RuntimePlugin`] that registers a "no auth" identity resolver, auth scheme, and auth scheme option resolver.
75///
76/// Ideally, a Smithy model should use `@optionalAuth` or `@auth([])` on operations so that:
77/// - The Smithy runtime supports the no-auth scheme
78/// - The code-generated default auth scheme option resolver includes the no-auth scheme for those operations
79///
80/// When that is not possible, this plugin can be used to achieve the same effect.
81#[derive(Debug)]
82pub struct NoAuthRuntimePluginV2(RuntimeComponentsBuilder);
83
84impl Default for NoAuthRuntimePluginV2 {
85    fn default() -> Self {
86        Self::new()
87    }
88}
89
90impl NoAuthRuntimePluginV2 {
91    /// Creates a new `NoAuthRuntimePluginV2`.
92    pub fn new() -> Self {
93        Self(
94            RuntimeComponentsBuilder::new("NoAuthRuntimePluginV2")
95                .with_identity_resolver(
96                    NO_AUTH_SCHEME_ID,
97                    SharedIdentityResolver::new(NoAuthIdentityResolver::new()),
98                )
99                .with_auth_scheme(SharedAuthScheme::new(NoAuthScheme::new())),
100        )
101    }
102}
103
104impl RuntimePlugin for NoAuthRuntimePluginV2 {
105    fn runtime_components(
106        &self,
107        current_components: &RuntimeComponentsBuilder,
108    ) -> Cow<'_, RuntimeComponentsBuilder> {
109        // No auth scheme option resolver is configured here because it needs to access
110        // the existing resolver (likely the code-generated default) stored in the
111        // current runtime components builder.
112        let auth_scheme_option_resolver: SharedAuthSchemeOptionResolver =
113            match current_components.auth_scheme_option_resolver() {
114                Some(current_resolver) => {
115                    NoAuthSchemeOptionResolver::new(current_resolver.clone()).into_shared()
116                }
117                None => StaticAuthSchemeOptionResolver::new(vec![NO_AUTH_SCHEME_ID]).into_shared(),
118            };
119        Cow::Owned(
120            self.0
121                .clone()
122                .with_auth_scheme_option_resolver(Some(auth_scheme_option_resolver)),
123        )
124    }
125}
126
127#[derive(Debug)]
128struct NoAuthSchemeOptionResolver<R> {
129    inner: R,
130}
131
132impl<R> NoAuthSchemeOptionResolver<R> {
133    fn new(inner: R) -> Self {
134        Self { inner }
135    }
136}
137
138impl<R> ResolveAuthSchemeOptions for NoAuthSchemeOptionResolver<R>
139where
140    R: ResolveAuthSchemeOptions,
141{
142    fn resolve_auth_scheme_options_v2<'a>(
143        &'a self,
144        params: &'a AuthSchemeOptionResolverParams,
145        cfg: &'a ConfigBag,
146        runtime_components: &'a RuntimeComponents,
147    ) -> AuthSchemeOptionsFuture<'a> {
148        let inner_future =
149            self.inner
150                .resolve_auth_scheme_options_v2(params, cfg, runtime_components);
151
152        AuthSchemeOptionsFuture::new(async move {
153            let mut options = inner_future.await?;
154            options.push(AuthSchemeOption::from(NO_AUTH_SCHEME_ID));
155            Ok(options)
156        })
157    }
158}
159
160/// The "no auth" auth scheme.
161///
162/// The orchestrator requires an auth scheme, so Smithy's `@optionalAuth` trait is implemented
163/// by placing a "no auth" auth scheme at the end of the auth scheme options list so that it is
164/// used if there's no identity resolver available for the other auth schemes. It's also used
165/// for models that don't have auth at all.
166#[derive(Debug, Default)]
167pub struct NoAuthScheme {
168    signer: NoAuthSigner,
169}
170
171impl NoAuthScheme {
172    /// Creates a new `NoAuthScheme`.
173    pub fn new() -> Self {
174        Self::default()
175    }
176}
177
178#[derive(Debug, Default)]
179struct NoAuthSigner;
180
181impl Sign for NoAuthSigner {
182    fn sign_http_request(
183        &self,
184        _request: &mut HttpRequest,
185        _identity: &Identity,
186        _auth_scheme_endpoint_config: AuthSchemeEndpointConfig<'_>,
187        _runtime_components: &RuntimeComponents,
188        _config_bag: &ConfigBag,
189    ) -> Result<(), BoxError> {
190        Ok(())
191    }
192}
193
194impl AuthScheme for NoAuthScheme {
195    fn scheme_id(&self) -> AuthSchemeId {
196        NO_AUTH_SCHEME_ID
197    }
198
199    fn identity_resolver(
200        &self,
201        identity_resolvers: &dyn GetIdentityResolver,
202    ) -> Option<SharedIdentityResolver> {
203        identity_resolvers.identity_resolver(NO_AUTH_SCHEME_ID)
204    }
205
206    fn signer(&self) -> &dyn Sign {
207        &self.signer
208    }
209}