RBAC

基于角色的权限访问控制(Role-Based Access Control)在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色。角色可依新的需求和系统的合并而赋予新的权限,而权限也可根据需要而从某角色中回收。

在IEDA中,打开DATABASE菜单,连接数据库

一共5张表,很好理解,

用户和角色的关系:一个用户可以拥有多个角色,相反一个角色也可以被多个用户所拥有

角色和权限的关系:一个角色可以拥有多个权限,相反一个权限也可以被多个角色所拥有

建库和表的sql我这里就不贴了,好了,前期的配置到此就结束了,接下来下面正式进入开发之旅。。。。。。。。。。

//实现用户的登录--拦截认证--密码加密后验证登录

login.jsp

<%--
Created by IntelliJ IDEA.
User: shaojiang
Date: //
Time: 下午7:
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="renderer" content="webkit|ie-comp|ie-stand">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
<!--[if lt IE ]>
<script type="text/javascript" src="/statics/lib/html5shiv.js"></script>
<script type="text/javascript" src="/statics/lib/respond.min.js"></script>
<![endif]-->
<link href="/statics/h-ui/css/H-ui.min.css" rel="stylesheet" type="text/css" />
<link href="/statics/h-ui.admin/css/H-ui.login.css" rel="stylesheet" type="text/css" />
<link href="/statics/h-ui.admin/css/style.css" rel="stylesheet" type="text/css" />
<link href="/statics/lib/Hui-iconfont/1.0.8/iconfont.css" rel="stylesheet" type="text/css" />
<!--[if IE ]>
<script type="text/javascript" src="/statics/lib/DD_belatedPNG_0.0.8a-min.js" ></script>
<script>DD_belatedPNG.fix('*');</script>
<![endif]-->
<title>JavaEE权限管理系统</title>
<meta name="keywords" content="H-ui.admin v3.1,H-ui网站后台模版,后台模版下载,后台管理系统模版,HTML后台模版下载">
<meta name="description" content="H-ui.admin v3.1,是一款由国人开发的轻量级扁平化网站后台模板,完全免费开源的网站后台管理系统模版,适合中小型CMS后台系统。">
</head>
<body>
<input type="hidden" id="TenantId" name="TenantId" value="" />
<div class="header">JavaEE权限管理系统</div>
<div class="loginWraper">
<div id="loginform" class="loginBox">
<form id="login_form1" class="form form-horizontal" onsubmit="return false" action="##" method="post">
<div style="color: red;text-align: center;">${requestScope.loginError}</div>
<div class="row cl">
<label class="form-label col-xs-3"><i class="Hui-iconfont"></i></label>
<div class="formControls col-xs-8">
<input id="userName" name="userName" type="text" placeholder="账户" class="input-text size-L">
</div>
</div>
<div class="row cl">
<label class="form-label col-xs-3"><i class="Hui-iconfont"></i></label>
<div class="formControls col-xs-8">
<input id="password" name="password" type="password" placeholder="密码" class="input-text size-L">
</div>
</div>
<%--<div class="row cl">--%>
<%--<div class="formControls col-xs-8 col-xs-offset-3">--%>
<%--<input class="input-text size-L" type="text" placeholder="验证码" onblur="if(this.value==''){this.value='验证码:'}" onclick="if(this.value=='验证码:'){this.value='';}" value="验证码:" style="width:150px;">--%>
<%--<img src=""> <a id="kanbuq" href="javascript:;">看不清,换一张</a> </div>--%>
<%--</div>--%>
<div class="row cl">
<div class="formControls col-xs-8 col-xs-offset-3">
<label for="rememberMe">
<input type="checkbox" name="rememberMe" id="rememberMe" value="">
使我保持登录状态</label>
</div>
</div>
<div class="row cl">
<div class="formControls col-xs-8 col-xs-offset-3">
<input id="sub_login" name="" type="button" class="btn btn-success radius size-L" value="&nbsp;登&nbsp;&nbsp;&nbsp;&nbsp;录&nbsp;">
<%--<input name="" type="reset" class="btn btn-default radius size-L" value="&nbsp;取&nbsp;&nbsp;&nbsp;&nbsp;消&nbsp;">--%>
</div>
</div>
</form>
</div>
</div>
<div class="footer">Copyright 通用权限管理系统 by H-ui.admin v3.</div>
<script type="text/javascript" src="/statics/lib/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="/statics/h-ui/js/H-ui.min.js"></script>
<script type="text/javascript" src="/statics/lib/layer/2.4/layer.js"></script>
<script type="text/javascript"> //当登录超时,会跳转到登录页面,如果在框架中加载了登录页,首先进行判断,如果不是顶级路径,就导致顶级路径
if (window.top!=window.self) {
//alert("执行了");
window.top.location.href = '/admin/login';
} $(function()
{ // 读取cookies中的用户信息
var rem = $.cookie('rememberMe');
if(rem){
$("#rememberMe").prop("checked",true);
$("#userName").val($.cookie("username"));
$("#password").val($.cookie("password"));
} //登录
$("#sub_login").click(function () { var username = $("#userName").val();
var password = $("#password").val(); if(!username){
layer.msg("请输入用户名");
$("#userName").focus().select();
return false;
}else if(!password){
layer.msg("请输入登录密码");
$("#password").focus().select();
return false;
}else
{
//验证是否需要保存账户信息到cookies
saveCookies();
//alert($('#login_form1').serialize());
//登录系统
$.ajax({
//几个参数需要注意一下
type: "POST",//方法类型
dataType: "json",//预期服务器返回的数据类型
url: "/admin/login" ,//url
data: $('#login_form1').serialize(),
success: function (data) {
console.log(data.result);//打印服务端返回的数据(调试用)
if (data.result == 'SUCCESS'||data.result == ) {
window.location.href = "/admin/main";
}else
{
layer.msg("登录失败:"+data.result.toString(),{icon:,time:});
}
},
error : function() {
layer.msg(data.result.toString());
}
}); } });
}); /**
* jquery.cookie.js 是一个轻量级的cookie 插件,可以读取、写入、删除 cookie。
* H-ui.js 中已封装jquery.cookie.js,无需单独下载。
*/
function saveCookies() { if($("#rememberMe").is(":checked")){
//alert("记住我");
var username = $("#userName").val();
var password = $("#password").val(); //创建一个cookie并设置有效时间为 7天:
//如果没有指定有效期,所创建的cookie有效期默认到用户关闭浏览器为止
$.cookie("rememberMe","true",{expires:});
$.cookie("username",username,{expires: });
$.cookie("password",password,{expires: });
}else{
$.cookie("rememberMe","false",{expires:-});
$.cookie("username","",{ expires:- });
$.cookie("password","",{ expires:- });
}
} </script>
</body>
</html>

