SpringBoot系列教程(五)整合Shiro进行权限控制

本文采用shiro-spring-boot-starter方式将Shiro集成到SpringBoot开发环境中,对于Shiro不做过多的功能介绍。

1.引入相关依赖

<!-- Shiro -->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring-boot-starter</artifactId>
    <version>1.5.2</version>
</dependency>

<!-- 使用Shiro相关注解时必须映入,否则可能出现拦截失效-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2、数据表

  • tb_menu:菜单表
  • tb_role:角色表
  • tb_role_menu:角色菜单表
  • tb_user_role:用户角色表

数据表结构

tb_menu

tb_role

tb_role_menutb_user_role

3.定义MenuMapper

package com.lemonzuo.mapper;

import com.lemonzuo.model.Menu;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @author LemonZuo
 * @create 2020-04-19 16:40
 */
@Repository
public interface MenuMapper {
    /**
     * 根据RoleId获取菜单信息
     * @param roleId
     * @return
     */
    List<Menu> getMenuByRoleId(String roleId);

    /**
     * 查询子菜单
     * @param menuId
     * @return
     */
    List<Menu> findChildMenu(String menuId);

    void addMenu(Menu menu);

    List<Menu> getMenuList();

    void deleteMenu(String menuId);

    Menu getMenuByMenuId(String menuId);

