Springboot整合Shiro并且在html页面使用Shiro标签

1.首先引入我们最重要的两个pom文件

 <!-- 页面使用shiro标签依赖 -->
<dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>

<!-- 集成shiro依赖 -->
        <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring-boot-web-starter -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring-boot-web-starter</artifactId>
            <version>1.4.0</version>
        </dependency>

2.首先是我们的Realm类

这个类其实和SSM整合Shiro没有什么区别

package com.ywj.springbootshiro.shiro;

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

import java.util.Set;

/**
 * @ClassName MyRealm
 * @Author ywj
 * @Describe
 * @Date 2019/3/28 0028 14:15
 */
public class MyRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    /**
     * @Description: 授权
     * @Param: [principalCollection]
     * @return: org.apache.shiro.authz.AuthorizationInfo
     * @Author: ywj
     * @Date: 2019/2/19 0019
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        String username = principalCollection.getPrimaryPrincipal().toString();
        User user = userService.queryByUsername(username);
        //获取角色
        Set<String> roles = userService.getRolesByUserId(user.getUserid());
        //获取权限
        Set<String> pers = userService.getPersByUserId(user.getUserid());
        //设置角色信息
        info.setRoles(roles);
        //设置权限信息
        info.setStringPermissions(pers);
        return info;
    }

    /**
     * @Description: 认证
     * @Param: [authenticationToken]是从controller传递过来的
     * @return: org.apache.shiro.authc.AuthenticationInfo
     * @Author: ywj
     * @Date: 2019/2/19 0019
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String username = authenticationToken.getPrincipal().toString();
        //从数据库取出对象
        User user = userService.queryByUsername(username);
//        user.getSalt() 这是我们的盐
        AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(),
                user.getPassword(),
                ByteSource.Util.bytes(user.getSalt())
                , this.getName());
        return authenticationInfo;
    }
}

3.然后是我们最重要的配置信息

因为springboot是号称0配置文件的,所以我们不用配置文件了,写配置类就好了

配置类的内容和配置文件是很相似的,对于一下解释我也写在注释里了

这里再给大家解释一下@Qualifier

Qualifier的意思是合格者,通过这个标示,表明了哪个实现类才是我们所需要的,添加@Qualifier注解,需要注意的是@Qualifier的参数名称为我们之前定义@Service注解的名称之一。

package com.ywj.springbootshiro.config;

import com.ywj.springbootshiro.shiro.MyRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.mgt.SessionsSecurityManager;
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.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import java.util.LinkedHashMap;

/**
 * @ClassName ShiroConfig
 * @Author ywj
 * @Describe
 * @Date 2019/3/28 0028 17:08
 */
@Configuration
public class ShiroConfig {

