Skip to content

Commit

Permalink
完成动态菜单,集成shiro权限管理
Browse files Browse the repository at this point in the history
  • Loading branch information
FlyingAnt8080 committed Oct 10, 2018
1 parent 28335e1 commit 1baafd0
Show file tree
Hide file tree
Showing 145 changed files with 25,001 additions and 140 deletions.
12 changes: 12 additions & 0 deletions restaurant/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.theborakompanioni/thymeleaf-extras-shiro -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
public enum ResultEnum {
UNKNOWN_ERROR(-1,"未知错误!"),
SUCCESS(200,"成功!"),
USER_NO_FOUND(101,"用户未找到!"),
PWD_ERROR(101,"密码错误!");
USER_NO_FOUND(101,"账号未找到!"),
PWD_ERROR(101,"密码错误!"),
FIELD_VALIDATION_FAILS(202,"验证失败");
private Integer code;
private String msg;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package com.lzy.liujing.restaurant.auth;

import com.lzy.liujing.restaurant.Enums.ResultEnum;
import com.lzy.liujing.restaurant.entity.SysMenu;
import com.lzy.liujing.restaurant.entity.SysUser;
import com.lzy.liujing.restaurant.exception.CustomAuthenticationException;
import com.lzy.liujing.restaurant.service.SysUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
* 自定义拦截器
*/
@Service
public class CustomRealm extends AuthorizingRealm {
@Autowired
private SysUserService sysUserService;

/**
* 认证
* 获取身份效验信息
* @param authenticationToken
* @return
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
String loginCode = token.getUsername();
//此处username 即loginCode登录账号
SysUser user = sysUserService.findByLoginCode(loginCode);
if(user==null){
//此处自定义的AuthenticationException
throw new CustomAuthenticationException(ResultEnum.USER_NO_FOUND);
}else if(!user.getPassword().equals(new String((char[]) token.getCredentials()))){
throw new CustomAuthenticationException(ResultEnum.PWD_ERROR);
}
//new SimpleAuthenticationInfo(token.getPrincipal(),user.getPassword(),getName());
// 当验证都通过后,把用户信息放在session里
Session session = SecurityUtils.getSubject().getSession();
session.setAttribute("user",user);

//身份信息
return new SimpleAuthenticationInfo(
user,//用户
user.getPassword(),//密码
ByteSource.Util.bytes(loginCode),
getName()//realm name
);
}

/**
* 授权
* 获取授权信息
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//获取用户的输入的账号.
String loginCode = (String) SecurityUtils.getSubject().getPrincipal();
//根据账号查询用户
SysUser param = sysUserService.findByLoginCode(loginCode);
//授权信息对象info,用来存放查出的用户的所有的角色(role)及权限(permission)
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
Set<String> roles = sysUserService.findRoleNameByUser(param);
info.setRoles(roles);
SysMenu sysMenu = new SysMenu();
sysMenu.getCondition().put("list",roles);
//根据角色信息,查询出用户具备的权限字符串
List<SysMenu> menuList = sysUserService.findMenuList(sysMenu);
Set<String> permissions = new HashSet<>();
for(SysMenu menu:menuList){
if(!StringUtils.isEmpty(menu.getPermission())){
permissions.add(menu.getPermission());
System.out.println(menu.getPermission());
}
}
info.addStringPermissions(permissions);
return info;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.lzy.liujing.restaurant.config;

import com.lzy.liujing.restaurant.auth.CustomRealm;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 必须设置 SecurityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
// setLoginUrl ,默认会自动寻找Web工程根目录下的"/login.jsp"页面 或 "/login" 映射
shiroFilterFactoryBean.setLoginUrl("/sysuser/login.html");
//登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/sysuser/admin.html");
// 设置无权限时跳转的 url;
shiroFilterFactoryBean.setUnauthorizedUrl("/sysuser/login.html");
//设置拦截器
Map<String,String> filterChainDefinitionMap = new LinkedHashMap<>();
//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/logout", "logout");
//开发资源文件权限
filterChainDefinitionMap.put("/css/**","anon");
filterChainDefinitionMap.put("/js/**","anon");
filterChainDefinitionMap.put("/image/**","anon");
filterChainDefinitionMap.put("/layui/**","anon");
filterChainDefinitionMap.put("/layuiadmin/**","anon");
//游客权限开放
filterChainDefinitionMap.put("/guest/**","anon");
//开放登录
filterChainDefinitionMap.put("/sysuser/login.do","anon");
//<!-- 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
//<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
//自定义加载权限资源关系
/* List<Resources> resourcesList = resourcesService.queryAll();
for(Resources resources:resourcesList){
if (StringUtil.isNotEmpty(resources.getResurl())) {
String permission = "perms[" + resources.getResurl()+ "]";
filterChainDefinitionMap.put(resources.getResurl(),permission);
}
}*/
//其余url一律拦截
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}

@Bean
public SecurityManager securityManager(Realm realm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm);
return securityManager;
}

