Skip to content

Commit

Permalink
添加权限验证功能
Browse files Browse the repository at this point in the history
  • Loading branch information
angilin committed Apr 9, 2014
1 parent d4b9e30 commit 9929d6f
Show file tree
Hide file tree
Showing 10 changed files with 159 additions and 85 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,5 @@ SysRoleAr.hbm.xml
ArchiveDao.java
ArchiveService.java
FtpAccess.java
ArchiveServiceTest.java
ArchiveServiceTest.java
MapConvertUtil.java
2 changes: 1 addition & 1 deletion WebRoot/WEB-INF/.struts-config.mex
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<FlowViewLayout Version="1.2">
<StrutsActivity path="/login.do" location="50,50" dimension="233,104" />
<StrutsActivity path="/logout.do" location="950,50" dimension="257,104" />
<StrutsActivity path="/index.jsp" location="350,50" dimension="88,53" />
<StrutsActivity path="/login.jsp" location="650,50" dimension="86,53" />
<StrutsActivity path="/logout.do" location="950,50" dimension="257,104" />
<StrutsTransition id="/logout.do,success,/login.jsp,1" routingType="0">
<AutomaticBendpoints>
<AbsolutePoint location="950,88" />
Expand Down
45 changes: 24 additions & 21 deletions WebRoot/WEB-INF/struts-config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,33 @@
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">

<struts-config>
<data-sources />
<form-beans >
<form-bean name="LoginForm" type="com.rbac.form.system.LoginForm" />
<data-sources />
<form-beans>
<form-bean name="LoginForm"
type="com.rbac.form.system.LoginForm" />

</form-beans>
</form-beans>

<global-exceptions />
<global-forwards />
<action-mappings >
<action
attribute="LoginForm"
input="/login.jsp"
name="LoginForm"
path="/login"
scope="request"
type="com.rbac.action.system.LoginAction">
<forward name="success" path="/index.jsp" />
</action>
<action path="/logout" type="com.rbac.action.system.LogoutAction">
<forward name="success" path="/login.jsp" />
</action>
<global-exceptions />
<global-forwards />
<action-mappings>
<action attribute="LoginForm" input="/login.jsp"
name="LoginForm" path="/login" scope="request"
type="com.rbac.action.system.LoginAction">
<forward name="success" path="/index.jsp" />
</action>
<action path="/logout"
type="com.rbac.action.system.LogoutAction">
<forward name="success" path="/login.jsp" />
</action>

</action-mappings>
</action-mappings>

<message-resources parameter="config.ApplicationResources" />
<controller>
<set-property property="processorClass"
value="com.rbac.common.MvcRequestProcessor" />
</controller>

<message-resources parameter="config.ApplicationResources" />
</struts-config>

2 changes: 1 addition & 1 deletion WebRoot/login.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<div><span style="width:100px">用户名:</span><html:text property="username"/></div>
<div><span style="width:100px">密&nbsp;&nbsp;码:</span><html:password property="password"/></div>
<center><html:submit property="submit" value="登录"/></center>
<div><font color="red">${errormsg}</font></div>
<div><font color="red"><c:out value="${error_msg}"/></font></div>
</div>
</html:form>
</body>
Expand Down
2 changes: 1 addition & 1 deletion src/com/rbac/action/system/LoginAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public ActionForward execute(ActionMapping mapping, ActionForm form,
return mapping.findForward("success");
}
}
request.setAttribute("errormsg", "用户名或密码不正确");
request.setAttribute(MvcConstant.ERROR_MSG, "用户名或密码不正确");
loginForm.setPassword("");

return mapping.getInputForward();
Expand Down
4 changes: 4 additions & 0 deletions src/com/rbac/common/MvcConstant.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@
*/
public class MvcConstant {

//session中取得用户信息的key值
public static final String USER = "com_user";

//首页出错信息
public static final String ERROR_MSG = "error_msg";
}
58 changes: 58 additions & 0 deletions src/com/rbac/common/MvcRequestProcessor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.rbac.common;