    void updateMenu(Menu menu);
}
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lemonzuo.mapper.MenuMapper">
    <resultMap id="baseMap" type="com.lemonzuo.model.Menu">
        <id property="id" column="id"></id>
        <result property="menuId" column="menu_id"></result>
        <result property="menuName" column="menu_name"></result>
        <result property="menuUrl" column="menu_url"></result>
        <result property="menuPermission" column="menu_permission"></result>
        <result property="parentMenuId" column="parent_menu_id"></result>
        <collection property="childMenu" column="{menuId=menu_id}" select="findChildMenu"></collection>
    </resultMap>
    <insert id="addMenu" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
        INSERT INTO tb_menu(menu_id, menu_level, menu_name, menu_url, menu_permission, parent_menu_id, menu_hide)
        VALUES (#{menuId}, #{menuLevel}, #{menuName}, #{menuUrl}, #{menuPermission}, #{parentMenuId}, #{menuHide})
    </insert>
    <update id="updateMenu">
        UPDATE tb_menu
        SET
            menu_name = #{menuName},
            menu_url = #{menuUrl},
            menu_permission = #{menuPermission},
            menu_hide = #{menuHide}
        WHERE
            menu_id = #{menuId}
    </update>
    <delete id="deleteMenu">
        DELETE FROM tb_menu
        WHERE menu_id = #{menuId}
    </delete>
    <select id="getMenuByRoleId" resultMap="baseMap">
	SELECT
		id,
		menu.menu_id,
		menu_level,
		menu_hide,
		menu_name,
		menu_url,
		menu_permission,
		parent_menu_id
	FROM
		(SELECT menu_id FROM tb_role_menu WHERE role_id = #{roleId}) rm
		INNER JOIN tb_menu menu ON rm.menu_id = menu.menu_id
    </select>

    <select id="findChildMenu" resultType="com.lemonzuo.model.Menu">
        SELECT
             id,
             menu_id,
             menu_level,
             menu_hide,
             menu_name,
             menu_url,
             menu_permission,
             parent_menu_id
        FROM
            tb_menu
        WHERE
            parent_menu_id = #{menuId}
    </select>
    <select id="getMenuList" resultMap="baseMap">
        SELECT
             id,
             menu_id,
             menu_level,
             menu_hide,
             menu_name,
             menu_url,
             menu_permission,
             parent_menu_id
        FROM
            tb_menu
        WHERE
            menu_level = 1;
    </select>
    <select id="getMenuByMenuId" resultType="com.lemonzuo.model.Menu">
        SELECT
             id,
             menu_id,
             menu_level,
             menu_hide,
             menu_name,
             menu_url,
             menu_permission,
             parent_menu_id
        FROM
            tb_menu
        WHERE
            menu_id = #{menuId};
    </select>
</mapper>

定义RoleMapper

package com.lemonzuo.mapper;

import com.lemonzuo.shiro.Role;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @author LemonZuo
 * @create 2020-04-19 16:23
 */
@Repository
public interface RoleMapper {
    /**
     * 获取用户角色列表
     * @param userId
     * @return
     */
    List<Role> getUserRoleList(String userId);

    void addRole(Role role);

    void updateRole(Role role);

    void deleteRole(String roleId);

    List<Role> getRoleList(Role role);

    Role getRoleById(String roleId);

    void addRoleRelateMenu(@Param("roleId") String roleId, @Param("menuIds") String[] menuIds);

    void deleteRoleRelateMenu(String roleId);

    void addUserRole(@Param("userIds") String[] userIds, @Param("roleId") String roleId);

    void deleteUserRoleByRoleId(String roleId);

    List<String> findUserIdByRoleId(String roleId);

    List<String> findRoleIdByUserId(String userId);


}
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lemonzuo.mapper.RoleMapper">
    <resultMap id="baseResMap" type="com.lemonzuo.shiro.Role">
        <id property="id" column="id"></id>
        <result property="roleId" column="role_id"></result>
        <result property="roleName" column="role_name"></result>
        <result property="roleValue" column="role_value"></result>
        <collection property="menuList" select="com.lemonzuo.mapper.MenuMapper.getMenuByRoleId"
                     column="{roleId=role_id}"></collection>
    </resultMap>
    <insert id="addRole" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
        INSERT INTO tb_role(role_id, role_name, role_value)
        VALUES (#{roleId}, #{roleName}, #{roleValue})
    </insert>

    <insert id="addRoleRelateMenu">
    INSERT INTO tb_role_menu (`role_id`, `menu_id`)
    VALUES
    <foreach collection="menuIds" item="menuId" separator=",">
        (#{roleId}, #{menuId})
    </foreach>
    </insert>
    <insert id="addUserRole">
    INSERT INTO `tb_user_role` (`user_id`, `role_id`)
    VALUES
    <foreach collection="userIds" item="userId" separator=",">
        (#{userId}, #{roleId})
    </foreach>
    </insert>

    <update id="updateRole">
        UPDATE tb_role
        SET
            role_name = #{roleName},
            role_value = #{roleValue}
        WHERE
            role_id = #{roleId}
    </update>
    <delete id="deleteRole">
        DELETE FROM tb_role
        WHERE role_id = #{roleId}
    </delete>
    <delete id="deleteRoleRelateMenu">
        DELETE FROM tb_role_menu
        WHERE role_id = #{roleId}
    </delete>
    <delete id="deleteUserRoleByRoleId">
        DELETE FROM tb_user_role
        WHERE role_id = #{roleId}
    </delete>

    <select id="getUserRoleList" resultMap="baseResMap">
        SELECT
             role.id,
             role.role_id,
             role.role_name,
             role.role_value
        FROM
            tb_role role
        WHERE
            EXISTS (
                SELECT 1
                FROM tb_user_role WHERE role.role_id = tb_user_role.role_id AND tb_user_role.user_id = #{userId}
            )
    </select>
    <select id="getRoleList" resultType="com.lemonzuo.shiro.Role">
        SELECT
        role.id,
        role.role_id,
        role.role_name,
        role.role_value
        FROM
        tb_role role
        <where>
            <if test="roleId != null and roleId != ''">
                role_id = #{roleId}
            </if>
            <if test="roleName != null and roleName != ''">
                role_name = #{roleName}
            </if>
            <if test="roleValue != null and roleValue != ''">
                role_value = #{roleValue}
            </if>
        </where>
    </select>
    <select id="getRoleById" resultMap="baseResMap">
        SELECT
        role.id,
        role.role_id,
        role.role_name,
        role.role_value
        FROM
        tb_role role
        WHERE
        role_id = #{roleId}
    </select>
    <select id="findUserIdByRoleId" resultType="java.lang.String">
        SELECT user_id
        FROM tb_user_role
        WHERE role_id = #{roleId}
    </select>
    <select id="findRoleIdByUserId" resultType="java.lang.String">
        SELECT role_id
        FROM tb_user_role
        WHERE user_id = #{userId}
    </select>

</mapper>

定义UserMapper

package com.lemonzuo.mapper;

import com.lemonzuo.model.LoginHistory;
import com.lemonzuo.model.User;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @author LemonZuo
 * @create 2020-04-19 12:44
 */
@Repository
public interface UserMapper {
    /**
     * 获取单个用户
     *
     * @param user
     * @return
     */
    User findUserByParam(User user);

    int countByTel(String tel);

    void addUser(User user);

    void addLoginHistory(LoginHistory history);

    void updateUser(User user);

    List<User> findUserByUserType(int userType);

    void deleteUser(String userId);
}
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lemonzuo.mapper.UserMapper">
    <insert id="addUser" parameterType="com.lemonzuo.model.User" useGeneratedKeys="true" keyProperty="id"
            keyColumn="id">
        INSERT INTO tb_user(user_id, user_tel, user_password, user_type, user_name, user_mail)
        VALUES (#{userId}, #{userTel}, #{userPassword}, #{userType}, #{userName}, #{userMail})
    </insert>
    <insert id="addLoginHistory" parameterType="com.lemonzuo.model.LoginHistory" useGeneratedKeys="true"
            keyProperty="id" keyColumn="id">
        INSERT INTO tb_user_login_history(user_id, login_ip, login_time, login_os, login_address, login_platform)
        VALUES (#{userId}, #{loginIp}, #{loginTime}, #{loginOs}, #{loginAddress}, #{loginPlatform});
    </insert>
    <update id="updateUser">
        UPDATE tb_user
        SET
        <if test="userTel != null and userTel != ''">
            user_tel = #{userTel},
        </if>
        <if test="userMail != null and userMail != ''">
            user_mail = #{userMail},
        </if>
        <if test="userName != null and userName != ''">
            user_name = #{userName}
        </if>
        WHERE
            user_id = #{userId}
    </update>
    <delete id="deleteUser">
     DELETE FROM tb_user
     WHERE  user_id = #{userId}
    </delete>

    <select id="findUserByParam" resultType="com.lemonzuo.model.User">
        SELECT
        user_name,
        user_status,
        user_id,
        user_password,
        user_tel,
        user_mail
        FROM
        tb_user
        <where>
            <if test="userName != null and userName != ''">
                user_name = #{userName}
            </if>
            <if test="userPassword != null and userPassword != ''">
                AND user_password = #{userPassword}
            </if>
            <if test="userTel != null and userTel != ''">
                AND user_tel = #{userTel}
            </if>
            <if test="userMail != null and userMail != ''">
                AND user_mail = #{userMail}
            </if>
            <if test="userType != null and userType != null">
                AND user_type = #{userType}
            </if>
            <if test="userId != null and userId != ''">
                AND user_id = #{userId}
            </if>
        </where>
    </select>

    <select id="countByTel" resultType="java.lang.Integer">
        SELECT count(1)
        FROM tb_user
        WHERE user_tel = #{tel}
    </select>

    <select id="findUserByUserType" resultType="com.lemonzuo.model.User">
        SELECT
        user_name,
        user_id,
        user_password,
        user_tel,
        user_mail
        FROM
        tb_user
        WHERE
        user_type = #{userType};
    </select>

</mapper>

相关实体类

package com.lemonzuo.model;

import lombok.Data;

import java.util.List;

/**
 * @author LemonZuo
 * @create 2020-04-19 14:20
 */
@Data
public class Menu {
    private int id;
    private String menuId;
    private String menuName;
    private String menuUrl;
    private String menuPermission;
    private int menuLevel;
    private int menuHide;
    private String parentMenuId;
    private List<Menu> childMenu;
}
package com.lemonzuo.model;

import lombok.Data;

import java.util.List;

/**
 * @author LemonZuo
 * @create 2020-04-25 22:23
 */
@Data
public class Role {
    private int id;
    private String roleId;
    private String roleName;
    private String roleValue;
    private List<Menu> menuList;
}
package com.lemonzuo.model;

import lombok.Data;

/**
 * @author LemonZuo
 * @create 2020-04-19 12:42
 */
@Data
public class User {
    private int id;
    private String userId;
    private String userName;
    private String userPassword;
    private String userTel;
    private String userMail;
    private int userType;
}

定义UserUtils

package com.lemonzuo.util;

import com.lemonzuo.model.Menu;
import com.lemonzuo.model.User;
import com.lemonzuo.service.RoleService;
import com.lemonzuo.service.UserService;
import com.lemonzuo.shiro.Role;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * @author LemonZuo
 * @create 2020-04-19 14:28
 */
public class UserUtils {
    private static UserService userService = SpringUtil.getBean(UserService.class);
    private static RoleService roleService = SpringUtil.getBean(RoleService.class);

    public static User getCurrentUser() {
        String userName = (String) SecurityUtils.getSubject().getPrincipal();
        User user = new User();
        user.setUserName(userName);
        user.setUserType(1);
        user = userService.findUserByParam(user);
        return user;
    }

    public static List<Role> getRoleList() {
        List<Role> roleList = new ArrayList<>();
        User user = getCurrentUser();
        if (user != null && StringUtils.isNotBlank(user.getUserId())) {
            roleList = roleService.getUserRoleList(user.getUserId());
        }
        return roleList;
    }

    public static List<Menu> getMenuList() {
        List<Menu> menuList = new ArrayList<>();
        List<Role> list = getRoleList();
        for (Role role : list) {
            menuList.addAll(role.getMenuList());
        }
        return menuList;
    }
}

SpringUtils

package com.lemonzuo.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * @author LemonZuo
 * @create 2020-04-28 22:17
 */
@Component
public class SpringUtil implements ApplicationContextAware {
    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    public static void set(ApplicationContext applicationContext) {
        context = applicationContext;
    }

    /**
     * 通过字节码获取
     * @param beanClass
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> beanClass) {
        return context.getBean(beanClass);
    }

    /**
     * 通过BeanName获取
     * @param beanName
     * @param <T>
     * @return
     */
    public static <T> T getBean(String beanName) {
        return (T) context.getBean(beanName);
    }

    /**
     * 通过beanName和字节码获取
     * @param name
     * @param beanClass
     * @param <T>
     * @return
     */
    public static <T> T getBean(String name, Class<T> beanClass) {
        return context.getBean(name, beanClass);
    }
}

UserService

package com.lemonzuo.service;

import com.lemonzuo.mapper.UserMapper;
import com.lemonzuo.model.LoginHistory;
import com.lemonzuo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author LemonZuo
 * @create 2020-04-19 12:52
 */
@Service
public class UserService {
    private UserMapper userMapper;

    @Autowired
    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Transactional(readOnly = true)
    public User findUserByParam(User user) {
        return userMapper.findUserByParam(user);
    }

    @Transactional(readOnly = true)
    public int countByTel(String tel) {
        return userMapper.countByTel(tel);
    }

    @Transactional(rollbackFor = Exception.class)
    public void addUse(User user) {
        userMapper.addUser(user);
    }

    @Transactional
    public void addLoginHistory(LoginHistory history) {
        userMapper.addLoginHistory(history);
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateUser(User user) {
        userMapper.updateUser(user);
    }

    @Transactional(readOnly = true)
    public List<User> findUserByUserType(int userType) {
        return userMapper.findUserByUserType(userType);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteUser(String userId) {
        userMapper.deleteUser(userId);
    }
}

RoleService

package com.lemonzuo.service;

import com.lemonzuo.mapper.RoleMapper;
import com.lemonzuo.shiro.Role;
import com.lemonzuo.util.LeafUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author LemonZuo
 * @create 2020-04-19 17:16
 */
@Repository
public class RoleService {
    @Autowired
    private RoleMapper roleMapper;

    public List<Role> getUserRoleList(String userId) {
        return roleMapper.getUserRoleList(userId);
    }

    public void addRole(Role role) {
        role.setRoleId(LeafUtil.getId());
        roleMapper.addRole(role);
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateRole(Role role) {
        roleMapper.updateRole(role);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteRole(String roleId) {
        roleMapper.deleteRole(roleId);
    }

    public List<Role> getRoleList(Role role) {
        return roleMapper.getRoleList(role);
    }

    public Role getRoleById(String roleId) {
        return roleMapper.getRoleById(roleId);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteRoleRelateMenu(String roleId) {
        roleMapper.deleteRoleRelateMenu(roleId);
    }

    @Transactional(rollbackFor = Exception.class)
    public void addRoleRelateMenu(String roleId, String[] menuIds) {
        roleMapper.addRoleRelateMenu(roleId, menuIds);
    }

    @Transactional(rollbackFor = Exception.class)
    public void addUserRole(String[] userIds, String roleId) {
        roleMapper.addUserRole(userIds, roleId);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteUserRoleByRoleId(String roleId) {
        roleMapper.deleteUserRoleByRoleId(roleId);
    }

    @Transactional(readOnly = true)
    public List<String> findUserIdByRoleId(String roleId) {
        return roleMapper.findUserIdByRoleId(roleId);
    }

    @Transactional(readOnly = true)
    public List<String> findRoleIdByUserId(String userId) {
        return roleMapper.findRoleIdByUserId(userId);
    }
}

自定义UserRealm

package com.lemonzuo.shiro;

import com.lemonzuo.model.Menu;
import com.lemonzuo.model.User;
import com.lemonzuo.service.UserService;
import com.lemonzuo.util.UserUtils;
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.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * @author LemonZuo
 * @create 2020-04-19 9:05
 */
public class UserRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;
    /**
     * 认证
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        Object principal = token.getPrincipal();
        if (principal == null) {
            return null;
        }
        // 获取用户名
        String userName = token.getUsername();
        String password = new String(token.getPassword());
        User userToken = new User();
        userToken.setUserType(1);
        userToken.setUserName(userName);
        User user = userService.findUserByParam(userToken);
        if(user == null) {
            // 用户不存在
            throw new UnknownAccountException("用户不存在");
        } else if(user != null && !password.equals(user.getUserPassword())) {
            // 密码错误
            throw  new IncorrectCredentialsException("密码错误");
        } else {
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUserName(), user.getUserPassword(), user.getUserName());
            return authenticationInfo;
        }
    }

    /**
     * 授权
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
/*        // 获取用户名
        String userName = (String) principalCollection.getPrimaryPrincipal();
        User user = new User();
        user.setUserName(userName);
        user.setUserType(1);
        // 查询用户信息
        userService.findUserByParam(user);*/
        // 添加角色与权限
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        // 获取角色
        List<Role> roleList = UserUtils.getRoleList();
        for (Role role : roleList) {
            // 添加角色
            authorizationInfo.addRole(role.getRoleName());
            for (Menu menu : role.getMenuList()) {
                // 添加权限
                authorizationInfo.addStringPermission(menu.getMenuPermission());
            }
        }
        return authorizationInfo;
    }
}

自定义RedisSessionDao

package com.lemonzuo.shiro;

import com.lemonzuo.util.RedisUtil;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.*;

/**
 * @author LemonZuo
 * @create 2020-04-19 18:41
 */
@Component
public class RedisSessionDao extends AbstractSessionDAO {
    private String prefix = "learn-";

    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = generateSessionId(session);
        assignSessionId(session, sessionId);
        saveSession(session);
        return sessionId;
    }

    @Override
    protected Session doReadSession(Serializable sessionId) {
        if (sessionId == null) {
            return null;
        }
        String key = prefix + sessionId;
        Object valueObject = RedisUtil.get(key);
        Session session = null;
        if(valueObject != null && valueObject instanceof Session) {
             session = (Session) valueObject;
        }
        return session;
    }

    @Override
    public void update(Session session) throws UnknownSessionException {
        saveSession(session);
    }

    @Override
    public void delete(Session session) {
        if (session != null) {
            String key = prefix + session.getId();
            RedisUtil.remove(key);
        }
    }

    @Override
    public Collection<Session> getActiveSessions() {
        Set<Session> sessionList = new HashSet<>();
        Set<String> keys = RedisUtil.keys(prefix);
        for (String key : keys) {
            Object valueObject = RedisUtil.get(key);
            Session session = null;
            if(valueObject != null && valueObject instanceof Session) {
                session = (Session) valueObject;
                sessionList.add(session);
            }
        }
        return sessionList;
    }

    private void saveSession(Session session) {
        if (session != null && session.getId() != null) {
            String key = prefix + session.getId();
            RedisUtil.set(key, session, 10 * 60 * 1000);
        }
    }
}

自定义CustomerSessionManage

package com.lemonzuo.shiro;

import com.lemonzuo.util.RedisUtil;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.SessionKey;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.session.mgt.WebSessionKey;
import org.springframework.stereotype.Component;

import javax.servlet.ServletRequest;
import java.io.Serializable;

/**
 * @author LemonZuo
 * @create 2020-04-25 8:40
 */
@Component
public class CustomerSessionManage extends DefaultWebSessionManager {
    private String prefix = "learn-";

    @Override
    protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException {
        Serializable sessionId = getSessionId(sessionKey);
        ServletRequest request = null;
        if (sessionKey instanceof WebSessionKey) {
            request = ((WebSessionKey) sessionKey).getServletRequest();
        }
        if (request != null && sessionId != null) {
            Session session = (Session) request.getAttribute(sessionId.toString());
            if (session != null) {
                return session;
            }
        }
        Session session = retrieveSessionFromDataSource(sessionId);
        if (request != null && sessionId != null) {
            request.setAttribute(sessionId.toString(), session);
        }
        return session;
    }

    @Override
    protected Session retrieveSessionFromDataSource(Serializable sessionId) throws UnknownSessionException {
        if (sessionId == null) {
            return null;
        }
        String key = prefix + sessionId;
        Object valueObject = RedisUtil.get(key);
        Session session = null;
        if (valueObject != null && valueObject instanceof Session) {
            session = (Session) valueObject;
        }
        return session;
    }
}

定义ShiroConfig配置类

package com.lemonzuo.config;

import com.lemonzuo.shiro.CustomerSessionManage;
import com.lemonzuo.shiro.RedisSessionDao;
import com.lemonzuo.shiro.UserRealm;
import org.apache.shiro.mgt.SessionsSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

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

/**
 * @author LemonZuo
 * @create 2020-04-19 8:50
 */
@Configuration
public class ShiroConfig {
    @Bean
    public UserRealm getRealm() {
        UserRealm realm = new UserRealm();
        return realm;
    }

    @Bean
    public SessionsSecurityManager getSecurityManager(UserRealm realm, CustomerSessionManage sessionManager) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(realm);
        securityManager.setSessionManager(sessionManager);
        return securityManager;
    }

    @Bean
    @Primary
    public CustomerSessionManage sessionManager(RedisSessionDao sessionDao) {
        CustomerSessionManage sessionManager = new CustomerSessionManage();
        sessionManager.setSessionDAO(sessionDao);
        return sessionManager;
    }

    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String, String> map = new LinkedHashMap<>();
        map.put("/admin/adminLoginPage.do", "anon");
        map.put("/admin/adminLogin.do", "anon");
        map.put("/admin/adminLogout.do", "logout");
        map.put("/admin/css/**", "anon");
        map.put("/admin/images/**", "anon");
        map.put("/admin/js/**", "anon");
        map.put("/admin/lib/**", "anon");
        map.put("/admin/**", "authc");
        map.put("/**", "anon");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        shiroFilterFactoryBean.setLoginUrl("/admin/adminLoginPage.do");
        shiroFilterFactoryBean.setSuccessUrl("/admin/index.do");
        shiroFilterFactoryBean.setUnauthorizedUrl("/admin/adminLoginPage.do");
        return shiroFilterFactoryBean;
    }

    @Bean
    @ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
        defaultAAP.setProxyTargetClass(true);
        return defaultAAP;
    }

    @Bean
    @ConditionalOnMissingBean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor =
                new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值