最近在写登陆策略配置LoginConfig模块,如今经过分析登陆策略配置模块来讲明系统的层次结构。系统后台主要包括四层:java
1. 数据库层:包括表、存储过程、实体类 2. 数据访问层:数据访问对象(也就是Dao层) 3. 后端逻辑层:查询与命令类 4. Rest接口层:资源类
登陆限制策略模块包括一张login_configs表,6个存储过程(Insertloginconfigs,Updateloginconfigs,Deleteloginconfigs,GetAllFromloginconfigs,GetloginconfigsById和GetloginconfigsByName),以及一个LoginConfis的实体类
LoginConfigs表格只有6个字段,在create_tables.sql中建立表格sql
//create_tables.sql CREATE TABLE login_configs ( loginconfig_id uuid NOT NULL, role_name character varying(255) NOT NULL, time_limit character varying(4000), ip_limit character varying(4000), mac_limit character varying(4000), other character varying(4000) );
存储过程:好比增长Insertloginconfigs数据库
CREATE OR REPLACE FUNCTION Insertloginconfigs( v_loginconfig_id uuid, v_role_name VARCHAR(255), v_time_limit VARCHAR(4000), v_ip_limit VARCHAR(4000), v_mac_limit VARCHAR(4000), v_other VARCHAR(4000) )RETURNS VOID AS $PROCEDURE$ BEGIN INSERT INTO login_configs (loginconfig_id,role_name,time_limit,ip_limit,mac_limit,other) VALUES (v_loginconfig_id,v_role_name,pgp_sym_encrypt(v_time_limit,'engine'),pgp_sym_encrypt(v_ip_limit,'engine'),pgp_sym_encrypt(v_mac_limit,'engine'),pgp_sym_encrypt(v_other,'engine')); END;$PROCEDURE$ LANGUAGE plpgsql;
实体类LoginConfig后端
public class LoginConfigs implements IVdcQueryable, BusinessEntity<Guid>{ private static final long serialVersionUID = 3090608330047174149L; //进程Id private Guid id; @Override public Guid getId() { return id; } @Override public void setId(Guid id) { this.id = id; } //角色名 private String roleName; public String getRoleName() { return roleName; } public void setRoleName(String roleName) { this.roleName = roleName; } //限制时间 private String timeLimit; public String getTimeLimit() { return timeLimit; } public void setTimeLimit(String timeLimit) { this.timeLimit = timeLimit; } //限制IP private String macLimit; public String getMacLimit() { return macLimit; } public void setMacLimit(String macLimit) { this.macLimit = macLimit; } //限制IP private String ipLimit; public String getIpLimit() { return ipLimit; } public void setIpLimit(String ipLimit) { this.ipLimit = ipLimit; } //预留字段 private String other; public String getOther() { return other; } public void setOther(String other) { this.other = other; } public LoginConfigs(){ id = Guid.Empty; roleName = ""; timeLimit = ""; ipLimit = ""; other = ""; } @Override public Object getQueryableId() { return getId(); } @Override public int hashCode() { return Objects.hash(id,roleName,timeLimit,ipLimit,other); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof LoginConfigs)) { return false; } LoginConfigs configs = (LoginConfigs) obj; return Objects.equals(id, configs.id) && Objects.equals(roleName, configs.roleName) && Objects.equals(timeLimit, configs.timeLimit) && Objects.equals(ipLimit, configs.ipLimit) && Objects.equals(other, configs.other); } }
添加完LoginConfigs.java后配置在Common.gwt.xml中,不然 将不能被部分包所使用session
DbFacade:数据库的外观器
LoginConfigsDao:数据访问对象接口层app
//LoginConfigsDao.java public interface LoginConfigsDao extends Dao,SearchDao<LoginConfigs>{ void save(LoginConfigs loginConfigs); void update(LoginConfigs loginConfigs); void detele(Guid id); LoginConfigs getById(Guid id); LoginConfigs getByName(String roleName); List<LoginConfigs> getAll(); }
LoginConfigsDaoImpl:数据访问对象实现类ide
public class LoginConfigsDaoImpl extends BaseDao implements LoginConfigsDao{ private RowMapper<LoginConfigs> loginConfigsRowMapper = (rs ,rowNum) -> { LoginConfigs entity = new LoginConfigs(); entity.setId(getGuidDefaultEmpty(rs,"loginconfig_id")); entity.setRoleName(rs.getString("role_name")); entity.setTimeLimit(rs.getString("time_limit")); entity.setIpLimit(rs.getString("ip_limit")); entity.setMacLimit(rs.getString("mac_limit")); entity.setOther(rs.getString("other")); return entity; }; @Override public List<LoginConfigs> getAllWithQuery(String query) { return null; } @Override public void save(LoginConfigs loginConfigs) { Guid id = loginConfigs.getId(); if(Guid.isNullOrEmpty(id)){ id = Guid.newGuid(); loginConfigs.setId(id); } getCallsHandler().executeModification("Insertloginconfigs",createFullParametersMapper(loginConfigs )); } @Override public void update(LoginConfigs loginConfigs) { getCallsHandler().executeModification("Updateloginconfigs", createFullParametersMapper(loginConfigs)); } @Override public void detele(Guid id) { getCallsHandler().executeModification("Deleteloginconfigs", createIdParameterMapper(id)); } @Override public LoginConfigs getById(Guid id) { return getCallsHandler().executeRead("GetloginconfigsById",loginConfigsRowMapper,createIdParameterMapper(id)); } @Override public LoginConfigs getByName(String roleName) { MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource().addValue("role_name", roleName); return getCallsHandler().executeRead("GetloginconfigsByName", loginConfigsRowMapper, parameterSource); } @Override public List<LoginConfigs> getAll() { return getCallsHandler().executeReadList("GetAllFromloginconfigs",loginConfigsRowMapper,getCustomMapSqlParameterSource()); } private MapSqlParameterSource createIdParameterMapper(Guid id){ return getCustomMapSqlParameterSource().addValue("loginconfig_id", id); } private MapSqlParameterSource createFullParametersMapper(LoginConfigs entity) { return createIdParameterMapper(entity.getId()) .addValue("ip_limit",entity.getIpLimit()) .addValue("mac_limit",entity.getMacLimit()) .addValue("time_limit",entity.getTimeLimit()) .addValue("role_name",entity.getRoleName()) .addValue("other",entity.getOther()); } }
后端逻辑层是对操做命令化,把每种操做请求都封装成命令的形式
[参数]ui
1. LoginConfigsOperationParameters 模块操做的基本参数类 2. AddLoginConfigsCommand 添加操做的参数类 3. RemoveLoginConfigsParameters 更新操做的参数类 4. UpdateLoginConfigsParameters 删除操做的参数类
【查询与命令】this
1. GetAllLoginConfigsQuery 获取全部登陆策略的查询类 2. GetLoginConfigByIdQuery 根据id获取指定的登陆策略的查询类 3. GetLoginConfigByNameQuery 根据角色名获取指定登陆策略的查询类 4. AddLoginConfigsCommand 添加LoginConfigs的命令类 5. RemoveLoginConfigsCommand 删除LoginConfigs的命令类 6. UpdateLoginConfigsCommand 更新LoginConfigs的命令类
【类型】日志
1. VdcActionType 动做类型集合 2. VdcQueryType 查询类型集合 3. VdcObjectType 对象类型集合 4. ActionGroup 动做组集合
//LoginConfigsOperationParameters.java 是全部操做的参数类的父类 public class LoginConfigsOperationParameters extends VdcActionParametersBase{ private static final long serialVersionUID = 3991635679508928037L; @Valid private LoginConfigs loginConfigs; public LoginConfigsOperationParameters(){ } public LoginConfigsOperationParameters(Guid id){ this.setId(id); loginConfigs.setId(id); } public LoginConfigsOperationParameters(LoginConfigs _loginConfigs){ loginConfigs = _loginConfigs; } public Guid getId(){ return loginConfigs == null ? null : loginConfigs.getId(); } public void setId(Guid id){ if(loginConfigs == null){ loginConfigs = new LoginConfigs(); } loginConfigs.setId(id); } public String getName(){ return loginConfigs == null ? null : loginConfigs.getRoleName(); } public void setName(String name){ if(loginConfigs == null){ loginConfigs = new LoginConfigs(); }else { loginConfigs.setRoleName(name); } } public LoginConfigs getLoginConfigs(){ return loginConfigs; } public void setLoginConfigs(LoginConfigs loginConfigs){ this.loginConfigs = loginConfigs; } }
添加操做的参数类
public class AddLoginConfigsParameters extends LoginConfigsOperationParameters{ private static final long serialVersionUID = -7832310521101821905L; public AddLoginConfigsParameters(LoginConfigs loginConfigs){ super(loginConfigs); } }
获取全部登陆策略的查询类
public class GetAllLoginConfigsQuery <P extends VdcQueryParametersBase> extends QueriesCommandBase<P>{ public GetAllLoginConfigsQuery(P parameters) { super(parameters); } @Override protected void executeQueryCommand() { getQueryReturnValue().setReturnValue(getDbFacade().getLoginConfigsDao().getAll()); } }
添加登陆限制策略的命令类
public class AddLoginConfigsCommand <T extends AddLoginConfigsParameters> extends AbstractCommand<T> { public AddLoginConfigsCommand(T parameters, CommandContext cmdContext) { super(parameters, cmdContext); } public AddLoginConfigsCommand(Guid commandId) { super(commandId); } @Override protected void executeCommand() { DbFacade dbFacade = DbFacade.getInstance(); getParameters().setId(Guid.newGuid()); DbUser user = getCurrentUser(); LoginConfigs configs = getParameters().getLoginConfigs(); if (configs == null) { setSucceeded(false); return; } String roleName = configs.getRoleName() == null ? "" : configs.getRoleName(); if (user != null) { if (user.getLoginName().equals("systemAdmin")) { setSucceeded(false); } else if (user.getLoginName().equals("securityAdmin")) { //保密员配置普通用户角色的登陆策略 if (roleName.contains("SystemAdmin") || roleName.contains("AuditAdmin")|| roleName.contains("UserRole")) { dbFacade.getLoginConfigsDao().save(configs); setSucceeded(true); } } else if (user.getLoginName().equals("auditAdmin")) { if (roleName.contains("SecurityAdmin")) { dbFacade.getLoginConfigsDao().save(configs); setSucceeded(true); } } } else { setSucceeded(false); } } //检测权限 @Override public List<PermissionSubject> getPermissionCheckSubjects() { return Collections.singletonList(new PermissionSubject(Guid.SYSTEM, VdcObjectType.System, ActionGroup.LOGIN_CONFIG)); } //记录日志 @Override public AuditLogType getAuditLogTypeValue() { return getSucceeded() ? AuditLogType.ADD_LOGIN_CONFIGS : AuditLogType.ADD_LOGIN_CONFIGS_ERROR; } }
VdcQueryType.java 对新增的查询类添加对应的枚举类
GetAllLoginConfigs(RoleType.USER), GetLoginConfigById(RoleType.USER), GetLoginConfigByName(RoleType.USER),
VdcActionType 对新增的命令类添加对应的枚举类
AddLoginConfigs(8004,ActionGroup.LOGIN_CONFIG,false,QuotaDependency.NONE), UpdateLoginConfigs(8005,ActionGroup.LOGIN_CONFIG,false,QuotaDependency.NONE), RemoveLoginConfigs(8006,ActionGroup.LOGIN_CONFIG,false,QuotaDependency.NONE),
ActionGroup 与角色权限有关
LOGIN_CONFIG(1701,RoleType.USER, false),
BackendLoginConfigsResource 主资源实现类
BackendLoginConfigResource 子资源实现类
BackendApiResource 后台应用类,用于分发请求
LoginConfigsResource 主资源接口类
LoginConfigResource 子资源接口类
SystemResource
LoginConfigsResource 主资源
@Produces(ApiMediaType.APPLICATION_JSON) public interface LoginConfigsResource { @POST @Consumes(ApiMediaType.APPLICATION_JSON) default Response add(LoginConfigs loginConfigs) { throw new UnsupportedOperationException(); } @GET default List<LoginConfigs> list() { throw new UnsupportedOperationException(); } @POST @Consumes(ApiMediaType.APPLICATION_JSON) @Path("getByname") default LoginConfigs getByName (LoginConfigs loginConfigs) { throw new UnsupportedOperationException(); } @Path("{id}") LoginConfigResource getLoginConfigResource(@PathParam("id") String id); }
LoginConfigResource 子资源
@Produces({ApiMediaType.APPLICATION_XML, ApiMediaType.APPLICATION_JSON}) public interface LoginConfigResource { @DELETE default Response remove() { throw new UnsupportedOperationException(); } @GET default LoginConfigs get() { throw new UnsupportedOperationException(); } @PUT @Consumes(ApiMediaType.APPLICATION_JSON) default LoginConfigs update(LoginConfigs loginConfigs) { throw new UnsupportedOperationException(); } }
BackendLoginConfigsResource 主资源实现类
public class BackendLoginConfigsResource extends BackendResource implements LoginConfigsResource { @Override public Response add(LoginConfigs loginConfigs) { return performAction(VdcActionType.AddLoginConfigs,new AddLoginConfigsParameters(loginConfigs)); } @Override public List<LoginConfigs> list() { VdcQueryReturnValue returnValue = runQuery(VdcQueryType.GetAllLoginConfigs, new VdcQueryParametersBase()); return returnValue.getReturnValue(); } @Override public LoginConfigs getByName(LoginConfigs loginConfigs) { String roleName = loginConfigs.getRoleName(); VdcQueryReturnValue returnValue = runQuery(VdcQueryType.GetLoginConfigByName, sessionize(new NameQueryParameters(roleName))); return returnValue.getReturnValue(); } @Override public LoginConfigResource getLoginConfigResource(String id) { return inject(new BackendLoginConfigResource(id)); } }
BackendLoginConfigsResource 子资源实现类
public class BackendLoginConfigResource extends BackendResource implements LoginConfigResource{ protected Guid id; public BackendLoginConfigResource(String id){ this.id = asGuid(id); } @Override public Response remove(){ return performAction(VdcActionType.RemoveLoginConfigs,new RemoveLoginConfigsParameters(id)); } @Override public LoginConfigs get(){ VdcQueryReturnValue returnValue = runQuery(VdcQueryType.GetLoginConfigById, sessionize(new IdQueryParameters(id))); return returnValue.getReturnValue(); } @Override public LoginConfigs update(LoginConfigs loginConfigs) { loginConfigs.setId(this.id); Response response = performAction(VdcActionType.UpdateLoginConfigs,new UpdateLoginConfigsParameters(loginConfigs)); if (response.getStatus() == 200) { return runQuery(VdcQueryType.GetLoginConfigById, sessionize(new IdQueryParameters(id))).getReturnValue(); } return null; } }
systemResource
@Path("/") @Produces(MediaType.APPLICATION_JSON) public interface SystemResource { @Path("loginConfigs") LoginConfigsResource getLoginConfigsResource(); .... }
至此登陆限制策略的后台接口已完成,可经过loginconfigs接口对登陆策略进行增删改查。这样实现起来简单明了,不过因为是根据角色定义登陆限制策略,同一种角色只有一种登陆限制策略,对不一样用户暂时不能作到多样性控制,后期再修正。还有就是有多条限制策略时都存在同一张表的同一个字段中,前台需作一些处理。