转载:https://z77z.oschina.io/

一、引入依赖

shiro-all包含shiro所有的包、shiro-core是核心包、shiro-web是与web整合、shiro-spring是与spring整合、shiro-ehcache是与EHCache整合、shiro-quartz是与任务调度quartz整合等等。

<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.2</version>
</dependency> <dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.2.2</version>
</dependency> <dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.2.2</version>
</dependency> <dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.2</version>
</dependency>

二、导入数据库

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for u_permission
-- ----------------------------
DROP TABLE IF EXISTS `u_permission`;
CREATE TABLE `u_permission` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`url` varchar(256) DEFAULT NULL COMMENT 'url地址',
`name` varchar(64) DEFAULT NULL COMMENT 'url描述',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of u_permission
-- ----------------------------
INSERT INTO `u_permission` VALUES ('', '/user/select', '用户查询');
INSERT INTO `u_permission` VALUES ('', '/admin/add', '管理员添加');
INSERT INTO `u_permission` VALUES ('', '/admin/delete', '管理员删除'); -- ----------------------------
-- Table structure for u_role
-- ----------------------------
DROP TABLE IF EXISTS `u_role`;
CREATE TABLE `u_role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(32) DEFAULT NULL COMMENT '角色名称',
`type` varchar(10) DEFAULT NULL COMMENT '角色类型',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of u_role
-- ----------------------------
INSERT INTO `u_role` VALUES ('', 'admin', '');
INSERT INTO `u_role` VALUES ('', 'user', '');
INSERT INTO `u_role` VALUES ('', 'visitor', ''); -- ----------------------------
-- Table structure for u_role_permission
-- ----------------------------
DROP TABLE IF EXISTS `u_role_permission`;
CREATE TABLE `u_role_permission` (
`rid` bigint(20) DEFAULT NULL COMMENT '角色ID',
`pid` bigint(20) DEFAULT NULL COMMENT '权限ID'
) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of u_role_permission
-- ----------------------------
INSERT INTO `u_role_permission` VALUES ('', '');
INSERT INTO `u_role_permission` VALUES ('', '');
INSERT INTO `u_role_permission` VALUES ('', ''); -- ----------------------------
-- Table structure for u_user
-- ----------------------------
DROP TABLE IF EXISTS `u_user`;
CREATE TABLE `u_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`nickname` varchar(20) DEFAULT NULL COMMENT '用户昵称',
`email` varchar(128) DEFAULT NULL COMMENT '邮箱|登录帐号',
`pswd` varchar(32) DEFAULT NULL COMMENT '密码',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`last_login_time` datetime DEFAULT NULL COMMENT '最后登录时间',
`status` bigint(1) DEFAULT '' COMMENT '1:有效,0:禁止登录',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of u_user
-- ----------------------------
INSERT INTO `u_user` VALUES ('', 'admin', null, '', '2017-05-10 20:22:59', null, '');
INSERT INTO `u_user` VALUES ('', 'user', null, '', null, null, ''); -- ----------------------------
-- Table structure for u_user_role
-- ----------------------------
DROP TABLE IF EXISTS `u_user_role`;
CREATE TABLE `u_user_role` (
`uid` bigint(20) DEFAULT NULL COMMENT '用户ID',
`rid` bigint(20) DEFAULT NULL COMMENT '角色ID'
) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of u_user_role
-- ----------------------------
INSERT INTO `u_user_role` VALUES ('', '');
INSERT INTO `u_user_role` VALUES ('', '');
SET FOREIGN_KEY_CHECKS=1;

三、Controller层

