SpringBoot 集成 shiro权限验证


1. 表结构

还是是用标准的5张表来展现权限。如下图:image 

分别为用户表,角色表,资源表,用户角色表,角色资源表。在这个demo中使用了mybatis-generator自动生成代码。运行mybatis-generator:generate -e 根据数据库中的表,生成 相应的model,mapper单表的增删改查。不过如果是导入本项目的就别运行这个命令了。新增表的话,也要修改mybatis-generator-config.xml中的tableName,指定表名再运行。

2.pom.xml的依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sourceforge.nekohtml</groupId>
            <artifactId>nekohtml</artifactId>
            <version>1.9.22</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
    </dependencies>

重点是 shiro-spring包

3.配置文件

spring:
    datasource:
      url: jdbc:mysql://localhost:3306/test
      username: root
      password: root
      driver-class-name: com.mysql.jdbc.Driver

    jpa:
      database: mysql
      show-sql: true
      hibernate:
        ddl-auto: update
        naming:
          strategy: org.hibernate.cfg.DefaultComponentSafeNamingStrategy
      properties:
         hibernate:
            dialect: org.hibernate.dialect.MySQL5Dialect

    thymeleaf:
       cache: false
       mode: LEGACYHTML5

thymeleaf的配置是为了去掉html的校验

4.shiro配置

1.shiroConfig

package com.msp.whg.shiro;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
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.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
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;

/**
 * Shiro 配置
 *
 Apache Shiro 核心通过 Filter 来实现,就好像SpringMvc 通过DispachServlet 来主控制一样。
 既然是使用 Filter 一般也就能猜到,是通过URL规则来进行过滤和权限校验,所以我们需要定义一系列关于URL的规则和访问权限。
 */
@Configuration
public class ShiroConfiguration {

    /**
     * ShiroFilterFactoryBean 处理拦截资源文件问题。
     * 注意:单独一个ShiroFilterFactoryBean配置是或报错的,以为在
     * 初始化ShiroFilterFactoryBean的时候需要注入:SecurityManager
     *
     Filter Chain定义说明
     1、一个URL可以配置多个Filter,使用逗号分隔
     2、当设置多个过滤器时,全部验证通过,才视为通过
     3、部分过滤器可指定参数,如perms,roles
     *
     */
    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager){
        
        System.out.println("ShiroConfiguration.shirFilter()");
        ShiroFilterFactoryBean shiroFilterFactoryBean  = new ShiroFilterFactoryBean();

        // 必须设置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/index");
        // 登录成功后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/main");
        //未授权界面;
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
        //拦截器.
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();

        //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
        filterChainDefinitionMap.put("/logout", "logout");
        filterChainDefinitionMap.put("/css/**","anon");
        filterChainDefinitionMap.put("/js/**","anon");
        filterChainDefinitionMap.put("/img/**","anon");
        filterChainDefinitionMap.put("/font-awesome/**","anon");
        filterChainDefinitionMap.put("/favicon.ico", "anon");

        filterChainDefinitionMap.put("/**", "authc");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
        //设置realm.
        securityManager.setRealm(myShiroRealm());
        return securityManager;
    }

    /**
     * 身份认证realm;
     * (这个需要自己写,账号密码校验;权限等)
     * @return
     */
    @Bean
    public MyShiroRealm myShiroRealm(){
        MyShiroRealm myShiroRealm = new MyShiroRealm();
        myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return myShiroRealm;
    }

    /**
     * 凭证匹配器
     * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
     *  所以我们需要修改下doGetAuthenticationInfo中的代码;
     * )
     * @return
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
        hashedCredentialsMatcher.setHashIterations(1);//散列的次数,比如散列两次,相当于 md5(md5(""));
        return hashedCredentialsMatcher;
    }

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

    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }


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

    @Bean
    @DependsOn("lifecycleBeanPostProcessor")
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
        proxyCreator.setProxyTargetClass(true); // this SETTING
        return proxyCreator;
    }

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

2.自定义realm

package com.msp.whg.shiro;

import com.msp.whg.domain.UserManage;
import com.msp.whg.service.UserManageService;
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 java.util.List;

/**
 * Created by Administrator on 2018\2\28 0028.
 * 自定义realm实现认证
 */
public class MyShiroRealm extends AuthorizingRealm {

    @Autowired
    private UserManageService userService;