//此处需要注入我们自己写的Realm
@Bean
@DependsOn("lifecycleBeanPostProcessor")
public Realm customRealm(){
return new CustomRealm();
}

@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
return new LifecycleBeanPostProcessor();
}

/**
*开启shiro aop注解支持.
* 使用代理方式;所以需要开启代码支持;
* @param securityManager
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@
import com.lzy.liujing.restaurant.entity.SysUser;
import com.lzy.liujing.restaurant.service.SysUserService;
import com.lzy.liujing.restaurant.utils.ResultUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;

/**
Expand All @@ -21,23 +27,40 @@
*/
@Controller
@RequestMapping("/sysuser")
public class LoginController {
public class LoginController{
@Autowired
private SysUserService sysUserService;
/**
/**登录功能
* @Valid 表示验证该对象 验证结果保存到BindingResult对象中
*/
@PostMapping(value = "/login.do")
@ResponseBody
public Result<SysUser> login(@Valid SysUser user, BindingResult bindingResult){
public Result<SysUser> login(@Valid SysUser user, BindingResult bindingResult, HttpSession session){
if(bindingResult.hasErrors()){
//202 验证失败
return ResultUtil.error(202,bindingResult.getFieldError().getDefaultMessage());
}
System.out.println("成功");
return ResultUtil.success(sysUserService.findByLoginCode(user));
//获取主体
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(user.getLoginCode(),user.getPassword());
//将登录交个shiro
subject.login(token);
//登录成功后
return ResultUtil.success();
}

/**
* 退出登录
* @return
*/
@GetMapping("/logout.do")
public String logout(){
Subject subject = SecurityUtils.getSubject();
subject.logout();
//清除session
subject.getSession().removeAttribute("user");
return "redirect:login.html";
}
/**
* 登录页面
* @return
Expand All @@ -52,7 +75,19 @@ public String login(){
* @return
*/
@GetMapping("/admin.html")
public String index(){
public String admin(HttpSession session, Model model){
SysUser sysUser = (SysUser) session.getAttribute("user");
//查询菜单格式后的结构树并返回视图
model.addAttribute("menuList",sysUserService.findMenuTreeByUser(sysUser));
return "/admin";
}

/**
* 控制台页面
* @return
*/
@GetMapping("/console.html")
public String console(){
return "/home/console";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.lzy.liujing.restaurant.entity.SysMenu;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
* Created with IDEA
* author:LiuJing
Expand All @@ -11,5 +13,12 @@
*/
@Mapper
public interface SysMenuDao extends tk.mybatis.mapper.common.Mapper<SysMenu>{
SysMenu findById(Long menuId);

/**
* 根据用户查询菜单
* @param sysMenu
* @return
*/
List<SysMenu> findList(SysMenu sysMenu);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.lzy.liujing.restaurant.dao;

import com.lzy.liujing.restaurant.entity.SysRole;
import com.lzy.liujing.restaurant.entity.SysUser;
import org.apache.ibatis.annotations.Mapper;

import java.util.Set;

/**
* Created with IDEA
* author:LiuJing
Expand All @@ -11,6 +14,6 @@
*/
@Mapper
public interface SysRoleDao extends tk.mybatis.mapper.common.Mapper<SysRole>{

Set<String> findRoleNamesByUser(SysUser sysUser);
}

Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,19 @@ public interface SysUserDao extends tk.mybatis.mapper.common.Mapper<SysUser>{
* 根据账号查询
* @return
*/
SysUser findByLoginCode(SysUser sysUser);
SysUser findByLoginCode(String loginCode);

/**
* 修改删除
* @param sysUser
* @return
*/
int update(SysUser sysUser);

/**
* 插入用
* @param sysUser
* @return
*/
int insert(SysUser sysUser);
}
Loading

0 comments on commit 1baafd0

Please sign in to comment.