@RestController
public class AdminController { private static Logger logger = LoggerFactory.getLogger(AdminController.class); @Autowired
private URoleDao uRoleDao; //跳转到登录表单页面
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String login() {
return "need login";
} //登录成功后,跳转的页面
@RequestMapping("/success")
public String index(Model model) {
return "success";
} //未登录,可以访问的页面
@RequestMapping("/index")
public String list(Model model) {
return "index";
} //登陆验证,这里方便url测试,正式上线需要使用POST方式提交
@RequestMapping(value = "/ajaxLogin", method = RequestMethod.GET)
public String index(UUser user) {
if (user.getNickname() != null && user.getPswd() != null) {
UsernamePasswordToken token = new UsernamePasswordToken(user.getNickname(), user.getPswd(), "login");
Subject currentUser = SecurityUtils.getSubject();
logger.info("对用户[" + user.getNickname() + "]进行登录验证..验证开始");
try {
currentUser.login( token );
//验证是否登录成功
if (currentUser.isAuthenticated()) {
logger.info("用户[" + user.getNickname() + "]登录认证通过(这里可以进行一些认证通过后的一些系统参数初始化操作)");
System.out.println("用户[" + user.getNickname() + "]登录认证通过(这里可以进行一些认证通过后的一些系统参数初始化操作)");
return "redirect:/";
} else {
token.clear();
System.out.println("用户[" + user.getNickname() + "]登录认证失败,重新登陆");
return "redirect:/login";
}
} catch ( UnknownAccountException uae ) {
logger.info("对用户[" + user.getNickname() + "]进行登录验证..验证失败-username wasn't in the system");
} catch ( IncorrectCredentialsException ice ) {
logger.info("对用户[" + user.getNickname() + "]进行登录验证..验证失败-password didn't match");
} catch ( LockedAccountException lae ) {
logger.info("对用户[" + user.getNickname() + "]进行登录验证..验证失败-account is locked in the system");
} catch ( AuthenticationException ae ) {
logger.error(ae.getMessage());
}
}
return "login";
} /**
* ajax登录请求接口方式登陆
* @param username
* @param password
* @return
*/
@RequestMapping(value="/ajaxLogin",method= RequestMethod.POST)
@ResponseBody
public Map<String,Object> submitLogin(@RequestParam(value = "nickname") String username, @RequestParam(value = "pswd") String password) {
Map<String, Object> resultMap = new LinkedHashMap<String, Object>();
try { UsernamePasswordToken token = new UsernamePasswordToken(username, password);
SecurityUtils.getSubject().login(token);
resultMap.put("status", 200);
resultMap.put("message", "登录成功"); } catch (Exception e) {
resultMap.put("status", 500);
resultMap.put("message", e.getMessage());
}
return resultMap;
} //登出
@RequestMapping(value = "/logout")
public String logout(){
return "logout";
} //错误页面展示
@GetMapping("/403")
public String error(){
return "error ok!";
} //管理员功能
@RequiresRoles("admin")
@RequiresPermissions("管理员添加")
@RequestMapping(value = "/admin/add")
public String create(){
return "add success!";
} //用户功能
@RequiresRoles("user")
@RequiresPermissions("用户查询")
@RequestMapping(value = "/user/select")
public String detail(){
return "select success";
  }
}

四、shiro配置

1.shiroConfiguration.java