    /**
     * 认证信息.(身份验证)
     * :
     * Authentication 是用来验证用户身份
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        //获取用户的输入的账号.
        String username = (String)token.getPrincipal();
        UserManage userManage = new UserManage();
        userManage.setUserName(username);
        //根据用户名去数据库查询是否有该用户
        UserManage user = userService.selectOne(userManage);

        if(user == null){
            return null;
        }
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                user, //用户名
                user.getUserPwd(), //密码
                getName()  //realm name
        );
        return authenticationInfo;
    }

    // 授权校验
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        //获取用户的信息
        UserManage user = (UserManage)principals.getPrimaryPrincipal();

        //返回的对象
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        //根据用户信息查询用户有哪些权限
        List<String> permissionList = userService.findPermissionByUserManage(user);
        authorizationInfo.addStringPermissions(permissionList);
        return authorizationInfo;
    }
}

去UserService中调用findPermission()方法查询有哪些权限,然后在页面上使用shiro的标签haspermission来实现动态显示


在service中将菜单的ingcheng加入到permissionList集合中,在shiro:hasPermission标签中为名称(要对应)

UserService:



效果:


  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Spring Boot是基于Spring框架的快速开发应用程序的工具,而Shiro则是一个强大且灵活的Java安全框架。将Spring BootShiro结合使用可以实现权限管理的功能。 首先需要在Spring Boot项目中引入相关依赖,包括Spring Boot的依赖和Shiro的依赖。可以在pom.xml文件中添加如下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.7.1</version> </dependency> ``` 接下来,需要配置Shiro的配置类。可以创建一个继承自org.apache.shiro.web.mgt.DefaultWebSecurityManager的类,并在该类中配置Shiro的相关信息,包括认证器和授权器。 认证器负责验证用户的身份,可以使用Shiro提供的Realm来实现自定义的身份验证逻辑。授权器负责判断用户是否有权限执行某个操作,可以使用Shiro提供的Permission类来实现权限的控制。 然后,需要为Spring Boot应用程序配置Shiro过滤器链。可以使用Shiro的FilterChainDefinitionMap类来配置URL与权限的映射关系。可以在一个继承自org.apache.shiro.web.env.AbstractWebEnvironment的类中配置这些过滤器链。 最后,在Spring Boot应用程序的入口类中启动Shiro配置。在main()方法中,可以使用org.apache.shiro.SecurityUtils类的setSecurityManager()方法来设置Shiro的安全管理器。 完成以上步骤后,Spring Boot应用程序就集成Shiro权限管理功能。可以通过编写相应的Controller和页面来测试权限管理的效果。 总之,通过将Spring BootShiro结合使用,可以实现权限管理的功能。通过配置Shiro的相关类和过滤器链,以及编写自定义的Realm和Permission,可以实现身份验证权限控制的逻辑。 ### 回答2: Spring Boot是一个用于创建独立的、基于Spring的应用程序的框架。Shiro是一个强大的Java安全框架,提供了身份认证、授权、加密等安全功能。下面是使用Spring Boot集成Shiro权限管理的步骤和注意事项。 1. 添加依赖:在Maven或Gradle中添加Spring BootShiro的依赖项。 2. 创建Shiro配置类:创建一个继承自`org.apache.shiro.spring.config.ShiroAnnotationProcessorConfiguration`的配置类。在该类中配置Shiro的安全相关属性,比如加密算法、身份认证方式等。 3. 创建用户实体类:创建表示用户的实体类,并为其添加相关属性,如用户名、密码等。 4. 创建用户服务类:创建一个用户服务类,用于处理用户相关的操作,如用户注册、查询用户等。 5. 创建Realm类:创建一个继承自`org.apache.shiro.realm.AuthorizingRealm`的自定义Realm类。在该类中,实现身份认证和授权的逻辑。 6. 配置Shiro过滤器:在`application.properties`文件中配置Shiro的过滤器链,指定URL与权限之间的对应关系。 7. 创建Controller类:创建一个Controller类,用于处理用户请求。在该类中,通过`@RequiresRoles`和`@RequiresPermissions`等注解为方法添加授权需求。 8. 启动应用程序:使用Spring Boot的注解启动应用程序,让Spring Boot自动配置并启用Shiro。 注意事项: - 在配置Shiro时,需要根据实际需要选择适当的安全策略、加密算法和认证方式。 - 在自定义Realm类中,需要根据实际需求进行身份认证和授权的实现。 - 在通过Shiro注解为方法添加授权需求时,需要确保用户已经成功登录。 - 需要根据实际业务需求,合理配置Shiro的过滤器链,以获得所需的权限控制效果。 总之,使用Spring Boot集成Shiro权限管理可以方便地实现应用程序的安全认证和授权功能。通过配置Shiro的相关属性和自定义Realm类,可以实现灵活的权限管理,保护应用程序的安全。 ### 回答3: Spring Boot集成Shiro权限管理是一种常用的方式,可以实现安全的身份验证和授权功能。以下是一个简单的步骤,来演示如何实现这个集成。 第一步,导入相关依赖。在pom.xml文件中添加以下依赖项: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-web-starter</artifactId> <version>1.7.1</version> </dependency> ``` 第二步,编写Shiro的配置文件。创建一个类,命名为ShiroConfig,并使用@Configuration注解将其声明为一个配置类。在配置类中,使用@RequiresPermissions注解来定义URL的访问权限,使用@Bean注解来创建ShiroFilterFactoryBean和DefaultWebSecurityManager等Bean。 第三步,创建一个自定义的Realm类。这个类需要继承自AuthenticatingRealm,并实现其中的认证和授权方法。在认证方法中,需要根据用户名和密码来进行验证用户的身份。在授权方法中,需要判断用户是否具有访问某个URL的权限。 第四步,在Spring Boot的启动类中,添加@EnableCaching注解来启用缓存功能。这样可以提高系统的性能。 第五步,编写Controller类。在Controller中,使用@RequiresPermissions注解来定义URL的访问权限。在方法中,可以使用Subject进行身份验证和授权操作。 最后,启动应用程序。通过访问配置的URL,可以验证是否成功实现了Shiro权限管理功能。 通过以上步骤,我们可以实现Spring Boot集成Shiro权限管理。这样就可以在应用程序中实现安全的身份验证和授权功能,确保只有具备相应权限的用户可以访问指定的URL。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值