|
| 1 | +# Oracle JDBC Providers for Spring |
| 2 | + |
| 3 | +This module contains providers for integrations between Oracle JDBC and |
| 4 | +[Spring](https://spring.io/). |
| 5 | + |
| 6 | +## Installation |
| 7 | + |
| 8 | +Providers in this module are distributed as a single jar on the |
| 9 | +Maven Central Repository. The jar is compiled for JDK 17, and is forward |
| 10 | +compatible with later JDK versions. The coordinates for the latest release are: |
| 11 | +```xml |
| 12 | +<dependency> |
| 13 | + <groupId>com.oracle.database.jdbc</groupId> |
| 14 | + <artifactId>ojdbc-provider-spring</artifactId> |
| 15 | + <version>1.0.6</version> |
| 16 | +</dependency> |
| 17 | +``` |
| 18 | + |
| 19 | +## End User Security Context Provider |
| 20 | +The End User Security Context Provider provides a security context that enables |
| 21 | +Deep Data Security features in Oracle Database. This is a |
| 22 | +[Resource Provider](https://docs.oracle.com/en/database/oracle/oracle-database/26/jajdb/oracle/jdbc/spi/OracleResourceProvider.html) |
| 23 | +identified by the name `ojdbc-provider-spring-end-user-security-context`. |
| 24 | + |
| 25 | +This provider must be configured to authenticate as an OAuth 2.0 client. The |
| 26 | +client should be mapped to a `DATA ROLE` or `APPLICATION IDENTITY` defined in |
| 27 | +an Oracle Database. In the example below, Spring Boot properties under |
| 28 | +`spring.security` define an |
| 29 | +[OAuth 2.0 client registration](https://docs.spring.io/spring-security/reference/servlet/oauth2/client/core.html#oauth2Client-client-registration) |
| 30 | +for Azure, and properties under `spring.datasource` configure this provider to |
| 31 | +use that registration. |
| 32 | +```yaml |
| 33 | +spring: |
| 34 | + security: |
| 35 | + oauth2: |
| 36 | + client: |
| 37 | + provider: |
| 38 | + azure: |
| 39 | + token-uri: "https://login.microsoftonline.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/oauth2/v2.0/token" |
| 40 | + registration: |
| 41 | + azure: |
| 42 | + authorization-grant-type: client_credentials |
| 43 | + client-id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" |
| 44 | + client-secret: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" |
| 45 | + scope: "https://xxxxxxxxxxxxxxxxx.onmicrosoft.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/.default" |
| 46 | + datasource: |
| 47 | + url: > |
| 48 | + jdbc:oracle:thin:@example |
| 49 | + ?oracle.jdbc.provider.endUserSecurityContext=ojdbc-provider-spring-end-user-security-context |
| 50 | + &oracle.jdbc.provider.endUserSecurityContext.registrationId=azure_client |
| 51 | + username: db_user |
| 52 | + password: db_password |
| 53 | +``` |
| 54 | +This provider is activated by parameters seen in the JDBC URL above, where |
| 55 | +`oracle.jdbc.provider.endUserSecurityContext` configures Oracle JDBC to load an |
| 56 | +[EndUserSecurityContextProvider](https://docs.oracle.com/en/database/oracle/oracle-database/26/jajdb/oracle/jdbc/spi/EndUserSecurityContextProvider.html) |
| 57 | +with the name of this provider: |
| 58 | +`ojdbc-provider-spring-end-user-security-context`. This configuration will have |
| 59 | +an [oracle.jdbc.EndUserSecurityContext](https://docs.oracle.com/en/database/oracle/oracle-database/26/jajdb/oracle/jdbc/EndUserSecurityContext.html) provided to Oracle JDBC |
| 60 | +each time it executes a database operation. |
| 61 | + |
| 62 | +Almost every network request JDBC sends to the database is considered a database |
| 63 | +operation. This includes SQL execution, row fetching, commit/rollback, |
| 64 | +and LOB data access. When an `EndUserSecurityContext` is provided to Oracle |
| 65 | +JDBC, all of these operations become subject to `DATA GRANT` policies defined in |
| 66 | +Oracle Database. |
| 67 | + |
| 68 | +A `DATA GRANT` policy can apply to specific controls based on which user is |
| 69 | +accessing the database, and which application they are accessing it through. |
| 70 | +This offers a more granular approach to data security when compared to the |
| 71 | +traditional model, in which all application users access the database as the |
| 72 | +same database user. |
| 73 | + |
| 74 | +### Application Authorization and User Identity |
| 75 | +An `EndUserSecurityContext` provided to Oracle JDBC encapsulates two security |
| 76 | +tokens: |
| 77 | +<dl> |
| 78 | +<dt>Database Access Token</dt> |
| 79 | +<dd> |
| 80 | +This token authorizes a Spring application to access the database. The provider |
| 81 | +requests this token using an OAuth 2.0 client registration identified by the |
| 82 | +<code>oracle.jdbc.provider.endUserSecurityContext.registrationId</code> |
| 83 | +parameter. |
| 84 | +</dd> |
| 85 | +<dt>End User Token</dt> |
| 86 | +<dd> |
| 87 | +This token identifies the end user of a Spring application. |
| 88 | +It is typically received in the Authorization header of an incoming HTTP |
| 89 | +request. The provider retrieves this token using Spring's |
| 90 | +<a href="https://docs.spring.io/spring-security/reference/servlet/authentication/architecture.html#servlet-authentication-securitycontextholder"> |
| 91 | +SecurityContextHolder |
| 92 | +</a>. |
| 93 | +</dd> |
| 94 | +</dl> |
| 95 | +These two tokens allow Oracle Database to make authorization decisions based |
| 96 | +on the application user who is accessing data, and which application they are |
| 97 | +accessing it from. |
| 98 | + |
| 99 | +### Application Managed Data Roles and Attributes |
| 100 | +The `EndUserSecurityContext` provided to Oracle JDBC may include application |
| 101 | +managed <code>DATA ROLE</code> names or <code>END USER CONTEXT</code> attributes |
| 102 | +that are derived from a |
| 103 | +<a href="https://docs.spring.io/spring-security/reference/servlet/authentication/architecture.html#servlet-authentication-granted-authority"> |
| 104 | +GrantedAuthority |
| 105 | +</a> present in Spring's |
| 106 | +<a href="https://docs.spring.io/spring-security/reference/servlet/authentication/architecture.html#servlet-authentication-securitycontextholder"> |
| 107 | +SecurityContextHolder |
| 108 | +</a>. |
| 109 | +<dl> |
| 110 | +<dt>Application Managed Data Roles</dt> |
| 111 | +<dd> |
| 112 | +If one or more <code>GrantedAuthority</code> objects have <code>String</code> |
| 113 | +representations beginning with a specified prefix, then the provider will |
| 114 | +recognize them as application managed <code>DATA ROLE</code> names that |
| 115 | +should be enabled for the end user. |
| 116 | +<p> |
| 117 | +The name of a <code>DATA ROLE</code> should appear |
| 118 | +after the specified prefix. For example: If the prefix is configured as |
| 119 | +"ORACLE_DATA_ROLE_", then a <code>GrantedAuthority</code> might have a |
| 120 | +<code>String</code> representation of <code>ORACLE_DATA_ROLE_ADMIN</code>. The |
| 121 | +provider will recognize that <code>GrantedAuthority</code> as a |
| 122 | +<code>DATA ROLE</code> named "ADMIN". |
| 123 | +</dd> |
| 124 | +<dt>End User Context Attributes</dt> |
| 125 | +<dd> |
| 126 | +If one or more <code>GrantedAuthority</code> objects have <code>String</code> |
| 127 | +representations beginning with a specified prefix, then the provider will |
| 128 | +recognize them as attributes of an <code>END USER CONTEXT</code>. |
| 129 | +<p> |
| 130 | +A JSON object containing the attributes of one or more |
| 131 | +<code>END USER CONTEXT</code> should appear |
| 132 | +after the <code>ORACLE_CONTEXT_ATTRIBUTE_</code> prefix. For example: If the |
| 133 | +prefix is configured as "ORACLE_CONTEXT_ATTRIBUTE_", then a |
| 134 | +<code>GrantedAuthority</code> might have the following <code>String</code> |
| 135 | +representation, including the line breaks: |
| 136 | +<pre> |
| 137 | +ORACLE_CONTEXT_ATTRIBUTE_{ |
| 138 | + "app_schema.user_details" : { |
| 139 | + "first_name" : "George", |
| 140 | + "last_name" : "Washington" |
| 141 | + }, |
| 142 | + "app_schema.location_info" : { |
| 143 | + "City" : "Mount Vernon", |
| 144 | + "State" : "Virginia", |
| 145 | + "Country" : "United States" |
| 146 | + } |
| 147 | +} |
| 148 | +</pre> |
| 149 | +The provider will recognize that <code>GrantedAuthority</code> as the attributes |
| 150 | +of two <code>END USER CONTEXT</code> objects named "user_details" and |
| 151 | +"location_info", each declared within a database schema named "app_schema". |
| 152 | +</dd> |
| 153 | +</dl> |
| 154 | + |
| 155 | +### Configuration |
| 156 | +The full set of parameters that configure this provider are listed in the table |
| 157 | +below. |
| 158 | +<table> |
| 159 | +<thead><tr> |
| 160 | +<th>Parameter Name</th> |
| 161 | +<th>Description</th> |
| 162 | +<th>Accepted Values</th> |
| 163 | +<th>Default Value</th> |
| 164 | +</tr></thead><tbody><tr><td> |
| 165 | +oracle.jdbc.provider.endUserSecurityContext.registrationId |
| 166 | +</td><td> |
| 167 | +The ID of an |
| 168 | +<a href="https://docs.spring.io/spring-security/reference/servlet/oauth2/client/core.html#oauth2Client-client-registration"> |
| 169 | +OAuth 2.0 client registration |
| 170 | +</a>. |
| 171 | +The provider requests database access tokens using this client registration. |
| 172 | +</td><td> |
| 173 | +This should be the ID of an OAuth 2.0 client registration configured using |
| 174 | +Spring. |
| 175 | +</td><td> |
| 176 | +<i>No default value. A value must be configured for this parameter.</i> |
| 177 | +</td></tr><tr><td> |
| 178 | +oracle.jdbc.provider.endUserSecurityContext.dataRoles |
| 179 | +</td><td> |
| 180 | +A fixed set of <code>DATA ROLE</code> names to enable for all end users. |
| 181 | +</td><td> |
| 182 | +This should be one or more <code>DATA ROLE</code> names, separated by commas: |
| 183 | +<pre> |
| 184 | +common_user_role, common_app_role, read_only_role |
| 185 | +</pre> |
| 186 | +</td><td> |
| 187 | +<i>No default value. This parameter is optional.</i> |
| 188 | +</td></tr><tr><td> |
| 189 | +oracle.jdbc.provider.endUserSecurityContext.endUserContextAttributes |
| 190 | +</td><td> |
| 191 | +A fixed set of <code>END USER CONTEXT</code> attributes that apply to all end |
| 192 | +users. |
| 193 | +</td><td> |
| 194 | +This should be a JSON object containing the attributes of one or more |
| 195 | +<code>END USER CONTEXT</code> objects: |
| 196 | +<pre> |
| 197 | +{ |
| 198 | + "app_schema.user_details" : { |
| 199 | + "first_name" : "George", |
| 200 | + "last_name" : "Washington" |
| 201 | + }, |
| 202 | + "app_schema.location_info" : { |
| 203 | + "City" : "Mount Vernon", |
| 204 | + "State" : "Virginia", |
| 205 | + "Country" : "United States" |
| 206 | + } |
| 207 | +} |
| 208 | +</pre> |
| 209 | +The example above would be recognized as the attributes of two |
| 210 | +<code>END USER CONTEXT</code> named "user_details" and "location_info" declared |
| 211 | +within a database schema named "app_schema". |
| 212 | +</td><td> |
| 213 | +<i>No default value. This parameter is optional.</i> |
| 214 | +</td></tr><tr><td> |
| 215 | +oracle.jdbc.provider.endUserSecurityContext.authorityRolePrefix |
| 216 | +</td><td> |
| 217 | +The prefix used in the <code>String</code> representation of a |
| 218 | +<code>GrantedAuthority</code> that the provider should recognize as a |
| 219 | +<code>DATA ROLE</code>. The name of the <code>DATA ROLE</code> should appear |
| 220 | +after the prefix. For example, this parameter might be set to |
| 221 | +"ORACLE_DATA_ROLE_" and a <code>GrantedAuthority</code> could have the |
| 222 | +<code>String</code> representation of <code>ORACLE_DATA_ROLE_ADMIN</code>. |
| 223 | +The provider will recognize this <code>GrantedAuthority</code> as a |
| 224 | +<code>DATA ROLE</code> named "ADMIN", and will enable that |
| 225 | +<code>DATA ROLE</code> for the end user. |
| 226 | +</td><td> |
| 227 | +This should be a unique string that is unlikely to collide with a |
| 228 | +<code>String</code> representation used by any other |
| 229 | +<code>GrantedAuthority</code> that is not intended to be recognized as a |
| 230 | +<code>DATA ROLE</code>. |
| 231 | +</td><td> |
| 232 | +<i>No default value. This parameter is optional.</i> |
| 233 | +</td></tr><tr><td> |
| 234 | +oracle.jdbc.provider.endUserSecurityContext.authorityAttributePrefix |
| 235 | +</td><td> |
| 236 | +The prefix used in the <code>String</code> representation of a |
| 237 | +<code>GrantedAuthority</code> that the provider should recognize as |
| 238 | +a JSON object containing the attributes of one or more |
| 239 | +<code>END USER CONTEXT</code>. The JSON object should appear |
| 240 | +after the prefix. For example, this parameter might be set to |
| 241 | +"ORACLE_CONTEXT_ATTRIBUTE_" and a <code>GrantedAuthority</code> |
| 242 | +might have the following <code>String</code> representation, including the line |
| 243 | +breaks: |
| 244 | +<pre> |
| 245 | +ORACLE_CONTEXT_ATTRIBUTE_{ |
| 246 | + "app_schema.user_details" : { |
| 247 | + "first_name" : "George", |
| 248 | + "last_name" : "Washington" |
| 249 | + }, |
| 250 | + "app_schema.location_info" : { |
| 251 | + "City" : "Mount Vernon", |
| 252 | + "State" : "Virginia", |
| 253 | + "Country" : "United States" |
| 254 | + } |
| 255 | +} |
| 256 | +</pre> |
| 257 | +The provider will recognize this <code>GrantedAuthority</code> as the attributes |
| 258 | +of two <code>END USER CONTEXT</code> named "user_details" and "location_info" |
| 259 | +declared within a database schema named "app_schema", and it will apply these |
| 260 | +attributes to the end user. |
| 261 | +</td><td> |
| 262 | +This should be a unique string that is unlikely to collide with a |
| 263 | +<code>String</code> representation used by any other |
| 264 | +<code>GrantedAuthority</code> that is not intended to be recognized as |
| 265 | +<code>END USER CONTEXT</code> attributes. |
| 266 | +</td><td> |
| 267 | +ORACLE_CONTEXT_ATTRIBUTE_ |
| 268 | +</td></tr></tbody></table> |
0 commit comments