我们能够通过Apusic应用服务器的安全框架来自定义自己的安全提供程序,下面以一个例子来描述如何在Apusic应用服务器上开发一个自定义的安全提供程序
这里讲述了如何开发一个有效的安全提供程序,这个例子描述的是通过配置文件存储用户和组的信息。用户的信息存储在user.conf文件中,组的信息存储在group.conf文件中。内容如下:
#在group.conf文件中定义的组信息如下: group=administrator group=manager group=employee 在user.conf文件中定义的用户信息如下: user=admin password=admin group=administrator user=director password=director group=manager user=operater password=operator group=employee
上面介绍了实体信息的存储,下面我们可以通过SimpleStore.java来完成对实体信息的读取操作
//SimpleStore.java package com.apusic.demo.security.store; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.security.Principal; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Vector; public final class SimpleStore { //从group.conf中读取的组信息 private static final Map<String, SimpleGroup> groups = new HashMap<String, SimpleGroup>(); //从user.conf中读取的用户信息 private static final Map<String, Principal> users = new HashMap<String, Principal>(); private static final SimpleStore store = new SimpleStore(); static { try { String groupEntry = null; String groupName = null; String userEntry = null; String user = null; String roles[] = null; String password = null; String elements[] = null; SimpleGroup group = null; SimplePrincipal principal = null; //从group.conf中读取组信息 Iterator iterator = readEntry("group.conf"); while (iterator.hasNext()) { groupEntry = (String) iterator.next(); if (groupEntry == null) { continue; } elements = groupEntry.split("="); if (elements.length == 2 && elements[0].equals("group")) { groupName = elements[1]; groups.put(groupName, new SimpleGroup(groupName)); } } //从user.conf中读取用户信息,并设置用户所在的组 iterator = readEntry("user.conf"); while (iterator.hasNext()) { userEntry = (String) iterator.next(); if (userEntry == null) { continue; } elements = userEntry.split("\t"); if (elements.length == 3 && elements[0].startsWith("user=") && elements[1].startsWith("password=") && elements[2].startsWith("group=")) { user = elements[0].substring(5); password = elements[1].substring(9); roles = elements[2].substring(6).split(","); principal = new SimplePrincipal(user, password); users.put(user, principal); for (String role : roles) { group = groups.get(role); if (group != null) { group.addMember(principal); } } } } } catch (Exception e) { e.printStackTrace(); } } public static SimpleStore getStore() { return store; } public SimpleGroup getGroup(String group) { return groups.get(group); } public Principal getUser(String user) { return users.get(user); } private static Iterator readEntry(String file) throws IOException { Vector vector = new Vector(); BufferedReader buffer = new BufferedReader(new FileReader(file)); String entry = null; while (true) { entry = buffer.readLine(); if (entry == null) { break; } if (entry.trim().length() == 0 || entry.startsWith("#")) { continue; } vector.add(entry); } vector.add(entry); return vector.iterator(); } }
为了实现自己的身份验证提供程序,我们需要实现com.apusic.security.realm.AuthenticationProvider接口,并实现下面的方法,示例如下:
//SimpleAuthentication实现 package com.apusic.demo.security.provider; import java.security.Principal; import com.apusic.demo.security.store.SimplePrincipal; import com.apusic.demo.security.store.SimpleStore; import com.apusic.security.Password; import com.apusic.security.User; import com.apusic.security.auth.login.PasswordCredential; import com.apusic.security.config.RealmConfig; import com.apusic.security.realm.AuthenticationProvider; import com.apusic.security.realm.InitialException; public class SimpleAuthentication implements AuthenticationProvider{ private SimpleStore store = SimpleStore.getStore(); //实现通过user.conf文件中查找是否存在对应的用户 public boolean authenticate(Object user, Object password) { Principal principal = store.getUser((String) user); if (principal == null) { return false; } String pwd = new String(((PasswordCredential) password).getPassword()); if (principal instanceof SimplePrincipal) { return ((SimplePrincipal)principal).getPassword().equals(pwd); } return false; } //用户的Provider可以不实现该接口,一般内部使用 public boolean authenticate(Object user, Object password, byte[] random) { return false; } //资源的销毁 public void destroy() { } //实现通过user.conf文件中查找是否存在对应的用户 public Object findUser(String userId) { User user = null; Password password = null; Principal principal = store.getUser(userId); if (principal == null) { return user; } if (principal instanceof SimplePrincipal) { password = new Password(((SimplePrincipal)principal).getPassword()); user = new User(userId,password); } return user; } //用来完成一些初始化工作,如读取在security.xml文件中配置的参数...等信息 public void init(RealmConfig config) throws InitialException { } }
为了实现自己的授权验证提供程序,我们需要实现com.apusic.security.realm.AuthorizationProvider接口,并实现相关方法。示例如下:
//SimpleAuthorization实现 package com.apusic.demo.security.provider; import java.security.acl.Group; import com.apusic.demo.security.store.SimpleStore; import com.apusic.security.config.RealmConfig; import com.apusic.security.realm.AuthorizationProvider; import com.apusic.security.realm.InitialException; public class SimpleAuthorization implements AuthorizationProvider{ //资源的销毁 public void destroy() { } //实现通过group.conf文件中查找对应的组信息 public Group getGroup(String name) { return SimpleStore.getStore().getGroup(name); } //用来完成一些初始化工作,如读取在security.xml文件中配置的参数...等信息 public void init(RealmConfig config) throws InitialException { } } //SimpleGroup实现 package com.apusic.demo.security.store; import java.security.Principal; import java.security.acl.Group; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.List; public class SimpleGroup implements Group{ private List<Principal> members ; private String name = null; public SimpleGroup(String name) { this.name = name; members = new ArrayList<Principal>(); } public boolean addMember(Principal user) { return members.add(user); } public boolean isMember(Principal member) { return members.contains(member); } public Enumeration<? extends Principal> members() { return Collections.enumeration(members); } public boolean removeMember(Principal user) { return members.remove(user); } public String getName() { return this.name; } }
完成了上面的验证提供程序和授权提供程序后,我们需要在%DOMAIN_HOME%/config/security.xml文件中添加该安全提供程序,配置如下:
<realm> <realm-name>SimpleRealm</realm-name> <provider-type>Simple Provider</provider-type> <authentication-provider>com.apusic.demo.security.SimpleAuthentication</authentication-provider> <authorization-provider>com.apusic.demo.security.SimpleAuthorization</authorization-provider> </realm>
到现在我们就可以在我们自己应用的apusic-application.xml文件中的指定下面的信息,通过SimpleRealm实现安全验证和授权。
<realm-name>SimpleRealm</realm-name>