SpringBoot集成Shiro

Shiro是一个安全框架,控制登陆,角色权限管理(身份认证、授权、回话管理、加密)

Shiro不会去维护用户,维护权限;这些需要通过realm让开发人员自己注入

1、在pom.xml中引入shiro的jar包

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.4.0</version>
</dependency>

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-ehcache</artifactId>
    <version>1.4.0</version>
</dependency>

2、在src\main\resources下创建ehcache-shiro.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false" name="cacheManagerConfigFile">
    <defaultCache maxElementsInMemory="1000"
    eternal="false"
    timeToIdleSeconds="120"
    timeToLiveSeconds="120"
    overflowToDisk="false"
    diskPersistent="false"
    diskExpiryThreadIntervalSeconds="120"
    memoryStoreEvictionPolicy="LRU"/>
    <cache name="shiro-activeSessionCache"
    eternal="false"
    maxElementsInMemory="10000"
    overflowToDisk="false"
    timeToIdleSeconds="0"
    timeToLiveSeconds="0"/>
</ehcache>

3、创建User类

package com.cppdy.entity;

public class User {

    private int id;
    private String username;
    private String password;
    private int roleid;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public int getRoleid() {
        return roleid;
    }

    public void setRoleid(int roleid) {
        this.roleid = roleid;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}

4、创建Role类

package com.cppdy.entity;

public class Role {

    private int id;
    private String rolename;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getRolename() {
        return rolename;
    }

    public void setRolename(String rolename) {
        this.rolename = rolename;
    }

}

5、创建Permission类

package com.cppdy.entity;

public class Permission {

    private int id;
    private String pername;
    private int roleid;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getPername() {
        return pername;
    }

    public void setPername(String pername) {
        this.pername = pername;
    }

    public int getRoleid() {
        return roleid;
    }

    public void setRoleid(int roleid) {
        this.roleid = roleid;
    }

}

6、创建UserMapper接口

package com.cppdy.mapper;

import org.apache.ibatis.annotations.Mapper;

import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.cppdy.entity.User;

@Mapper
public interface UserMapper extends BaseMapper<User>{

}

7、创建RoleMapper接口

package com.cppdy.mapper;

import org.apache.ibatis.annotations.Mapper;

import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.cppdy.entity.Role;

@Mapper
public interface RoleMapper extends BaseMapper<Role>{

}

8、创建PermissionMapper接口

package com.cppdy.mapper;

import org.apache.ibatis.annotations.Mapper;

import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.cppdy.entity.Permission;

@Mapper
public interface PermissionMapper extends BaseMapper<Permission>{

}

9、创建UserService接口

package com.cppdy.service;

import com.cppdy.entity.User;

public interface UserService {

    public void update(String username, int id);

    public User selectUserByUsername(String username);

}

10、创建UserServiceImpl接口实现类

package com.cppdy.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.cppdy.entity.User;
import com.cppdy.mapper.UserMapper;
import com.cppdy.service.UserService;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    // 开启事务管理
    @Transactional
    public void update(String username, int id) {

        User user = userMapper.selectById(id);
        user.setUsername(username);
        // 更新一条数据
        userMapper.updateById(user);

    }

    @Override
    public User selectUserByUsername(String username) {
        Wrapper<User> wrapper = new EntityWrapper<>();
        wrapper.eq("username", username);
        List<User> list = userMapper.selectList(wrapper);
        if(list.size()>0) {
            return list.get(0);
        }
        return null;
    }

}

11、创建UserRealm类

package com.cppdy.realm;

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

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
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 com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.cppdy.entity.Permission;
import com.cppdy.entity.Role;
import com.cppdy.entity.User;
import com.cppdy.mapper.PermissionMapper;
import com.cppdy.mapper.RoleMapper;
import com.cppdy.service.UserService;

public class UserRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermissionMapper permissionMapper;

    // 控制角色权限
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        String username = (String) principals.getPrimaryPrincipal();
        // 将当前用户的角色和权限查询进来
        User user = userService.selectUserByUsername(username);
        Role role = roleMapper.selectById(user.getRoleid());

        info.addRole(role.getRolename());

        Wrapper<Permission> wrapper = new EntityWrapper<>();
        wrapper.eq("roleid", role.getId());
        List<Permission> selectList = permissionMapper.selectList(wrapper);
        ArrayList<String> perList = new ArrayList<String>();
        selectList.forEach(per -> {
            perList.add(per.getPername());
        });

        info.addStringPermissions(perList);
        return info;
    }

    // 控制登陆
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        AuthenticationInfo info = null;
        String username = (String) token.getPrincipal();
        User user = userService.selectUserByUsername(username);
        if (user != null) {
            info = new SimpleAuthenticationInfo(username, user.getPassword(), "cppdy");
        }
        return info;
    }

}

12、创建ShiroConfiguration配置类

package com.cppdy.config;

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