import java.io.IOException;
import java.util.Set;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.RequestProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;


public class MvcRequestProcessor extends RequestProcessor{

private ApplicationContext getCtx(HttpServletRequest request) {
ApplicationContext ctx = WebApplicationContextUtils
.getRequiredWebApplicationContext(request.getSession()
.getServletContext());
return ctx;
}

public boolean processRoles(HttpServletRequest request,
HttpServletResponse response, ActionMapping mapping)
throws IOException, ServletException {
HttpSession session = request.getSession();

// 如果访问的路径是登陆、登出则不需要权限验证
if (mapping.getPath().equals("/login")
|| mapping.getPath().equals("/logout")) {
return true;
}

// 如果没有登录,进行提示并返回到错误页面
if (session.getAttribute(MvcConstant.USER) == null) {
request.setAttribute(MvcConstant.ERROR_MSG, "请先登录系统");
RequestDispatcher rd = request.getRequestDispatcher("/login.jsp");
rd.forward(request, response);
return false;
}

//检查登录用户是否有权限访问该路径
UserDetail user = (UserDetail)session.getAttribute(MvcConstant.USER);
Set<String> permitActionSet = user.getPermitActionSet();
if(!permitActionSet.contains(mapping.getPath())){
request.setAttribute(MvcConstant.ERROR_MSG, "你没有权限访问该功能");
RequestDispatcher rd = request.getRequestDispatcher("/login.jsp");
rd.forward(request, response);
return false;
}

return true;
}
}
21 changes: 21 additions & 0 deletions src/com/rbac/dao/LoginDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@

import com.rbac.common.BaseDaoSupport;
import com.rbac.entity.SysAccount;
import com.rbac.entity.SysAction;
import com.rbac.entity.SysMenu;

