shiro三连斩之第三斩,整合 springboot

Posted 喜欢与改变

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shiro三连斩之第三斩,整合 springboot相关的知识,希望对你有一定的参考价值。

shiro爱springboot中使用 ,还有thymeleaf前端框架。主要是如何配置

pom.xml配置依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com</groupId>
    <artifactId>bpms</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>bpms</name>
    <description>Demo project for Spring Boot</description>
    
    <properties>
        <java.version>1.8</java.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--json格式转换-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.8</version>
        </dependency>
        <!--分页插件-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.3</version>
        </dependency>
        
        <!--认证,授权,加密相关-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-web</artifactId>
            <version>1.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.4.0</version>
        </dependency>
        <!--Druid提供强大的监控和扩展功能-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.14</version>
        </dependency>
    
        <!--thyemleaf中支持shiro-->
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.7</version>
                <configuration>
                    <overwrite>true</overwrite>
                    <configurationFile>${basedir}/src/main/resources/generatorConfig.xml</configurationFile>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>5.1.47</version>
                    </dependency>
                </dependencies>
            
            </plugin>
        </plugins>
    </build>

</project>

 

Shiro配置文件的设置

package com.bpms.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.bpms.shiro.CustomRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
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.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

/*shiro的注册,springboot没有配置文件,只有通过java类的形式进行注册,
关于shiro一共用 普通java类,SSM框架,springboot分别写了三遍,原理大致是一样的。区别在于怎么配置
1.shiro过滤器,  对登录的用户进行 认证,授权。对url路径进行的拦截,需要shiro过滤器
2.shiro管理器,管理认证 授权 缓存 等等。但是都需要创建配置。首先创建安全管理器,去管理各种组件。
3.shiro自定义域。shiro安全管理器中认证需要的组件
4.密码匹配器。
5.缓存
6.使shiro权限注解生效
7.对类进行aop代理
8.对thymeleaf进行支持
*/
@Configuration//说明这个被为配置信息类,spring 把这个类作为配置文件处理,把里面被@Bean修饰的方法返回的对象交给IOC容器管理。注入需要的地方
                //这个注入,好像时方法中的参数。会被自动调用
public class ShiroConfig {

    //Shiro过滤器配置,并注入安全管理器
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("sm") DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setLoginUrl("/login.html");
        bean.setUnauthorizedUrl("/403.html");
        Map map = new LinkedHashMap();
        map.put("/login.html", "anon");
        map.put("/doLogin", "anon");
        map.put("/css/**", "anon");
        map.put("/static/**", "anon");
        map.put("/js/**", "anon");
        map.put("/images/**", "anon");
        map.put("/*", "authc");
        bean.setFilterChainDefinitionMap(map);
        bean.setSecurityManager(securityManager);
        return bean;
    }

    //Shiro安全管理器,把域放入安全管理器
    @Bean("sm")
    public DefaultWebSecurityManager securityManager(CustomRealm customRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(customRealm);
        return securityManager;
    }

    //配置自定义域,可以注入密码匹配器
    @Bean
    public CustomRealm customRealm(HashedCredentialsMatcher matcher, MemoryConstrainedCacheManager manager) {
        CustomRealm realm = new CustomRealm();
        realm.setCredentialsMatcher(matcher);//注入
        realm.setCacheManager(manager);
        return realm;
    }

    //密码匹配器
    @Bean
    public HashedCredentialsMatcher matcher() {
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        matcher.setHashAlgorithmName("md5");
        matcher.setHashIterations(2);
        return matcher;
    }

    //缓存
    @Bean
    public MemoryConstrainedCacheManager cacheManager() {
        MemoryConstrainedCacheManager manager = new MemoryConstrainedCacheManager();
        return manager;
    }

    //使Shiro权限注解生效。让controller中添加的 对权限,或者角色 后台拦截的标签生效
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }

    //对类进行aop代理。shiro的认证功能 属于在请求到达方法前进行的,切面编程。执行aop代理
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
        creator.setProxyTargetClass(true);
        return creator;
    }

    //支持thyemleaf
    @Bean
    public ShiroDialect shiroDialect() {
        ShiroDialect dialect = new ShiroDialect();
        return dialect;
    }
}

Shiro配置文件中需要的自定义域的编写,和Shiro第二斩的中一致

package com.bpms.shiro;

import com.bpms.pojo.User;
import com.bpms.service.AuthService;
import com.bpms.service.UserService;
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.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Set;


public class CustomRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;

    @Autowired
    private AuthService authService;


    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        User user = (User)principalCollection.getPrimaryPrincipal();
        List<String> list = authService.findPerms(user.getUserId());
        for(String str : list){
            System.out.println("授权:"+str);
        }
        Set<String> perms= new HashSet<>(list);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setStringPermissions(perms);
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String userName = (String) authenticationToken.getPrincipal();
        User user  = userService.findUserByName(userName);
        if(user == null){
            throw new UnknownAccountException("unkown account");
        }
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),this.getClass().getName());
        info.setCredentialsSalt(ByteSource.Util.bytes(user.getSalt()));
        return info;
    }
}

前端使用thymeleaf框架,使用shiro的标签

//在thymeleaf框架中,shiro:hasPermission="sys:user:save" 修饰的标签,如果当前用户的权限中没有 匹配 sys:user:save 字段的。就不会显示。后台的拦截,参考shiro第二斩
  //就是配置的方式不同,在使用方面是一样的。
//在html标签中做一下声明,这个HTML页面为thymeleaf ,并且可以使用 shiro标签
  <html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">

<a shiro:hasPermission="sys:user:save" class="easyui-linkbutton" data-options="iconCls:‘icon-add‘" onclick="oepnAddDialog()">添加</a> <a shiro:hasPermission="sys:user:update" class="easyui-linkbutton" data-options="iconCls:‘icon-edit‘" onclick="openModifyDialog()">修改</a> <a shiro:hasPermission="sys:user:delete" class="easyui-linkbutton" data-options="iconCls:‘icon-remove‘" onclick="deleteUser()">删除</a>

 

以上是关于shiro三连斩之第三斩,整合 springboot的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis框架之第三篇

shiro之第一个项目

SpringBoot整合Shiro两种方式

springboo整合elasticSearch8 java client api

springboo整合elasticSearch8 java client api

springboo整合elasticSearch8 java client api