iServer 提供了 Storage 接口来实现用户、角色、权限等安全信息的存储与管理。在实现自定义的存储方式时,需要实现Storage,形式如下:

public class JsonStorage implements Storage {
...
}

实现使用json文件来存储安全信息,本例将实现:

  • 用户的存储:获取用户列表,以及添加、删除、修改用户
  • 角色的存储:获取角色列表,以及添加、删除、修改角色
  • 用户组的存储:获取用户组列表,以及添加、删除、修改用户组
  • 用户、用户组、角色之间的关联信息
  • 为角色授权
  • 获取服务的授权信息

相应的方法包括:

功能类别 方法 描述
用户 getUsers(int startIndex, int expectCount) getUser(String name) addUser(User toAdd) removeUsers(String[] names) alterUser(String name, User user) authenticate(String username, char[] password) 获取、添加、删除、修改用户,以及将用户账户信息写入。  
角色 getRole(String name) getRoles(String username, Set<String> groups) getRoles(int startIndex, int expectCount) addRole(Role toAdd) removeRoles(String[] names) alterRole(String name, Role role) containOne(String[] roles, String theRole) insertRole(String roleName, String description) getRolePermissions(String[] names) setRolePermissions(String roleName, RolePermissions permission, ServiceBeanPermission[] permissions) 获取、添加、删除、修改角色,在存储文件中插入角色信息,以及获取、设置角色授权。  
用户组 getGroups(int startIndex, int expectCount) getGroups(String username) addUserGroup(UserGroup toAdd) removeUserGroups(String[] names) alterUserGroup(String name, UserGroup userGroup) insertGroups(String GroupName, String description) 获取、添加、删除、修改用户组,以及将用户组信息写入。  
权限 getPublicServiceNames() getPermission(String user, Collection<? extends String> groups, Collection<? extends String> roles, Set<String> resourceIds) getInstanceAuthorisations() updateInstanceAuthorisation(String name, AuthorizeSetting authorizeSetting) insert(ServiceBeanPermission[] permissions) 获取服务列表,获取用户的授权信息,获取、更新服务实例的授权状态,以及将权限信息写入。

 