@Configuration
public class ShiroConfiguration {
/**
* ShiroFilterFactoryBean 处理拦截资源文件问题。
* 注意:单独一个ShiroFilterFactoryBean配置是或报错的,以为在
* 初始化ShiroFilterFactoryBean的时候需要注入:SecurityManager
*
* Filter Chain定义说明 1、一个URL可以配置多个Filter,使用逗号分隔 2、当设置多个过滤器时,全部验证通过,才视为通过
* 3、部分过滤器可指定参数,如perms,roles
*
*/ @Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
} @Bean(name = "shiroRealm")
@DependsOn("lifecycleBeanPostProcessor")
public ShiroRealm shiroRealm() {
ShiroRealm realm = new ShiroRealm();
return realm;
} @Bean(name = "ehCacheManager")
@DependsOn("lifecycleBeanPostProcessor")
public EhCacheManager ehCacheManager(){
EhCacheManager ehCacheManager = new EhCacheManager();
return ehCacheManager;
} @Bean(name = "securityManager")
public DefaultWebSecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(shiroRealm());
securityManager.setCacheManager(ehCacheManager());//用户授权/认证信息Cache, 采用EhCache 缓存
return securityManager;
} @Bean(name = "shiroFilter")
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager); System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); // 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边
Map<String, String> filterChainDefinitionManager = new LinkedHashMap<String, String>();
// 配置退出过滤器,其中的具体的退出代码Shiro已经替我们实现了
filterChainDefinitionManager.put("/logout", "logout");
// authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问
filterChainDefinitionManager.put("/user/**", "authc,roles[user]");
filterChainDefinitionManager.put("/admin/**", "authc,roles[admin]");
filterChainDefinitionManager.put("/login", "anon");
filterChainDefinitionManager.put("/index", "anon");
filterChainDefinitionManager.put("/ajaxLogin", "anon");
filterChainDefinitionManager.put("/statistic/**", "anon");
filterChainDefinitionManager.put("/**", "authc,roles[user]");//其他资源全部拦截
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionManager); // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/login");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/success");
// 未授权界面
shiroFilterFactoryBean.setUnauthorizedUrl("/403"); return shiroFilterFactoryBean;
} @Bean
@ConditionalOnMissingBean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
daap.setProxyTargetClass(true);
return daap;
} @Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
aasa.setSecurityManager(securityManager);
return aasa;
} }

2.shiroRealm.java

public class ShiroRealm extends AuthorizingRealm {

    private Logger logger = LoggerFactory.getLogger(ShiroRealm.class);