AdminController

    /**
* 管理员登录
* @return
*/
@RequestMapping(value = "/login",method = RequestMethod.POST)
@ResponseBody
public Map<String,Object> adminLogin(
HttpServletRequest request,
HttpSession session)
{
Map<String,Object> resultMap = new HashMap<String,Object>(); if(request.getParameter("userName")==null||
request.getParameter("password")==null){
resultMap.put("result","用户名或密码不能为空");
} //获取用户名和密码
String userName = request.getParameter("userName").toString();
String password = request.getParameter("password").toString(); //查询数据库该用户是否存在
AdminUser adminUser = adminUserService.findAdminUserByLoginName(userName); if(adminUser!=null){
//logger.info("adminUser:"+adminUser.toString());
//将用户的密码进行加密后返回,再进行比对
String encryptPassword =
passwordEncryption.encryption(password,
adminUser.getLoginName().toString());
if(adminUser.getLoginName().equals(userName)&&
adminUser.getPassword().equals(encryptPassword))
{
if(adminUser.getState()==){
//验证通过,保存登录信息到session,转发到管理员后台控制器
session.setAttribute("adminUser",adminUser);
resultMap.put("result","SUCCESS");
}else
{
resultMap.put("result","账户异常!请联系系统管理员!");
}
}else
{
resultMap.put("result","用户名或密码错误!");
}
}else
{
resultMap.put("result","用户名不存在!");
} return resultMap;
}

登录时用到了passwordEncryption服务类,该类负责进行密码的加密,当用户登录时,将用户的密码进行加密,这里加密的规则,是把当前用户名作为盐值,使用sha-256算法,散列次数5,进行加密,加密后,再使用Base64进行编码,加密后根据当前登录的用户名查询该用户的数据库储存的加密密码比对是否一致,如果一致,登录成功。

使用自动注入引用

@Autowired
private PasswordEncryption passwordEncryption;

我是放在了service子模块中的,这样子方便扫描

PasswordEncryption类:

package com.supin51.service.impl;

