1. 程式人生 > 其它 >SpringBoot+Thymeleaf+Shiro整合

SpringBoot+Thymeleaf+Shiro整合

技術標籤:javashirospring boot

SpringBoot+Thymeleaf+Shiro整合

pom.xml

   <!-- shiro -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.6.0</version>
        </dependency>
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>

user.java(使用者實體類):

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.lamda.shiro.Role;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Set;

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "t_tzsb_user")
public class UserEntity {
    //id
    @TableId(type = IdType.AUTO)
    private Integer id;
    //使用者名稱
    private String userName;
    //密碼
    private String passWord;
    //部門
    private String department;
    //郵箱
    private String mail;
    //角色名稱
    private String roleName;
}

Role.java(角色對應實體類):

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Set;

/**
 * <p>
 *
 * </p>
 *
 * @author qcl
 * @since 2021-02-04
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("T_TZSB_ROLE")
public class Role implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * id
     */
    @TableId(type = IdType.AUTO)
    private Integer id;

    /**
     * 角色名稱
     */
    @TableField("ROLE_NAME")
    private String roleName;

    /**
     * 使用者ID
     */
    @TableField("USER_ID")
    private Integer userId;


}

Permissions.java(許可權對應實體類):

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;

/**
 * @author qinchunlin
 * @version 1.0.0
 * @ClassName Permissions
 * @Description
 * @createTime 2021年01月09日 10:17:00
 */
@Data
@AllArgsConstructor
@TableName("T_TZSB_PERMISSIONS")
public class Permissions {
    @TableId(type = IdType.AUTO)
    private Integer id;
    private String permissionsName;
    private Integer roleId;
}

CustomRealm.java

  • 自定義Realm用於查詢使用者的角色和許可權資訊並儲存到許可權管理器
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lamda.entity.yhgl.UserEntity;
import com.lamda.service.qt.RoleService;
import com.lamda.service.yhgl.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.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

public class CustomRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;


    /**
     * @MethodName doGetAuthorizationInfo
     * @Description 許可權配置類
     * @Param [principalCollection]
     * @Return AuthorizationInfo
     * @Author WangShiLin
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //獲取登入使用者名稱
        String name = (String) principalCollection.getPrimaryPrincipal();
        //查詢使用者名稱稱
        UserEntity user = userService.getUserByName(name);
        //新增角色和許可權
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            Role role=roleService.getOne(new QueryWrapper<Role>().eq("ROLE_NAME",user.getRoleName()));
            //新增角色
            simpleAuthorizationInfo.addRole(role.getRoleName());
            //新增許可權
            for (Permissions permissions : userService.getPermissions(role.getId())) {
                simpleAuthorizationInfo.addStringPermission(permissions.getPermissionsName());
            }

        return simpleAuthorizationInfo;
    }

    /**
     * @MethodName doGetAuthenticationInfo
     * @Description 認證配置類
     * @Param [authenticationToken]
     * @Return AuthenticationInfo
     * @Author WangShiLin
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        if (StringUtils.isEmpty(authenticationToken.getPrincipal())) {
            return null;
        }
        //獲取使用者資訊
        String name = authenticationToken.getPrincipal().toString();
        UserEntity user = userService.getUserByName(name);
        if (user == null) {
            //這裡返回後會報出對應異常
            return null;
        } else {
            //這裡驗證authenticationToken和simpleAuthenticationInfo的資訊
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, user.getPassWord(), getName());
            return simpleAuthenticationInfo;
        }
    }
}


ShiroConfig.java

  • 把CustomRealm和SecurityManager等注入到spring容器中
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.mgt.SecurityManager;
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.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;
/**
 * @author qinchunlin
 * @version 1.0.0
 * @ClassName shiroConfig
 * @Description
 * @createTime 2021年01月09日 10:30:00
 */
@Configuration
public class ShiroConfig {

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

    //將自己的驗證方式加入容器
    @Bean
    public CustomRealm myShiroRealm() {
        CustomRealm customRealm = new CustomRealm();
        return customRealm;
    }

    //許可權管理,配置主要是Realm的管理認證
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        return securityManager;
    }

    //Filter工廠,設定對應的過濾條件和跳轉條件
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String, String> map = new HashMap<>();
        //登出
        map.put("/user/logout", "logout");
        //忽略靜態資源
        map.put("/**/*.css", "anon");
        map.put("/**/*.js", "anon");
        map.put("/**/*.html", "anon");
        map.put("/**/*.conf", "anon");
        //對所有使用者認證
        map.put("/**", "anon");
        //登入
        shiroFilterFactoryBean.setLoginUrl("/login");
        //首頁
        shiroFilterFactoryBean.setSuccessUrl("/ggts/getGgts");
        //錯誤頁面,認證不通過跳轉
        shiroFilterFactoryBean.setUnauthorizedUrl("/error");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }


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

    /**
     * 頁面上使用shiro標籤
     * @return
     */
    @Bean(name = "shiroDialect")
    public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }
}

全域性異常處理

import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.AuthorizationException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@[email protected]
public class MyExceptionHandler {

    @ExceptionHandler
    @ResponseBody
    public String ErrorHandler(AuthorizationException e) {
        log.error("沒有通過許可權驗證!", e);
        return "沒有通過許可權驗證!";
    }}

後端控制權限

  • 這兩個註解可以放在類上或方法上
 @RequiresRoles("admin")
 @RequiresPermissions("query")

前端使用shiro標籤(兩種方式)(使用thymeleaf時)

在這裡插入圖片描述
在這裡插入圖片描述