- 浏览: 483215 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
龘龘龘:
TrueBrian 写道有个问题,Sample 1中,为了控制 ...
What's New on Java 7 Phaser -
龘龘龘:
楼主总结的不错。
What's New on Java 7 Phaser -
TrueBrian:
有个问题,Sample 1中,为了控制线程的启动时机,博主实际 ...
What's New on Java 7 Phaser -
liguanqun811:
不知道楼主是否对zookeeper实现的分布式锁进行过性能测试 ...
Distributed Lock -
hobitton:
mysql的get lock有版本限制,否则get lock可 ...
Distributed Lock
本文部分内容节选自Enterprise JavaBeans 3.0 by Bill Burke & Richard Monson-Haefel
5 Security
EJB规范虽然规定了如何将安全信息从客户端传递到服务器,但是EJB规范并没有规定客户端如何取得安全信息,也没有规定如何进行验证。对于大多数应用服务器而言,JNDI验证是最为常见的一种方式。客户端在与JNDI InitialContext建立连接时进行验证,之后在调用远程EJB时,安全信息会传递到服务器并在服务器中进行传播。验证的执行过程是将一个或者多个角色与给定的用户进行关联。用户一旦通过了验证,应用服务器会对该用户进行授权。与验证不同,EJB规范对授权进行了明确的定义。
5.1 JAAS
OpenEJB可以使用标准的JAAS机制来实现验证和授权。通常情况下,你需要通过设置java.security.auth.login.config系统属性来配置login modules的配置文件。如果没有指定这个系统属性,那么缺省会使用login.config作为文件名。以下是conf目录下一个login.config文件的例子:
PropertiesLogin {
org.apache.openejb.core.security.jaas.PropertiesLoginModule required
Debug=true
UsersFile="users.properties"
GroupsFile="groups.properties";
};
以上文件中指定了org.apache.openejb.core.security.jaas.PropertiesLoginModule作为login module。同时指定了users.properties和groups.properties,其内容分别如下:
conf/users.properties
Kevin=password
WhiteSock=password
conf/groups.propertie
Manager=Kevin
Employee=Kevin,WhiteSock
以下是修改后的MovieDaoJpaImpl.java:
@Stateful @TransactionAttribute(TransactionAttributeType.REQUIRED) public class MovieDaoJpaImpl implements MovieDaoJpaLocal, MovieDaoJpaRemote { // @PersistenceContext(unitName = "movie", type = PersistenceContextType.TRANSACTION) private EntityManager entityManager; @SuppressWarnings("unchecked") @PermitAll public List<Movie> getAllMovies() { Query query = entityManager.createQuery("SELECT m from Movie as m"); return query.getResultList(); } @RolesAllowed({"Employee", "Manager"}) public void addMovies(List<Movie> movies) { for(Movie m : movies) { entityManager.persist(m); } } @RolesAllowed({"Manager"}) public void deleteMovie(Movie movie) { Movie m = entityManager.merge(movie); entityManager.remove(m); } }
public static void main(String args[]) throws Exception { // Properties properties = new Properties(); properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.RemoteInitialContextFactory"); properties.setProperty(Context.PROVIDER_URL, "ejbd://localhost:4201"); properties.setProperty(Context.SECURITY_PRINCIPAL, "Kevin"); properties.setProperty(Context.SECURITY_CREDENTIALS, "password"); InitialContext ctx = new InitialContext(properties); // List<Movie> movies = new ArrayList<Movie>(); movies.add(new Movie("Dances with Wolves", "Kevin Costner", 1990)); movies.add(new Movie("Legends of the Fall", "Edward Zwich", 1994)); movies.add(new Movie("A Very Long Engagement", "Jean-Pierre Jeunet", 2004)); // Object ref = ctx.lookup("MovieDaoJpaImplRemote"); MovieDaoJpaRemote dao = (MovieDaoJpaRemote) PortableRemoteObject.narrow(ref, MovieDaoJpaRemote.class); dao.addMovies(movies); for(Movie m : dao.getAllMovies()) { System.out.println("dao.getAllMovies(): " + m); dao.deleteMovie(m); } }
以上代码中,如果尝试以"WhiteSock"作为Context.SECURITY_PRINCIPAL进行登陆,那么在执行到dao.deleteMovie(m)时,会抛出javax.ejb.EJBAccessException异常。
5.2 Plug Points
OpenEJB的安全机制有多种扩展点,其中最复杂的方式是实现SecurityService接口。OpenEJB的缺省实现是SecurityServiceImpl,它继承自AbstractSecurityService。在conf/openejb.xml中通过以下方式进行配置:
<SecurityService id="My Default Security Service"> className org.apache.openejb.core.security.SecurityServiceImpl realmName PropertiesLogin </SecurityService>
如果采用JAAS进行验证授权,那么有一种比较简单的扩展方式是定制LoginModule。以下是个简单的例子:
import java.io.IOException; import java.security.Principal; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.naming.InitialContext; import javax.security.auth.Subject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; import javax.sql.DataSource; import org.apache.openejb.core.security.jaas.GroupPrincipal; import org.apache.openejb.core.security.jaas.UserPrincipal; public class JdbcLoginModule implements LoginModule { // private boolean debug; // private User user; private Subject subject; private CallbackHandler callbackHandler; private Set<Principal> principals = new HashSet<Principal>(); public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) { // this.subject = subject; this.callbackHandler = callbackHandler; debug = "true".equalsIgnoreCase((String)options.get("Debug")); // if(debug) { System.out.println("# in JdbcLoginModule.initialize()"); } } public boolean login() throws LoginException { // if(debug) { System.out.println("# in JdbcLoginModule.login()"); } // Callback[] callbacks = new Callback[2]; callbacks[0] = new NameCallback("Username: "); callbacks[1] = new PasswordCallback("Password: ", false); try { callbackHandler.handle(callbacks); } catch (IOException ioe) { throw new LoginException(ioe.getMessage()); } catch (UnsupportedCallbackException uce) { throw new LoginException(uce.getMessage() + " not available to obtain information from user"); } // String name = ((NameCallback) callbacks[0]).getName(); char[] password = ((PasswordCallback) callbacks[1]).getPassword(); if (password == null) password = new char[0]; // List<User> users; try { users = getUser(name, new String(password)); } catch (Exception e) { throw new RuntimeException("failed to get user by name: " + name, e); } if(users != null && users.size() == 1) { user = users.get(0); } else { throw new LoginException("invalid user name: " + name); } // return true; } public boolean commit() throws LoginException { // if(debug) { System.out.println("# in JdbcLoginModule.commit()"); } // principals.add(new UserPrincipal(user.getName())); for(Role r : user.getRoles()) { principals.add(new GroupPrincipal(r.getName())); } subject.getPrincipals().addAll(principals); return true; } public boolean logout() throws LoginException { // if(debug) { System.out.println("# in JdbcLoginModule.logout()"); } // subject.getPrincipals().removeAll(principals); principals.clear(); return true; } public boolean abort() throws LoginException { // if(debug) { System.out.println("# in JdbcLoginModule.abort()"); } // subject.getPrincipals().removeAll(principals); principals.clear(); return true; } private List<User> getUser(String name, String password) throws Exception { // InitialContext ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup("java:openejb/Resource/mysqlDataSource"); // boolean succeed = false; Connection con = null; Map<Integer, User> users = new HashMap<Integer, User>(); try { // con = ds.getConnection(); PreparedStatement pstmt = con.prepareStatement("select " + "u.id as user_id, u.name as user_name, " + "r.id as role_id, r.name as role_name " + "from user u, role r, user_role ur " + "where u.id = ur.user_id and r.id = ur.roles_id " + "and u.name = ? and u.password = ?"); pstmt.setString(1, name); pstmt.setString(2, password); // ResultSet rs = pstmt.executeQuery(); while ( rs.next() ) { // Integer userId = rs.getInt("user_id"); String userName = rs.getString("user_name"); User user = users.get(userId); if(user == null) { user = new User(); user.setId(userId.intValue()); user.setName(userName); users.put(userId, user); } if(user.getRoles() == null) { user.setRoles(new ArrayList<Role>()); } // Role role = new Role(); role.setId(rs.getInt("role_id")); role.setName(rs.getString("role_name")); user.getRoles().add(role); } rs.close(); pstmt.close(); // succeed = true; } finally { if(con != null) { try { con.close(); } catch(Exception e) { if(succeed) { throw e; } } } } // List<User> r = new ArrayList<User>(); r.addAll(users.values()); return r; } }
在login.config中配置JdbcLogin realm,例如:
JdbcLogin {
com.yourpackage.JdbcLoginModule required
Debug=true;
};
conf/openejb.xml中的相关配置如下:
<Resource id="mysqlDataSource" type="DataSource"> JdbcDriver com.mysql.jdbc.Driver JdbcUrl jdbc:mysql://localhost:3306/ejb UserName root Password password JtaManaged true </Resource> <SecurityService id="My Default Security Service"> className org.apache.openejb.core.security.SecurityServiceImpl realmName JdbcLogin </SecurityService>
数据库中的相关表如下:
mysql> select * from user; +----+-----------+----------+ | id | name | password | +----+-----------+----------+ | 1 | Kevin | password | | 2 | WhiteSock | password | +----+-----------+----------+ mysql> select * from role; +----+----------+ | id | name | +----+----------+ | 1 | Manager | | 2 | Employee | +----+----------+ mysql> select * from user_role; +---------+----------+ | User_id | roles_id | +---------+----------+ | 1 | 1 | | 2 | 2 | | 2 | 1 | +---------+----------+
发表评论
-
Terracotta in Action (3)
2009-03-25 09:20 51453 Inside Terracotta 3.1 Core T ... -
Terracotta in Action (2)
2009-03-21 21:09 47022. Terracotta Eclipse Plugin ... -
Terracotta in Action (1)
2009-03-19 21:52 62861. Introduction Terraco ... -
OpenEJB (3)
2008-05-11 09:04 2728本文部分内容节选自Enterprise JavaBeans 3 ... -
OpenEJB (2)
2008-05-11 09:03 3321本文部分内容节选自Enterprise JavaBeans 3 ... -
OpenEJB (1)
2008-05-10 22:39 5111本文部分内容节选自Enterprise JavaBeans 3 ... -
OpenJPA (7)
2008-03-25 21:56 357510 Miscellaneous Features 10 ... -
OpenJPA (6)
2008-03-23 21:33 63438 Object Locking 8.1 Configu ... -
OpenJPA (5)
2008-03-18 22:38 50527 Inheritance 对象使用引用以便关联到其 ... -
OpenJPA (4)
2008-03-11 23:27 71116 Query 6.1 JPQL Queries 6.1. ... -
OpenJPA (3)
2008-03-09 23:09 52554 EntityManagerFactory 4.1 Ove ... -
OpenJPA (2)
2008-03-05 23:59 72993 Metadata 通过javax.persist ... -
OpenJPA (1)
2008-03-04 23:11 68821 Overview Apache OpenJPA是 ... -
ActiveMQ in Action (7)
2008-02-27 14:33 126792.6.7 Wildcards Wil ... -
ActiveMQ in Action (6)
2008-02-26 15:22 137992.6 Features ActiveMQ包含了很多 ... -
ActiveMQ in Action (5)
2008-02-26 00:35 136022.5 Clustering ActiveMQ从多种 ... -
ActiveMQ in Action (4)
2008-02-26 00:21 112792.4 Security ActiveMQ ... -
ActiveMQ in Action (3)
2008-02-26 00:16 106382.3 Persistence 2.3.1 AMQ Mess ... -
ActiveMQ in Action (2)
2008-02-25 23:58 132782.2 Transport ActiveMQ目前支持 ... -
ActiveMQ in Action (1)
2008-02-25 23:18 238811 JMS 在介绍ActiveMQ ...
相关推荐
4. **事务管理** EJB 3.0 支持声明式事务管理,通过注解如 `@TransactionAttribute` 可以控制事务的传播属性。OpenEJB 3.0 实现了这些功能,允许开发者专注于业务逻辑,而无需过多关注底层事务细节。 5. **远程...
4. **打包EJB项目**: 使用jar命令或者Maven、Gradle等构建工具将EJB项目打包成ejb-jar文件。 5. **创建Web项目**: 创建一个普通的Web项目,其中包含对EJB的引用。在web.xml文件中配置JNDI查找,以便Web应用程序...
标题中的"openejb-embedded-maven-plugin-4.6.0.1.zip"是一个开源项目的Maven插件包,特别地,它是OpenEJB的嵌入式版本。OpenEJB是一个开源的企业JavaBeans(EJB)容器和服务器,它实现了Java EE(现在称为Jakarta ...
4. **开源文化**:开源项目意味着源代码对公众开放,鼓励开发者参与、贡献和改进项目。这种模式促进了技术创新,降低了软件开发的成本,并且往往带来更广泛的社区支持和持续的改进。 5. **版本控制与Git**:"jersey...
目前Tomcat并不直接支持EJB,但可借助openejb插件来间接能够支持EJB
标签:arquillian-openejb-embedded-4-4.6.0.jar,arquillian,openejb,embedded,4,4.6.0,jar包下载,依赖包
标签:arquillian-openejb-embedded-4-4.5.1.jar,arquillian,openejb,embedded,4,4.5.1,jar包下载,依赖包
标签:arquillian-openejb-embedded-4-4.7.0.jar,arquillian,openejb,embedded,4,4.7.0,jar包下载,依赖包
标签:arquillian-openejb-embedded-4-4.7.1.jar,arquillian,openejb,embedded,4,4.7.1,jar包下载,依赖包
标签:arquillian-openejb-embedded-4-4.5.2.jar,arquillian,openejb,embedded,4,4.5.2,jar包下载,依赖包
标签:arquillian-openejb-embedded-4-4.5.0.jar,arquillian,openejb,embedded,4,4.5.0,jar包下载,依赖包
标签:arquillian-openejb-embedded-4-4.5.1-sources.jar,arquillian,openejb,embedded,4,4.5.1,sources,jar包下载,依赖包
标签:arquillian-openejb-embedded-4-4.6.0.2.jar,arquillian,openejb,embedded,4,4.6.0.2,jar包下载,依赖包
标签:arquillian-openejb-embedded-4-4.7.1-javadoc.jar,arquillian,openejb,embedded,4,4.7.1,javadoc,jar包下载,依赖包
标签:arquillian-openejb-embedded-4-4.6.0-sources.jar,arquillian,openejb,embedded,4,4.6.0,sources,jar包下载,依赖包
标签:arquillian-openejb-embedded-4-4.5.2-sources.jar,arquillian,openejb,embedded,4,4.5.2,sources,jar包下载,依赖包
标签:arquillian-openejb-embedded-4-4.6.0-javadoc.jar,arquillian,openejb,embedded,4,4.6.0,javadoc,jar包下载,依赖包
标签:arquillian-openejb-embedded-4-4.5.0-javadoc.jar,arquillian,openejb,embedded,4,4.5.0,javadoc,jar包下载,依赖包
标签:arquillian-openejb-embedded-4-4.7.0-javadoc.jar,arquillian,openejb,embedded,4,4.7.0,javadoc,jar包下载,依赖包
标签:arquillian-openejb-embedded-4-4.7.1-sources.jar,arquillian,openejb,embedded,4,4.7.1,sources,jar包下载,依赖包