import javax.servlet.Filter;

import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
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.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.cppdy.realm.UserRealm;

@Configuration
public class ShiroConfiguration {

    @Bean
    public ShiroFilterFactoryBean shiroFilter(org.apache.shiro.mgt.SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        //必须设置SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //拦截器
        Map<String,String> filterChainDefinitionMap=new LinkedHashMap<String,String>();
        //配置静态资源允许访问
        filterChainDefinitionMap.put("/user/login", "anon");
        filterChainDefinitionMap.put("/user/loginAction", "anon");
        //authc:所有url都必须认证通过才可以访问;anon:所有url都可以匿名访问
        filterChainDefinitionMap.put("/**", "authc");
        //如果不设置默认会自动寻找web工程跟目标下的/login.jsp页面
        shiroFilterFactoryBean.setLoginUrl("/user/login");
        //未授权界面
//        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
        Map<String,Filter> filters=new HashMap<String,Filter>();
        shiroFilterFactoryBean.setFilters(filters);
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return shiroFilterFactoryBean;
    }

    @Bean
    public EhCacheManager getEhCacheManager() {
        EhCacheManager em=new EhCacheManager();
        em.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");
        return em;
    }

    //开启Controller中的shiro注解
    @Bean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator daap=new DefaultAdvisorAutoProxyCreator();
        daap.setProxyTargetClass(true);
        return daap;
    }

    @Bean
    public DefaultWebSessionManager getDefaultWebSessionManager() {
        DefaultWebSessionManager defaultWebSessionManager=new DefaultWebSessionManager();
        defaultWebSessionManager.setSessionDAO(getMemorySessionDAO());
        defaultWebSessionManager.setGlobalSessionTimeout(4200000);
        defaultWebSessionManager.setSessionValidationSchedulerEnabled(true);
        defaultWebSessionManager.setSessionIdCookieEnabled(true);
        defaultWebSessionManager.setSessionIdCookie(getSimpleCookie());
        return defaultWebSessionManager;
    }

    @Bean
    public MemorySessionDAO getMemorySessionDAO() {
        MemorySessionDAO memorySessionDAO=new MemorySessionDAO();
        memorySessionDAO.setSessionIdGenerator(javaUuidSessionIdGenerator());
        return memorySessionDAO;
    }

    @Bean
    public JavaUuidSessionIdGenerator javaUuidSessionIdGenerator() {

        return new JavaUuidSessionIdGenerator();
    }

    /**
     * session自定义cookie名
     * @return
     */
    @Bean
    public SimpleCookie getSimpleCookie() {
        SimpleCookie simpleCookie=new SimpleCookie();
        simpleCookie.setName("security.session");
        simpleCookie.setPath("/");
        return simpleCookie;
    }

    @Bean
    public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {

        return new LifecycleBeanPostProcessor();
    }

    @Bean(name="securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(UserRealm userRealm) {
        DefaultWebSecurityManager dwsm=new DefaultWebSecurityManager();
        dwsm.setRealm(userRealm);
        //用户授权/认证信息Cache,采用EhCache缓存
        dwsm.setCacheManager(getEhCacheManager());
        dwsm.setSessionManager(getDefaultWebSessionManager());
        return dwsm;
    }

    @Bean
    public UserRealm userRealm(EhCacheManager cacheManager) {
        UserRealm userRealm=new UserRealm();
        userRealm.setCacheManager(cacheManager);
        return userRealm;
    }

    /**
     * 开启shiro注解支持
     * @param userRealm
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(UserRealm userRealm) {
        AuthorizationAttributeSourceAdvisor aasa=new AuthorizationAttributeSourceAdvisor();
        aasa.setSecurityManager(getDefaultWebSecurityManager(userRealm));
        return aasa;
    }
}

13、创建UserController类

package com.cppdy.controller;

import org.apache.ibatis.session.RowBounds;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.cppdy.entity.User;
import com.cppdy.mapper.UserMapper;

@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    private UserMapper userMapper;

    @RequestMapping("getUserById")
    public Object getUserById(int id) {

        return userMapper.selectById(id);
    }

    @RequiresPermissions("sys:delete")
    @RequestMapping("deleteUserById")
    public Object deleteUserById(int id) {

        return userMapper.deleteById(id);
    }

    @RequiresRoles("admin")
    @RequestMapping("getUser")
    public Object getUser() {
        // 适配器
        Wrapper<User> wrapper = new EntityWrapper<>();
        wrapper.like("username", "测试");
        // 倒序
        wrapper.orderBy("id", false);
        return userMapper.selectList(wrapper);
    }

    @RequestMapping("selectPage")
    public Object selectPage(int pageNum, int pageSize) {
        // 适配器
        Wrapper<User> wrapper = new EntityWrapper<>();

        RowBounds rowBounds = new RowBounds((pageNum - 1) * pageSize, pageSize);

        return userMapper.selectPage(rowBounds, wrapper);
    }

    @RequestMapping("login")
    public String login() {

        return "loginPage";
    }

    @RequestMapping("loginAction")
    public String loginAction(String username,String password) {
        Subject subject = SecurityUtils.getSubject();
        String md5 = new Md5Hash(password, "cppdy").toString();
        AuthenticationToken token = new UsernamePasswordToken(username, md5);
        try {
            // 如果执行subject.login抛出异常,则证明登陆成功
            subject.login(token);
            return "login success";
        } catch (AuthenticationException e) {
            // 有异常则证明登陆错误
            e.printStackTrace();
            return "login failed";
        }
    }

}

14、创建表(user、role、permission),并添加测试数据(password为:123456;md5加密后的password为:9faea48dae4030f38bcd1ae6a4f7fc01)

15、访问loginAction方法进行登录,再分别调用getUser和deleteUserById方法测试角色权限控制

原文地址:https://www.cnblogs.com/cppdy/p/10051845.html

时间: 2024-10-31 07:33:31

SpringBoot集成Shiro的相关文章

SpringBoot:集成Shiro之INI授权篇

前言 图片描述(最多50字)前面说到如何使用INI文件进行登录认证,但是这一篇博客主要讲的是Shiro的另外一个重要功能就是授权操作,这里简单说明一下,授权操作就是来定义合法用户的权限操作.这一篇我们仍然使用INI文件的形式,看一下,我们如何来进行授权操作. RBAC简单阐述基于角色的权限访问控制(Role-Based Access Control)作为传统访问控制(自主访问,强制访问)的有前景的代替受到广泛的关注.在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限.

SpringBoot集成Shiro 实现动态加载权限

一.前言 本文小编将基于 SpringBoot 集成 Shiro 实现动态uri权限,由前端vue在页面配置uri,Java后端动态刷新权限,不用重启项目,以及在页面分配给用户 角色 . 按钮 .uri 权限后,后端动态分配权限,用户无需在页面重新登录才能获取最新权限,一切权限动态加载,灵活配置 基本环境 spring-boot 2.1.7 mybatis-plus 2.1.0 mysql 5.7.24 redis 5.0.5 温馨小提示:案例demo源码附文章末尾,有需要的小伙伴们可参考哦 ~

Springboot集成Shiro和Cas实现单点登录(服务端篇CAS5)

什么是单点登录? 先说一个需求场景,比如:一个企业的内部有N多个子系统,每个子系统都有一套自己的用户名和密码,那么企业的员工要登录N个子系统,这样一个员工 就要记住N个用户名和密码,就算各个子系统的用户名和密码都是统一的,登录每个子系统都要输入用户名和密码进行登录也是一个繁琐的操作过程,那么单点登录功能由此便应运而生了.单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应

springboot 集成shiro

首先看下shiro configuration 的配置,重要部分用红色标出了 package cn.xiaojf.today.shiro.configuration; import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; import cn.xiaojf.today.sys.security.credentials.RetryLimitHashedCredentialsMatcher; import cn.xiaojf.today.sys.

SpringBoot 集成 Shiro:使用Shiro的权限管理(六)

上一章使用了Shiro的角色管理,现在加入粒度更小的权限管理,即根据用户角色分配的权限来判断用户能否访问页面 准备实体类和修改数据源 @Getter @Setter public class Role implements Serializable { private String name; private Set<Permission> permissions; public Role(String name) { this.name = name; this.permissions =

springboot集成shiro实现权限缓存和记住我

到这节为止,我们已经实现了身份验证和权限验证.但是,如果我们登录之后多次访问http://localhost:8080/userInfo/userDel的话,会发现权限验证会每次都执行一次.这是有问题的,因为像用户的权限这些我们提供给shiro一次就够了. 下面,我们开始给shiro添加缓存支持: 1.添加依赖 <!-- shiro ehcache --> <dependency> <groupId>org.apache.shiro</groupId> &l

SpringBoot 集成 Shiro:使用Shiro的角色管理(五)

Shiro的角色管理,可以根据 添加Role实体类,修改User类,修改数据源 @Getter @Setter @AllArgsConstructor public class Role implements Serializable { private String name; } Role.java @Getter @Setter public class User implements Serializable { private String id; private String use

springboot集成shiro集成mybatis-plus、redis、quartz定时任务

完整项目代码位于码云上,点击获取:Git地址 主要介绍一下重点配置地方: 一.application.yml文件 server: port: 8084 servlet: context-path: /testspring: ## quartz定时任务,采用数据库方式 quartz: job-store-type: jdbc #json 时间戳统一转换 jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 aop: proxy-tar

springboot集成shiro的权限中cors跨域问题

@Configurationpublic class CorsConfig { private CorsConfiguration buildConfig() { CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedOrigin("*"); corsConfiguration.addAllowedHeader("*"); corsConf