]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | ||
5 | #ifndef CEPH_RGW_AUTH_KEYSTONE_H | |
6 | #define CEPH_RGW_AUTH_KEYSTONE_H | |
7 | ||
8 | #include <utility> | |
9 | #include <boost/optional.hpp> | |
31f18b77 | 10 | #include <boost/utility/string_view.hpp> |
7c673cae FG |
11 | |
12 | #include "rgw_auth.h" | |
13 | #include "rgw_rest_s3.h" | |
14 | #include "rgw_common.h" | |
15 | #include "rgw_keystone.h" | |
16 | ||
17 | namespace rgw { | |
18 | namespace auth { | |
19 | namespace keystone { | |
20 | ||
21 | /* Dedicated namespace for Keystone-related auth engines. We need it because | |
22 | * Keystone offers three different authentication mechanisms (token, EC2 and | |
23 | * regular user/pass). RadosGW actually does support the first two. */ | |
24 | ||
25 | class TokenEngine : public rgw::auth::Engine { | |
26 | CephContext* const cct; | |
27 | ||
28 | using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t; | |
29 | using auth_info_t = rgw::auth::RemoteApplier::AuthInfo; | |
30 | using result_t = rgw::auth::Engine::result_t; | |
31 | using token_envelope_t = rgw::keystone::TokenEnvelope; | |
32 | ||
33 | const rgw::auth::TokenExtractor* const extractor; | |
34 | const rgw::auth::RemoteApplier::Factory* const apl_factory; | |
35 | rgw::keystone::Config& config; | |
36 | rgw::keystone::TokenCache& token_cache; | |
37 | ||
38 | /* Helper methods. */ | |
39 | bool is_applicable(const std::string& token) const noexcept; | |
11fdf7f2 | 40 | token_envelope_t decode_pki_token(const DoutPrefixProvider* dpp, const std::string& token) const; |
7c673cae FG |
41 | |
42 | boost::optional<token_envelope_t> | |
11fdf7f2 | 43 | get_from_keystone(const DoutPrefixProvider* dpp, const std::string& token) const; |
7c673cae FG |
44 | |
45 | acl_strategy_t get_acl_strategy(const token_envelope_t& token) const; | |
46 | auth_info_t get_creds_info(const token_envelope_t& token, | |
47 | const std::vector<std::string>& admin_roles | |
48 | ) const noexcept; | |
11fdf7f2 TL |
49 | result_t authenticate(const DoutPrefixProvider* dpp, |
50 | const std::string& token, | |
7c673cae FG |
51 | const req_state* s) const; |
52 | ||
53 | public: | |
54 | TokenEngine(CephContext* const cct, | |
55 | const rgw::auth::TokenExtractor* const extractor, | |
56 | const rgw::auth::RemoteApplier::Factory* const apl_factory, | |
57 | rgw::keystone::Config& config, | |
58 | rgw::keystone::TokenCache& token_cache) | |
59 | : cct(cct), | |
60 | extractor(extractor), | |
61 | apl_factory(apl_factory), | |
62 | config(config), | |
63 | token_cache(token_cache) { | |
64 | } | |
65 | ||
66 | const char* get_name() const noexcept override { | |
67 | return "rgw::auth::keystone::TokenEngine"; | |
68 | } | |
69 | ||
11fdf7f2 TL |
70 | result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s) const override { |
71 | return authenticate(dpp, extractor->get_token(s), s); | |
7c673cae FG |
72 | } |
73 | }; /* class TokenEngine */ | |
74 | ||
75 | ||
31f18b77 | 76 | class EC2Engine : public rgw::auth::s3::AWSEngine { |
7c673cae FG |
77 | using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t; |
78 | using auth_info_t = rgw::auth::RemoteApplier::AuthInfo; | |
79 | using result_t = rgw::auth::Engine::result_t; | |
80 | using token_envelope_t = rgw::keystone::TokenEnvelope; | |
81 | ||
82 | const rgw::auth::RemoteApplier::Factory* const apl_factory; | |
83 | rgw::keystone::Config& config; | |
84 | rgw::keystone::TokenCache& token_cache; | |
85 | ||
86 | /* Helper methods. */ | |
87 | acl_strategy_t get_acl_strategy(const token_envelope_t& token) const; | |
88 | auth_info_t get_creds_info(const token_envelope_t& token, | |
89 | const std::vector<std::string>& admin_roles | |
90 | ) const noexcept; | |
91 | std::pair<boost::optional<token_envelope_t>, int> | |
11fdf7f2 | 92 | get_from_keystone(const DoutPrefixProvider* dpp, const boost::string_view& access_key_id, |
7c673cae | 93 | const std::string& string_to_sign, |
31f18b77 | 94 | const boost::string_view& signature) const; |
11fdf7f2 TL |
95 | result_t authenticate(const DoutPrefixProvider* dpp, |
96 | const boost::string_view& access_key_id, | |
31f18b77 | 97 | const boost::string_view& signature, |
11fdf7f2 | 98 | const boost::string_view& session_token, |
31f18b77 FG |
99 | const string_to_sign_t& string_to_sign, |
100 | const signature_factory_t&, | |
101 | const completer_factory_t& completer_factory, | |
7c673cae FG |
102 | const req_state* s) const override; |
103 | public: | |
104 | EC2Engine(CephContext* const cct, | |
31f18b77 | 105 | const rgw::auth::s3::AWSEngine::VersionAbstractor* const ver_abstractor, |
7c673cae FG |
106 | const rgw::auth::RemoteApplier::Factory* const apl_factory, |
107 | rgw::keystone::Config& config, | |
108 | /* The token cache is used ONLY for the retrieving admin token. | |
109 | * Due to the architecture of AWS Auth S3 credentials cannot be | |
110 | * cached at all. */ | |
111 | rgw::keystone::TokenCache& token_cache) | |
31f18b77 | 112 | : AWSEngine(cct, *ver_abstractor), |
7c673cae FG |
113 | apl_factory(apl_factory), |
114 | config(config), | |
115 | token_cache(token_cache) { | |
116 | } | |
117 | ||
31f18b77 | 118 | using AWSEngine::authenticate; |
7c673cae FG |
119 | |
120 | const char* get_name() const noexcept override { | |
121 | return "rgw::auth::keystone::EC2Engine"; | |
122 | } | |
123 | ||
124 | }; /* class EC2Engine */ | |
125 | ||
126 | }; /* namespace keystone */ | |
127 | }; /* namespace auth */ | |
128 | }; /* namespace rgw */ | |
129 | ||
130 | #endif /* CEPH_RGW_AUTH_KEYSTONE_H */ |