其他需要实现的方法有:

  • resetStorageSetting() ,设置使用扩展的json存储方式
    //设置使用扩展的json存储方式。
    @Override
    public void resetStorageSetting(SecurityInfoStorageSetting setting) {
        if (!(setting instanceof JsonStorageSetting)) {
            throw new IllegalArgumentException("only recieve JsonStorageSetting");
        }
        this.init((JsonStorageSetting) setting);
    }
  • init() ,读取配置的存储位置,并初始化一个json文件,用于存储安全信息
    //读取配置的存储位置,并初始化一个json文件,用于存储安全信息。
    private void init(JsonStorageSetting setting) {
        String appFilePath = Tool.getApplicationPath(setting.outputDirectory);
        this.storageFile = new File(appFilePath, SECURITY_FILE_NAME);
        if (!this.storageFile.exists()) {
            if (!this.storageFile.getParentFile().exists()) {
                try {
                    FileUtils.forceMkdirParent(this.storageFile);
                } catch (IOException e) {
                    throw new IllegalStateException("failed to make storage directory ");
                }
            }
            try {
                this.storageFile.createNewFile();
            } catch (IOException e) {
                throw new IllegalStateException("failed to make storage file ");
            }
            this.addPredefinedRoles();
            this.addPredefinedGroups();
        } else {
            this.setMapContent();
        }
    }
    @SuppressWarnings("unchecked")
    private void setMapContent() {
        try {
            String json = FileUtils.readFileToString(this.storageFile, UTF_8);
            Map<string, ?=""> statusMap = FastJSONUtils.parse(json, HashMap.class);
            if (statusMap.containsKey(TAG_USERS)) {
                this.users = (Map<string, user="">) statusMap.get(TAG_USERS);
            }
            if (statusMap.containsKey(TAG_ROLES)) {
                this.roles = (Map<string, role="">) statusMap.get(TAG_ROLES);
            }
            if (statusMap.containsKey(TAG_USERGROUPS)) {
                this.userGroups = (Map<string, usergroup="">) statusMap.get(TAG_USERGROUPS);
            }
            if (statusMap.containsKey(TAG_ROLEPERMISSIONS)) {
                this.rolePermissions = (Map<string, rolepermissions="">) statusMap.get(TAG_ROLEPERMISSIONS);
            }
            if (statusMap.containsKey(TAG_AUTHORIZESETTING)) {
                this.authorizeSetting = (Map<string, authorizesetting="">) statusMap.get(TAG_AUTHORIZESETTING);
            }
            if (statusMap.containsKey(TAG_SERVICEBEANPERMISSION)) {
                this.serviceBeanPermission = (Map<string, servicebeanpermission="">) statusMap.get(TAG_SERVICEBEANPERMISSION);
            }
        } catch (IOException e) {
            throw new IllegalStateException("JsonStorage init failed ");
        }
    }
  • persistenceToFile(),把安全信息的当前状态,包括所有用户、角色、用户组以及权限的状态持久化到存储文件中
    //把安全信息的当前状态,包括所有用户、角色、用户组以及权限的状态持久化到存储文件中。
    private void persistenceToFile() {
        Map<string, object=""> status = new HashMap<string, object="">();
        status.put(TAG_USERS, users);
        status.put(TAG_ROLES, roles);
        status.put(TAG_USERGROUPS, userGroups);
        status.put(TAG_ROLEPERMISSIONS, rolePermissions);
        status.put(TAG_AUTHORIZESETTING, authorizeSetting);
        status.put(TAG_SERVICEBEANPERMISSION, serviceBeanPermission);
        String jsonStatus = FastJSONUtils.toFastJson(status);
        jsonStatus = jsonFormat(jsonStatus);
        try {
            FileUtils.write(this.storageFile, jsonStatus, UTF_8);
        } catch (IOException e) {
            System.out.println("fail to persistence to " + this.storageFile.getAbsolutePath());
        }
    }
  • batchGet() ,批量查询
    //批量查询。
    private 	 QueryResult	 batchGet(int startIndex, int expectCount, List	 list) {
        int actualCount = expectCount;
        int size = list.size();
        if (expectCount > size - startIndex || expectCount == 0) {
            actualCount = size - startIndex;
        }
        List	 founds = new ArrayList	();
        if (startIndex <= size)="" {="" int="" index="startIndex;" findcount="0;" while="" (findcount="" <="" actualcount)="" founds.add(list.get(index));="" index++;="" findcount++;="" }="" queryresult<t=""> queryResult = new QueryResult	();
        queryResult.records = founds;
        queryResult.totalCount = size;
        return queryResult;
    }
  • ResolvingRolePermission() ,解析角色授权信息,使之转化为可存储的字符串。
    //解析角色授权信息,使之转化为可存储的字符串。
    private static class ResolvingRolePermission {
        List<string> allowedCom = new LinkedList<string>();
        List<string> deniedCom = new LinkedList<string>();
        List<string> allowedService = new LinkedList<string>();
        List<string> deniedService = new LinkedList<string>();
        boolean isPublisher = false;
        public RolePermissions toRolePermission() {
            RolePermissions result = new RolePermissions();
            result.publishEnabled = isPublisher;
            result.componentManagerPermissions = new MixedPermissions();
            result.componentManagerPermissions.denied = toArray(deniedCom);
            result.componentManagerPermissions.permitted = toArray(allowedCom);
            result.instanceAccessPermissions = new MixedPermissions();
            result.instanceAccessPermissions.denied = toArray(deniedService);
            result.instanceAccessPermissions.permitted = toArray(allowedService);
            return result;
        }
        void add(int resourceType, String resourceName, int perm) {
            List<string> list = null;
            switch (resourceType) {
            case RESOURCE_TYPE_PUBLISH: {
                isPublisher = true;
                break;
            }
            case RESOURCE_TYPE_COMPONENT: {
                list = isAllowManageComponent(perm) ? allowedCom : deniedCom;
                break;
            }
            case RESOURCE_TYPE_SERVICE: {
                list = isAllowAccessService(perm) ? allowedService : deniedService;
                break;
            }
            }
            if (list != null) {
                list.add(resourceName);
            }
        }
    }
    private static String[] toArray(List<string> list) {
        return list.isEmpty() ? ArrayUtils.EMPTY_STRING_ARRAY : list.toArray(new String[list.size()]);
    }

 

完整的扩展示例类如下:

NationalCacheStandardTileSourceInfo.java