import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import java.io.Serializable; /**
* @Author:ShaoJiang
* @description: apache shiro 的SimpleHash工具类加密
* @Date: created in 上午10:57 2019/1/26
* @Modified By:
*/
@Service
public class PasswordEncryption{ /**
* 基于注解的装配,这样可以在encrypt.properties属性文件中更改配置,在这里使用@Value进行注解装配获取到值
   * 后期如果需要更改加密类型,可在属性文件中更改其他算法:md5,sha1,sha-128,sha-256,sha-512
* 使用@Value的类,在spring中,不能直接通过new 操作符来使用,这样获取不到值的
* 而是在需要使用的地方,通过spring的注解 @Autowired 来使用,
* 例如:@Autowired private PasswordEncryption passwordEncryption;
*/
@Value("${algorithmName}")
private String algorithmName;//加密算法,md5,sha1,sha-128,sha-256,sha-512
@Value("${hashIterations}")
private int hashIterations;//散列次数
@Value("${isHex}")
private boolean isHex;//是否使用十六进制编码,设置false后将启用Base64编码 /**
* 密码加密
* @param password 加密前的密码
* @param salt 盐值(传递当前的用户名用作盐值)
* @return
*/
public String encryption(String password, String salt)
{
String encryptStr = "";
if(isHex)
{
//使用十六进制进行编码
//带salt(盐值)和散列加密后,再用十六进制编码
encryptStr =
new SimpleHash(algorithmName,password,salt,hashIterations).toHex();
//System.out.print("十六进制编码");
}else
{
//使用Base64进行编码
//带salt(盐值)和散列加密后,再用Base64编码
encryptStr =
new SimpleHash(algorithmName,password,salt,hashIterations).toBase64();
//System.out.print("Base64编码");
}
return encryptStr;
} }

应为拦截了所有路径,所以还要添加认证拦截器:

AuthenticationInterceptor类:

package com.supin51.interceptor;

import com.supin51.domain.AdminUser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* @Author:ShaoJiang
* @description:登录认证拦截
* @Date: created in 下午8:18 2019/1/21
* @Modified By:
*/
public class AuthenticationInterceptor implements HandlerInterceptor { private static final Log logger = LogFactory.getLog(AuthenticationInterceptor.class); //定义不需要拦截的URL路径
private static final String[] NO_INTERCEPTOR_URL = {"/admin/login","/404","/favicon.ico"}; /*
* return true 才会继续执行下列两个方法(请求继续),否则整个请求结束
* 该方法主要进行拦截处理,该方法在Controller处理之前调用,
* */
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { boolean flag = false;
//获取请求的路径进行判断
String servletUrl = request.getServletPath();
logger.info("url认证拦截器:preHandle-------->"+servletUrl);
//循环拦截的URL路径,如果当前请求的URL中包含需要拦截的URL,返回true
for (String s :NO_INTERCEPTOR_URL)
{
if(servletUrl.contains(s)){ flag = true;
break;
}
} //拦截请求
if(!flag){
//获取session中的用户信息
AdminUser adminUser = (AdminUser)request.getSession().getAttribute("adminUser");
//如果用户已登录,放行,否则拦截
if(adminUser!=null){
logger.info("url认证拦截器:preHandle-------->用户已登录,放行请求-------->");
flag = true;
}else
{
logger.info("url认证拦截器:preHandle-------->用户未登录,拦截请求-------->"); request.setAttribute("message","登录信息失效,请重新登录");
//只适合跳转页面,URL地址保持不变
//request.getRequestDispatcher("user1/login").forward(request,response);
response.sendRedirect("/admin/login");//重定向到控制器,URL地址改变
}
} return flag;
} @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
logger.info("url认证拦截器:postHandle-------->");
} @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
logger.info("url认证拦截器:afterCompletion-------->");
}
}

至此,整个登录的实现流程结束。本小节结束,下一小节将实现,登录成功后的权限菜单显示,基于自定义注解方法级别的权限菜单的拦截验证。

 