    //一般这里都写的是servic,这里省略直接调用dao
@Autowired
private UUserDao uUserDao;
@Autowired
private URoleDao uRoleDao;
@Autowired
private UPermissionDao uPermissionDao; /**
* 登录认证
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
logger.info("验证当前Subject时获取到token为:" + token.toString());
//查出是否有此用户
String username = token.getUsername();
UUser hasUser = uUserDao.selectAllByName(username); if (hasUser != null) {
// 若存在,将此用户存放到登录认证info中,无需自己做密码对比,Shiro会为我们进行密码对比校验
List<URole> rlist = uRoleDao.findRoleByUid(hasUser.getId());//获取用户角色
List<UPermission> plist = uPermissionDao.findPermissionByUid(hasUser.getId());//获取用户权限
List<String> roleStrlist=new ArrayList<String>();////用户的角色集合
List<String> perminsStrlist=new ArrayList<String>();//用户的权限集合
for (URole role : rlist) {
roleStrlist.add(role.getName());
}
for (UPermission uPermission : plist) {
perminsStrlist.add(uPermission.getName());
}
hasUser.setRoleStrlist(roleStrlist);
hasUser.setPerminsStrlist(perminsStrlist);
// 若存在,将此用户存放到登录认证info中,无需自己做密码对比,Shiro会为我们进行密码对比校验
return new SimpleAuthenticationInfo(hasUser, hasUser.getPswd(), getName());
} return null;
} /**
* 权限认证
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
logger.info("##################执行Shiro权限认证##################");
UUser user = (UUser) principalCollection.getPrimaryPrincipal();
if (user != null) {
//权限信息对象info,用来存放查出的用户的所有的角色(role)及权限(permission)
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//用户的角色集合
info.addRoles(user.getRoleStrlist());
//用户的权限集合
info.addStringPermissions(user.getPerminsStrlist()); return info;
}
// 返回null的话,就会导致任何用户访问被拦截的请求时,都会自动跳转到unauthorizedUrl指定的地址
return null;
}
}

五、测试

1.登录

2.查询

springboot+mybatis+shiro——登录认证和权限控制的更多相关文章

  1. spring boot(十四)shiro登录认证与权限管理

    这篇文章我们来学习如何使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求.在Java领域一般有Spring Security ...

  2. Shiro的认证和权限控制

    权限控制的方式 从类别上分,有两大类: - 认证:你是谁?–识别用户身份. - 授权:你能做什么?–限制用户使用的功能. 权限的控制级别 从控制级别(模型)上分: - URL级别-粗粒度 - 方法级别 ...

  3. Spring Cloud之路:(七)SpringBoot+Shiro实现登录认证和权限管理

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/sage_wang/article/details/79592269一.Shiro介绍1.Shiro是 ...

  4. shiro实现APP、web统一登录认证和权限管理

    先说下背景,项目包含一个管理系统(web)和门户网站(web),还有一个手机APP(包括Android和IOS),三个系统共用一个后端,在后端使用shiro进行登录认证和权限控制.好的,那么问题来了w ...

  5. springboot(十四):springboot整合shiro-登录认证和权限管理

    这篇文章我们来学习如何使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求.在Java领域一般有Spring Security ...

  6. Shiro+Mybatis实现登录认证、授权功能

    Shiro+Mybatis实现登录认证.授权功能 一.实现登录认证功能 1.流程: 跟据用户提交表单的账号,经Mybatis框架在数据库中查出User对象: 如果User为空,则会抛出异常:Unkno ...

  7. spring-boot(八) springboot整合shiro-登录认证和权限管理

    学习文章:springboot(十四):springboot整合shiro-登录认证和权限管理 Apache Shiro What is Apache Shiro? Apache Shiro是一个功能 ...

  8. springboot(十四):springboot整合shiro-登录认证和权限管理(转)

    springboot(十四):springboot整合shiro-登录认证和权限管理 .embody{ padding:10px 10px 10px; margin:0 -20px; border-b ...

  9. Spring Boot 2.X(十八):集成 Spring Security-登录认证和权限控制

    前言 在企业项目开发中,对系统的安全和权限控制往往是必需的,常见的安全框架有 Spring Security.Apache Shiro 等.本文主要简单介绍一下 Spring Security,再通过 ...

随机推荐

  1. C#泛型List的介绍

    一.List<T>描述 1).表示可通过索引访问的对象的强类型列表:提供用于对列表进行搜索.排序和操作的方法.2).是ArrayList类的泛型等效类.3).可以使用一个整数索引访问此集合 ...

  2. 嵌套Golang对象的初始化

      比如有这样一个对象: type ProductConfig struct {     Site map[string]string } 对应的初始化可以如下写: var pc ProductCon ...

  3. jqGrid用法汇总(全经典)

    1.支持多种类型的数据集合作为数据源 $("#grid1").jqgrid( ........ datatype: "xml", ........ ); XML ...

  4. Linux Loop设备 使用

    有时候需要一个独立的块设备,loop设备是个方便的选择,可通过如下方式创建 dd if=/dev/zero of=./loopback_file bs=1M count=1000 losetup /d ...

  5. MySQL数据库(5)----删除或更新已有行

    有时候,会需要删除某些行,或者修改其内容.这是候便需要用到DELETE语句和UPDATE语句. 1. DELETE 语句的基本格式如下所示: DELETE FROM tbl_name WHERE wh ...

  6. sqoop简单介绍

    一简介 Sqoop是一个用来将Hadoop和关系型数据库中的数据相互转移的工具,可以将一个关系型数据库(例如 : MySQL ,Oracle ,Postgres等)中的数据导进到Hadoop的HDFS ...

  7. How to use DBVisualizer to connect to Hbase using Apache Phoenix

    How to use DBVisualizer to connect to Hbase using Apache Phoenix Article DB Visualizer is a popular ...

  8. [poj 2479] Maximum sum -- 转载

    转自 CSND 想看更多的解题报告: http://blog.csdn.net/wangjian8006/article/details/7870410                         ...

  9. 21.拉取&删除远程分支

    拉取 当 git fetch 命令从服务器上抓取本地没有的数据时,它并不会修改工作目录中的内容. 它只会获取数据然后让你自己合并. 然而,有一个命令叫作 git pull 在大多数情况下它的含义是一个 ...

  10. C#mail发送

    这里,简单封装一个函数来发送邮件,代码如下: /// <summary> /// 邮件发送辅助类 /// </summary> public class MailHelper ...