2 回答

TA貢獻1815條經驗 獲得超13個贊
這是在mybatis-spring的幫助下完成您需要的操作的簡單方法。
除非您已經使用 mybatis-spring,否則第一步是更改項目的配置,以便您使用SqlSessionFactory
mybatis?org.mybatis.spring.SqlSessionFactoryBean
-spring 提供的功能。
下一步是設置/重置連接的用戶角色。在mybatis中,連接生命周期由實現接口的類控制org.apache.ibatis.transaction.Transaction
。查詢執行器使用此類的實例來獲取連接。
簡而言之,您需要創建自己的此類實現并配置 mybatis 來使用它。
您的實現可以基于SpringManagedTransaction
mybatis-spring ,并且看起來像:
import org.springframework.security.core.Authentication;
class UserRoleAwareSpringManagedTransaction extends SpringManagedTransaction {
? public UserRoleAwareSpringManagedTransaction(DataSource dataSource) {
? ? super(dataSource);
? }
? @Override
? public Connection getConnection() throws SQLException {
? ? Connection connection = getCurrentConnection();
? ? setUserRole(connection);
? ? return connection;
? }
? private Connection getCurrentConnection() {
? ? return super.getConnection();
? }
? @Override
? public void close() throws SQLException {
? ? resetUserRole(getCurrentConnection());
? ? super.close();
? }??
? private void setUserRole(Connection connection) {
? ? Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
? ? String username = authentication.getName();
? ? Statement statement = connection.createStatement();
? ? try {
? ? ? // note that this direct usage of usernmae is a subject for SQL injection
? ? ? // so you need to use the suggestion from
? ? ? // https://stackoverflow.com/questions/2998597/switch-role-after-connecting-to-database
? ? ? // about encoding of the username
? ? ? statement.execute("set role '" + username + "'");
? ? } finally {
? ? ? statement.close();
? ? }
? }
? private void resetUserRole(Connection connection) {
? ? Statement statement = connection.createStatement();
? ? try {
? ? ? statement.execute("reset role");
? ? } finally {
? ? ? statement.close();
? ? }
? }
}
現在您需要配置 mybatis 來使用您的Transaction
實現。為此,您需要實現TransactionFactory
類似于mybatis-springorg.mybatis.spring.transaction.SpringManagedTransactionFactory
提供的功能:
public class UserRoleAwareSpringManagedTransactionFactory implements TransactionFactory {
? @Override
? public Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit) {
? ? return new UserRoleAwareSpringManagedTransaction(dataSource);
? }
? @Override
? public Transaction newTransaction(Connection conn) {
? ? throw new UnsupportedOperationException("New Spring transactions require a DataSource");
? }
? @Override
? public void setProperties(Properties props) {
? }
}
然后UserRoleAwareSpringManagedTransactionFactory在 spring 上下文中定義一個類型的 bean 并將其注入到spring 上下文中transactionFactory的屬性中。SqlSessionFactoryBeen
現在mybatis每次獲取到Connection執行Transaction都會設置當前的spring security用戶來設置角色。

TA貢獻1851條經驗 獲得超3個贊
最佳實踐是數據庫用戶是應用程序。應用程序用戶對特定數據/資源的訪問應在應用程序中進行控制。應用程序不應依賴數據庫來限制數據/資源訪問。因此,應用程序用戶不應該在數據庫中具有不同的角色。應用程序應僅使用單個數據庫用戶帳戶。
Spring是最佳實踐的體現。因此Spring并沒有實現這個功能。如果你想要這樣的功能,你需要破解。您最好的選擇是:
@Autowired JdbcTemplate jdbcTemplate;?
// ...
public runPerUserSql() {
? ? jdbcTemplate.execute("set role user 'user_1';");
? ? jdbcTemplate.execute("SELECT 1;");
}
對此我還是沒有太大的信心。除非您正在為多個用戶編寫 pgAdmin Web 應用程序,否則您應該重新考慮您的方法和設計。
添加回答
舉報