JavaEE权限管理系统的搭建(四)--------使用拦截器实现登录认证和apache shiro密码加密的更多相关文章

  1. JavaEE权限管理系统的搭建(六)--------使用拦截器实现菜单URL的跳转权限验证和页面的三级菜单权限按钮显示

    本小结讲解,点击菜单进行页面跳转,看下图,点击管理员列表后会被认证拦截器首先拦截,验证用户是否登录,如果登录就放行,紧接着会被权限验证拦截器再次拦截,拦截的时候,会根据URL地址上找到对应的方法,然后 ...

  2. JavaEE权限管理系统的搭建(一)--------项目中用到的知识点概括

    转战Java有一段时间了,.net 已不再开发的新的工程,基本上在维护,最近大半年时间在学习Java,今天抽空将学习的到的知识,应用到了一个权限管理系统的小项目中,特此记录一下.代码如有不对之处,希望 ...

  3. JavaEE权限管理系统的搭建(八)--------角色的增删改

    如下图所示,添加角色的同时,要给角色分配权限菜单,关于权限数的显示,我实现了两种方式,普通方式和Ztree方式, 普通方式展示树: 主要代码部分: /** * 进入角色添加页面 * @param mo ...

  4. JavaEE权限管理系统的搭建(三)--------springmvc和mabatis整合环境搭建

    本节介绍如何环境的搭建和配置: 首先要在父工程引入jar包依赖: <!-- 通过属性定义指定jar的版本 --> <properties> <spring.version ...

  5. SpringMVC拦截器实现登录认证(转发)

    感谢原作者,转发自:http://blog.csdn.net/u014427391/article/details/51419521 以Demo的形式讲诉拦截器的使用 项目结构如图: 需要的jar:有 ...

  6. SpringMVC拦截器实现登录认证

    项目结构如图: 需要的jar:有springMVC配置需要的jar和jstl需要的jar SpringMVC包的作用说明: aopalliance.jar:这个包是AOP联盟的API包,里面包含了针对 ...

  7. JavaEE权限管理系统的搭建(五)--------RBAC权限管理中的权限菜单的显示

    上一小节实现了登录的实现,本小节实现登录后根据用户名查询当前用户的角色所关联的所有权限,然后进行菜单的显示.登录成功后,如下图所示,管理设置是一级菜单,管理员列表,角色管理,权限管理是二级菜单. 先来 ...

  8. JavaEE权限管理系统的搭建(二)--------聚合工程项目的创建和依赖关系

    本项目是一个聚合工程,所以要先搭建一个聚合工程的框架 搭建完成的项目结构图如下: 首先创建父项目:pom类型 子模块:web层的搭建,war类型 把这个两个目录标记为对应的类型 其他子模块:和serv ...

  9. JavaEE权限管理系统的搭建(七)--------管理用户的增删改

    本小结讲解管理用户的增删改查实现, 首先是添加用户,如下图所示,可以看到添加用户的同时也要给用户分配角色,至少给用户分配一个或者是多个角色 页面js部分: $.ajax({ //几个参数需要注意一下 ...

随机推荐

  1. import java.util.Collections类

    Collections类提供了一些操作集合的方法  下面介绍几个方法 1.将集合变为线程安全的 三个方法分别对应了ArrayList,HashMap,HashSet: Collections.sync ...

  2. [转]微信小程序开发(二)图片上传+服务端接收

    本文转自:http://blog.csdn.net/sk719887916/article/details/54312573 文/YXJ 地址:http://blog.csdn.net/sk71988 ...

  3. sqlServer游标的使用

    USE [PatPD1]GO/****** Object:  UserDefinedFunction [dbo].[fun_GetConditionInner]    Script Date: 201 ...

  4. C# 实现OrderBy按多个字段排序

    //倒序 list.OrderByDescending(i => i.a).ThenByDescending(i => i.b); //顺序 list.OrderBy(i => i. ...

  5. Jquery系列:textarea常用操作

    1.textarea内容的读取与设置 读textarea文本值可以用name和id.而写入文本值只能用id. <textarea name="content" id=&quo ...

  6. WinSock 重叠IO模型

    title: WinSock 重叠IO模型 tags: [WinSock 模型, 网络编程, 重叠IO模型] date: 2018-06-29 20:26:13 categories: Windows ...

  7. Stage6--Python简单爬虫

    正则表达式简单介绍 正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串.将匹配的子串做替换或者从某个串中取出符合某个条件的子串等. 字符 ...

  8. win环境下jdk7与jdk8共存问题

    1.jdk安装包 安装步骤略 2.jdk等配置文件修改 在安装JDK1.8时(本机先安装jdk1.7再安装的jdk1.8),会将java.exe.javaw.exe.javaws.exe三个文件cop ...

  9. python 函数,内置函数

    1.函数 1.1 定义函数 ·函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 (). ·任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数. ·函数的第一行语句可以选择性 ...

  10. mac 上配置 maven

    1. 将maven压缩包解压至/Users/suqiuhui/Applications目录下的新建文件夹dev下 2. 打开终端(系统根目录,~/下) 3. 如果没有 .bash_profile 文件 ...