    @Bean("hashedCredentialsMatcher")
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        //指定加密方式为MD5
        credentialsMatcher.setHashAlgorithmName("MD5");
        //加密次数
        credentialsMatcher.setHashIterations(1024);
//        true指定Hash散列值使用Hex加密存. false表明hash散列值用用Base64-encoded存储
        credentialsMatcher.setStoredCredentialsHexEncoded(true);
        return credentialsMatcher;
    }


    @Bean("myRealm")
    @DependsOn("lifecycleBeanPostProcessor")//让这个类先于meRealm加载
    public MyRealm myRealm(@Qualifier("hashedCredentialsMatcher") HashedCredentialsMatcher hashedCredentialsMatcher) {
        MyRealm myRealm = new MyRealm();
        //不启用授权缓存
        myRealm.setAuthorizationCachingEnabled(false);
        //加密机制
        myRealm.setCredentialsMatcher(hashedCredentialsMatcher);
        return myRealm;
    }

    /**
     * @Description: 定义安全管理器securityManager, 注入自定义的realm
     * 这里返回的是SessionsSecurityManager是因为在我们引入的stater包中存在的就是这个类
     * @Param: [myRealm]
     * @return: org.apache.shiro.mgt.SessionsSecurityManager
     * @Author: ywj
     * @Date: 2019/3/28 0028
     */
    @Bean("securityManager")
    public SessionsSecurityManager securityManager(@Qualifier("myRealm") MyRealm myRealm) {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm(myRealm);
        return manager;
    }

    /**
     * @Description: Shiro生命周期,保证实现了Shiro内部lifecycle函数的bean执行
     * @Param: []
     * @return: org.apache.shiro.spring.LifecycleBeanPostProcessor
     * @Author: ywj
     * @Date: 2019/3/28 0028
     */
    @Bean("lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }


    /**
     * Spring的一个bean , 由Advisor决定对哪些类的方法进行AOP代理 .
     *
     * @return
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
        creator.setProxyTargetClass(true);
        return creator;
    }


    /**
     * @Description: 将spring和shiro关联起来
     * 开启shiro aop注解支持.  一定要写入上面defaultAdvisorAutoProxyCreator()自动代理。不然AOP注解不会生效
     * 使用代理方式;所以需要开启代码支持;
     * @Param: [securityManager]
     * @return: org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor
     * @Author: ywj
     * @Date: 2019/3/28 0028
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }


    /**
     * 定义shiroFilter过滤器并注入securityManager
     * 这里的配置其实和xml的配置大致是一样的
     *
     * @param securityManager
     * @return
     */
    @Bean("shiroFilterFactoryBean")
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager securityManager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setSecurityManager(securityManager);
        bean.setLoginUrl("/login");
        bean.setSuccessUrl("/main");//认证成功
        bean.setUnauthorizedUrl("/unauthorized");//没有权限
        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/index", "authc");
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/loginUser", "anon");
        //角色为4的用户才能访问admin网页
        filterChainDefinitionMap.put("/admin/*", "roles[4]");
        //权限为user:edit的角色才能访问edit页面
        filterChainDefinitionMap.put("/edit", "perms[user:edit]");
        filterChainDefinitionMap.put("/druid/**", "anon");
        //另外的页面需要用户进行登录才能访问
        filterChainDefinitionMap.put("/**", "user");
        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return bean;
    }

}

3.其余的东西我想大家都懂就不一一展示了

只贴Controller的代码

package com.ywj.springbootshiro.controller;

import com.ywj.springbootshiro.bean.User;
import com.ywj.springbootshiro.service.UserService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
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.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ClassName UserCtroller
 * @Author ywj
 * @Describe
 * @Date 2019/3/28 0028 17:00
 */
@Controller
public class UserController {


    @Autowired
    private UserService userService;

    @ApiOperation(value = "用户登录", notes = "测试用接口")//这个你们不用管
    @ApiImplicitParam(name = "user", value = "用户对象", dataType = "User", required = true)//这个你们不用管
    @RequestMapping("/login")
    public String login(User user, Model model) {
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getUsername(), user.getPassword());
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(usernamePasswordToken);
            model.addAttribute("username", user.getUsername());
            return "main";
        } catch (Exception e) {
            return "login";
        }

    }

    //退出操作
    @ApiOperation(value = "用户退出", notes = "测试用接口")//这个你们不用管
    @RequestMapping("/logout")
    public String logout() {
        Subject subject = SecurityUtils.getSubject();
        if (subject != null) {
            subject.logout();
        }
        return "login";

    }


    //没有权限
    @ApiOperation(value = "用户权限不够", notes = "测试用接口")//这个你们不用管
    @RequestMapping("/unauthorized")
    public String unauthorized() {
        return "unauthorized";
    }

    //新增页面
    @RequestMapping("/admin/addUser.html")
    public String add() {
        return "addUser";
    }

}

这里有一个注意事项在yml文件中加上这个

spring:
  main:
     allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册

4.html页面如何使用shiro标签

首先:

<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">

然后使用方法:

   <p shiro:hasPermission name="user:create">
        <a  href="admin/addUser.html">用户新增</a>
       </p>

 

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值