粗粒度权限管理(拦截是否登录、拦截用户名admin权限)
RBAC是什么?
RBAC 是基于角色的访问控制(Role-Based Access Control )在 RBAC 中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便。
今天我们使用过滤器,实现一个简单的RBAC的Demo程序。
一、页面划分
计划分为三个页面,index.jsp,users.jsp,admin.jsp。
- index.jsp:所有的用户都可以访问,我们称之为游客界面。
- users.jsp:只有会员用户可以访问,我们称之为会员界面。
- admin.jsp:只有管理员用户可以访问,我们称之为管理员界面。
三个页面都有相互跳转的链接,有权限的前提下,可以跳转到其他页面。
例如:管理员界面:
我们的登录页面也相对简单一些,只给出用户名表单即可,
我们简单的根据用户名来判断是哪种用户,就不再使用连接数据库这种复杂的方式,如:判断用户名中是否包含admin,如果包含就是管理员,反之就不是。
登录界面核心代码
<body>
<h1>登录</h1>
<form action="<c:url value='/LoginServlet'/>" method="post">
用户名:
<input type="text" name="username" />
<input type="submit" value="登录" />
</form>
</body>
LoginServlet核心代码
public class LoginServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
/*
* 获取用户名,
* 判断用户名中是否包含admin:
* 如果包含就是管理员,反之就不是。
* 把登录的用户名称保存到session中。
* 成功之后转发到index.jsp
*/
String username = request.getParameter("username");
if(username.contains("admin")){
request.getSession().setAttribute("admin", username);
}else {
request.getSession().setAttribute("username", username);
}
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
}
二、过滤器部分
根据上面我们的设定,users文件夹下和admin文件夹下的网页访问是有限制的。
访问users,session中应该有一个名为username或者admin的键值对;
访问admin,session中应该有一个名为admin的键值对。
所以我们需要两个过滤器,分别来检测对这两个文件夹的访问。
1.UserFilter代码
public class UserFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
/*
* 得到session, 判断session域中是否存在admin,如果存在就放行。
* 判断session域中是否存在username,如果存在就放行。
*
* 否则,直接打回到login.jsp,并告诉它不要瞎溜达
*/
HttpServletRequest request2 = (HttpServletRequest) request;
String name = (String) request2.getSession().getAttribute("admin");
if (name != null) {
chain.doFilter(request, response);
return;
}
name = (String) request2.getSession().getAttribute("username");
if (name != null) {
chain.doFilter(request, response);
return;
}else {
request2.setAttribute("msg", "您瞅你那损色!不是会员,也不是管理员,请不要瞎溜达!");
request2.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
2.AdminFilter代码
public class AdminFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
/*
* 得到session, 判断session域中是否存在admin,如果存在就放行。
* 否则,直接打回到login.jsp,并告诉它不要瞎溜达
*/
HttpServletRequest request2 = (HttpServletRequest) request;
String name = (String) request2.getSession().getAttribute("admin");
if (name != null) {
chain.doFilter(request, response);
return;
} else {
request2.setAttribute("msg", "您不是管理员,这不是你该来的地方!");
request2.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
3. login.jsp的完善
我们还应该在login.jsp上添加回显的信息,加上${msg }
即可。
<body>
<h1>登录</h1>
${msg }
<form action="<c:url value='/LoginServlet'/>" method="post">
用户名:
<input type="text" name="username" />
<input type="submit" value="登录" />
</form>
</body>
三、测试
我们的功能是符合我们的预期的!
END.