@Component("loginDao")
public class LoginDao extends BaseDaoSupport {

/**
* 根据用户名查找用户
* @param username
* @return
*/
public SysAccount getSysAccountByUsername(String username) {
List list = super.getSession().createCriteria(SysAccount.class).add(
Restrictions.eq("isDeleted", 0)).add(
Expand All @@ -22,8 +28,23 @@ public SysAccount getSysAccountByUsername(String username) {
return null;
}

/**
* 根据用户id查找菜单列表
* @param accountId
* @return
*/
public List getMenuListByAccountId(Long accountId){
String sql = "select m.* from sys_menu m where m.is_deleted=0 and m.ID in (select rm.menu_id from sys_role_menu rm where rm.is_deleted=0 and rm.ROLE_ID in (select ar.role_id from sys_account_role ar where ar.is_deleted=0 and ar.account_id=:accountId))";
return super.getSession().createSQLQuery(sql).addEntity(SysMenu.class).setLong("accountId", accountId).list();
}

/**
* 根据用户id查找权限列表
* @param accountId
* @return
*/
public List getActionListByAccountId(Long accountId){
String sql = "select a.* from sys_action a where a.is_deleted=0 and a.id in (select ma.action_id from sys_menu_action ma where ma.is_deleted=0 and ma.menu_id in (select rm.menu_id from sys_role_menu rm where rm.is_deleted=0 and rm.ROLE_ID in (select ar.role_id from sys_account_role ar where ar.is_deleted=0 and ar.account_id=:accountId)))";
return super.getSession().createSQLQuery(sql).addEntity(SysAction.class).setLong("accountId", accountId).list();
}
}
57 changes: 47 additions & 10 deletions src/com/rbac/service/LoginService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.json.me.JSONArray;
Expand All @@ -17,6 +19,7 @@
import com.rbac.common.UserDetail;
import com.rbac.dao.LoginDao;
import com.rbac.entity.SysAccount;
import com.rbac.entity.SysAction;
import com.rbac.entity.SysMenu;
import com.rbac.entity.SysMenuVo;
import com.rbac.util.PasswordHash;
Expand All @@ -27,6 +30,12 @@ public class LoginService {
@Autowired
private LoginDao loginDao;

/**
* 登录功能
* @param username
* @param password
* @return UserDetail
*/
public UserDetail login(String username, String password) {
// 就算根据用户名没找到用户,也要去调用验证密码方法,防止别人根据返回时间猜测用户名
SysAccount account = loginDao.getSysAccountByUsername(username);
Expand All @@ -44,9 +53,9 @@ public UserDetail login(String username, String password) {
if (PasswordHash.validatePassword(password, s.toString())) {
UserDetail userDetail = new UserDetail();
userDetail.setAccount(account);
userDetail.setMenuJsonString(this.getMenuJsonString(this
userDetail.setMenuJsonString(this.getMenuJsonString(loginDao
.getMenuListByAccountId(account.getId())));

userDetail.setPermitActionSet(this.getPermitActionSet(account.getId()));
return userDetail;
}
} catch (NoSuchAlgorithmException e) {
Expand All @@ -57,13 +66,32 @@ public UserDetail login(String username, String password) {

return null;
}

public List<SysMenu> getMenuListByAccountId(Long accountId) {
List<SysMenu> list = loginDao.getMenuListByAccountId(accountId);
return list;

/**
* 获取用户权限,包括菜单自身权限和菜单相关权限
* @param accountId
* @return
*/
private Set<String> getPermitActionSet(Long accountId){
Set<String> permitActionSet = new HashSet<String>();
List<SysMenu> menuList = loginDao.getMenuListByAccountId(accountId);
List<SysAction> actionList = loginDao.getActionListByAccountId(accountId);
for(SysMenu menu : menuList){
permitActionSet.add(menu.getUrl());
}
for(SysAction action : actionList){
permitActionSet.add(action.getUrl());
}
return permitActionSet;
}


public String getMenuJsonString(List<SysMenu> menuList) {
/**
* 菜单转json字符串
* @param menuList
* @return
*/
private String getMenuJsonString(List<SysMenu> menuList) {
List<SysMenuVo> levelOneMenuList = new ArrayList<SysMenuVo>();
List<SysMenuVo> todoMenuList = new ArrayList<SysMenuVo>();
for (SysMenu menu : menuList) {
Expand All @@ -85,15 +113,20 @@ public String getMenuJsonString(List<SysMenu> menuList) {
setMenuChilren(menuVo, todoMenuList);
}

// {id:"0",text:"菜单",expanded: true ,children:[{id:"2",text:"子菜单1",leaf
// : true}]}
// 菜单json模板
// {id:"0",text:"菜单",expanded: true ,children:[{id:"2",text:"子菜单1",leaf: true}]}
JSONArray array = new JSONArray();
for (SysMenuVo menuVo : levelOneMenuList) {
array.put(objToJson(menuVo));
}
return array.toString();
}

/**
* 菜单转json字符串,递归处理子菜单
* @param menu
* @param todoMenuList
*/
private void setMenuChilren(SysMenuVo menu, List<SysMenuVo> todoMenuList) {
ListIterator<SysMenuVo> it = todoMenuList.listIterator();
while (it.hasNext()) {
Expand All @@ -108,11 +141,15 @@ private void setMenuChilren(SysMenuVo menu, List<SysMenuVo> todoMenuList) {
Collections.sort(menu.getChildren());
}

/**
* 菜单实体转json对象
* @param menuVo
* @return
*/
private JSONObject objToJson(SysMenuVo menuVo) {
JSONObject obj = new JSONObject();
try {
obj.put("id", menuVo.getId());

obj.put("leaf", menuVo.getLeaf());
obj.put("text", menuVo.getText());
obj.put("url", menuVo.getUrl());
Expand Down
50 changes: 0 additions & 50 deletions src/com/rbac/util/MyHttpServletRequestWrapper.java

This file was deleted.

0 comments on commit 9929d6f

Please sign in to comment.