ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

sm整合shiro权限控制(一)

2020-04-26 11:03:46  阅读:212  来源: 互联网

标签:return String DEFAULT id sm import 权限 public shiro


CasUser:

/**
 * Copyright (c) 2020, All Rights Reserved.
 *
*/

package com.micropattern.urp.domain.entity.cas;

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

import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.micropattern.urp.domain.entity.base.BaseIdAndTime;
import com.micropattern.urp.domain.entity.role.Role;

/**
 * cas集成用户<br/>
 *
 * @author zuo
 * @Date 2020年4月20日 上午11:11:05
 * @since 1.0.0
 *  
 */
@SuppressWarnings("serial")
@Table(name = "t_cas_user")
@Entity
public class CasUser extends BaseIdAndTime{
    
    private String userName;
    private String role;
    @Transient
    private String searchKey;
    private String salt;
    private String password;
    private String remark;
    
    /**
     * 用户角色关系表
     */
    @JsonIgnore
    @ManyToMany
    @JoinTable(name="t_cas_user_role", joinColumns={@JoinColumn(name="user_id",referencedColumnName="id")},
               inverseJoinColumns={@JoinColumn(name="role_id",referencedColumnName="id")})
    private Set<Role> roles = new HashSet<>();

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public String getSearchKey() {
        return searchKey;
    }

    public void setSearchKey(String searchKey) {
        this.searchKey = searchKey;
    }

    public Set<Role> getRoles() {
        return roles;
    }

    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }

    public String getSalt() {
        return salt;
    }

    public void setSalt(String salt) {
        this.salt = salt;
    }

    public String getPassword() {
        return password;
    }

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

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }
    
}
View Code

Role:

/**
 * Copyright (c) 2020, All Rights Reserved.
 *
*/

package com.micropattern.urp.domain.entity.role;

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

import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.micropattern.urp.domain.entity.base.BaseIdAndTime;
import com.micropattern.urp.domain.entity.cas.CasUser;
import com.micropattern.urp.domain.entity.permission.Permission;

/**
 * 此处应有类说明<br/>
 *
 * @author why
 * @Date 2020年4月13日 下午3:36:58
 * @since 1.0.0
 *  
 */
@SuppressWarnings("serial")
@Table(name = "t_cas_role")
@Entity
public class Role extends BaseIdAndTime{
    /**
     * 角色名
     */
    private String name;
    
    private Boolean delFlag;
    
    private String remark;
    
    /**
     * 角色,用户,多对多
     */
    @JsonIgnore
    @ManyToMany(mappedBy="roles")
    private Set<CasUser> users=new HashSet<>();
    
    @JsonIgnore
    @ManyToMany
    @JoinTable(name="t_cas_role_permission", joinColumns={@JoinColumn(name="role_id",referencedColumnName="id")},
               inverseJoinColumns={@JoinColumn(name="permission_id",referencedColumnName="id")})
    private Set<Permission> permissions = new HashSet<>();

    public Set<Permission> getPermissions() {
        return permissions;
    }

    public void setPermissions(Set<Permission> permissions) {
        this.permissions = permissions;
    }

    public Boolean getDelFlag() {
        return delFlag;
    }

    public void setDelFlag(Boolean delFlag) {
        this.delFlag = delFlag;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<CasUser> getUsers() {
        return users;
    }

    public void setUsers(Set<CasUser> users) {
        this.users = users;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }
    
}
View Code

Permission:

/**
 * Copyright (c) 2020, All Rights Reserved.
 *
*/

package com.micropattern.urp.domain.entity.permission;

import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Transient;

import com.micropattern.urp.domain.entity.base.BaseIdAndTime;

/**
 * 此处应有类说明<br/>
 *
 * @author why
 * @Date 2020年4月13日 下午3:50:53
 * @since 1.0.0
 *  
 */
@SuppressWarnings("serial")
@Table(name = "t_cas_permission")
@Entity
public class Permission extends BaseIdAndTime{
    
    /**
     * 权限名称
     */
    private String name;
    /**
     * 权限类型
     */
    private Integer type;
    /**
     * 资源路径
     */
    private String url;
    
    private Boolean delFlag;
    
    /**
     * 是否勾选
     * true : 勾选
     * false : 未勾选
     */
    @Transient
    private Boolean checked;
    
    /**
     * 排序
     */
    private Integer sort;
    
    /**
     * 菜单等级
     * 1:父节点
     * 2:子节点
     */
    private Integer level;
    
    /**
     * 父id
     */
    private String parentId;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getType() {
        return type;
    }
    public void setType(Integer type) {
        this.type = type;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public Boolean getDelFlag() {
        return delFlag;
    }
    public void setDelFlag(Boolean delFlag) {
        this.delFlag = delFlag;
    }
    public Boolean getChecked() {
        return checked;
    }
    public void setChecked(Boolean checked) {
        this.checked = checked;
    }
    public Integer getSort() {
        return sort;
    }
    public void setSort(Integer sort) {
        this.sort = sort;
    }
    public Integer getLevel() {
        return level;
    }
    public void setLevel(Integer level) {
        this.level = level;
    }
    public String getParentId() {
        return parentId;
    }
    public void setParentId(String parentId) {
        this.parentId = parentId;
    }
   
}
View Code

建表sql:

CREATE TABLE `t_cas_user` (
  `id` varchar(255) NOT NULL COMMENT '用户id',
  `password` varchar(255) DEFAULT NULL COMMENT '密码',
  `user_name` varchar(64) DEFAULT NULL COMMENT '用户名',
  `role` varchar(64) DEFAULT NULL COMMENT '角色',
  `salt` varchar(64) DEFAULT NULL COMMENT '密码盐',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `create_user` varchar(64) DEFAULT NULL COMMENT '创建用户',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `update_user` varchar(64) DEFAULT NULL COMMENT '更新用户',
  `version` int(11) DEFAULT '0',
  `remark` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `t_cas_user_role` (
  `user_id` varchar(255) NOT NULL,
  `role_id` varchar(255) NOT NULL,
  PRIMARY KEY (`user_id`,`role_id`),
  KEY `FK_h6p8coxk4oxl6txq1hd7jim82` (`role_id`),
  CONSTRAINT `FK_h6p8coxk4oxl6txq1hd7jim82` FOREIGN KEY (`role_id`) REFERENCES `t_cas_role` (`id`),
  CONSTRAINT `FK_oajhcq0g0st27cocwugnq47mf` FOREIGN KEY (`user_id`) REFERENCES `t_cas_user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `t_cas_role` (
  `id` varchar(255) NOT NULL,
  `name` varchar(64) DEFAULT NULL COMMENT '权限名称',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `create_user` varchar(255) DEFAULT NULL COMMENT '创建用户',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `update_user` varchar(255) DEFAULT NULL COMMENT '更新用户',
  `version` int(11) DEFAULT '0' COMMENT '版本号',
  `del_flag` bit(1) DEFAULT NULL COMMENT '是否删除,0:未删除',
  `remark` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色表';


CREATE TABLE `t_cas_role_permission` (
  `role_id` varchar(255) NOT NULL,
  `permission_id` varchar(255) NOT NULL,
  PRIMARY KEY (`role_id`,`permission_id`),
  KEY `FK_ssde3tsrhwnl5s15n0cys16p0` (`permission_id`),
  CONSTRAINT `FK_13au68ku0hwd8b01mtpdp49mo` FOREIGN KEY (`role_id`) REFERENCES `t_cas_role` (`id`),
  CONSTRAINT `FK_ssde3tsrhwnl5s15n0cys16p0` FOREIGN KEY (`permission_id`) REFERENCES `t_cas_permission` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `t_cas_permission` (
  `id` varchar(255) NOT NULL COMMENT '主键',
  `name` varchar(100) DEFAULT NULL COMMENT '权限名称',
  `type` int(11) DEFAULT NULL COMMENT '权限类型,1:菜单 2:按钮 3:API',
  `url` varchar(200) DEFAULT NULL COMMENT '资源路径',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `create_user` varchar(255) DEFAULT NULL COMMENT '创建用户',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `update_user` varchar(255) DEFAULT NULL COMMENT '更新用户',
  `version` int(11) DEFAULT '0' COMMENT '版本号',
  `del_flag` bit(1) DEFAULT NULL COMMENT '是否删除,0:未删除',
  `sort` int(11) DEFAULT '0' COMMENT '排序',
  `parent_id` varchar(64) DEFAULT NULL COMMENT '父id',
  `level` int(11) DEFAULT NULL COMMENT '权限等级,1:父节点,2:子节点',
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='资源表';
View Code

spring-shiro.xml:

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
                        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" 
    default-lazy-init="true">
  
    <description>Shiro Configuration</description>  
  
    <!-- 安全管理器 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="userRealm" />
        <property name="cacheManager" ref="cacheManager" />
        <!--设置会话管理器-->
        <!-- <property name="sessionManager" ref="sessionManager"></property> -->
    </bean>  
  
    <!-- 項目自定义的Realm -->  
    <bean id="userRealm" class="com.micropattern.urp.common.shiro.UserRealm">  
        <property name="cacheManager" ref="cacheManager" />
        <!-- <property name="credentialsMatcher" ref="credentialsMatcher"></property> -->
        <property name="credentialsMatcher" ref="customCredentialsMatcher"></property>
    </bean>  
  
    <!-- Shiro Filter -->  
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
        <property name="securityManager" ref="securityManager" />  
        <!-- 用户登录地址 -->
        <property name="loginUrl" value="/login"/>  
        <!-- 登录成功 -->
        <property name="successUrl" value="/login"/>  
        <!-- 未授权的失败页 -->
        <property name="unauthorizedUrl" value="/error"/>
        <property name="filterChainDefinitions">
            <value>  
                 <!-- 设置访问用户list页面需要授权操作 -->
                /** = anon
                /manage = anon
                
            </value>  
        </property>  
    </bean>  
    
    <!--配置会话管理器-->
    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <!--设置session的超时时间20min-->
        <property name="globalSessionTimeout" value="1200000"></property>
        <!--删除失效session-->
        <property name="deleteInvalidSessions" value="true"></property>
    </bean>
  
   <!-- 给予shior的内存缓存系统 -->
    <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager"/>  
  
    <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->  
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />  
  
    <!-- <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
        <property name="hashAlgorithmName" value="SHA-512"></property>
        <property name="hashIterations" value="2"></property>
    </bean> -->
    
    <bean id="customCredentialsMatcher" class="com.micropattern.urp.common.shiro.CustomCredentialsMatcher"/>

    
</beans>
View Code

UserRealm:

/**
 * Copyright (c) 2020, All Rights Reserved.
 *
 */

package com.micropattern.urp.common.shiro;

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

import org.apache.shiro.SecurityUtils;
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.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;
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 com.micropattern.urp.common.constant.ErrorCode.SystemUserError;
import com.micropattern.urp.common.enums.SystemUserStatus;
import com.micropattern.urp.common.exception.BusinessException;
import com.micropattern.urp.domain.entity.permission.Permission;
import com.micropattern.urp.domain.entity.role.Role;
import com.micropattern.urp.domain.entity.system.User;
import com.micropattern.urp.domain.service.system.UserService;

/**
 * shiro管理<br/>
 *
 * @author zuo
 * @Date 2020年4月13日 下午2:10:29
 * @since 1.0.0
 * 
 */
public class UserRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    //授权认证
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.out.println("=============执行授权逻辑================");
        Set<String> set = new HashSet<>();// 权限集合
        // 给资源进行授权
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        User tokenUser = (User) principals.getPrimaryPrincipal();
        User user = userService.findByUserName(tokenUser.getUserName());
        Set<Role> roles = user.getRoles();
        for (Role role : roles) {
            Set<Permission> permissions = role.getPermissions();
            for (Permission permission : permissions) {
                set.add(permission.getUrl());
            }
        }
        simpleAuthorizationInfo.addStringPermissions(set);
        return simpleAuthorizationInfo;
    }

    //登录认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("=============执行认证逻辑================");
        UsernamePasswordToken tokens = (UsernamePasswordToken) token;
        User user = userService.findByUserName(tokens.getUsername());
        if (user == null) {
            throw new BusinessException(SystemUserError.USER_NAME_NOTEXISTS);
        }
        if (user.getDelFlag()) {
            throw new BusinessException(SystemUserError.USER_NAME_NOTEXISTS);
        } else if (SystemUserStatus.ENABLE != user.getStatus()) {
            throw new BusinessException(SystemUserError.LOGIN_FORBID);
        }
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user, user.getPassword(),
                ByteSource.Util.bytes(user.getSalt()), getName());
        return simpleAuthenticationInfo;
    }

    //自定义密码校验
    @Override
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        super.setCredentialsMatcher(new CustomCredentialsMatcher());
    }

    //清空权限缓存 
    public void clearCachedAuthorization(){
        clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
    }
    
}
View Code

shiro清空缓存:

/**
 * Copyright (c) 2020, All Rights Reserved.
 *
*/

package com.micropattern.urp.common.shiro;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.mgt.RealmSecurityManager;

/**
 * shiro清除缓存<br/>
 *
 * @author zuo
 * @Date 2020年4月17日 上午9:25:50
 * @since 1.0.0
 *  
 */
public class ShiroUtils {
    
    public static void clearShiroCache(){
        RealmSecurityManager rsm = (RealmSecurityManager)SecurityUtils.getSecurityManager();
        UserRealm realm = (UserRealm)rsm.getRealms().iterator().next();
        realm.clearCachedAuthorization();
    }
    
}
View Code

自定义加密类:

/**
 * Copyright (c) 2018, All Rights Reserved.
 * 
 */

package com.micropattern.urp.common.utils;

import java.security.MessageDigest;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 签名加密工具类<br/>
 * Date: 2018年1月29日 下午2:15:59 <br/>
 * 
 * @author xin.zhou
 * @version
 * @since JDK 1.7
 * @see
 */
public class SignUtils {
    private static final Logger LOG = LoggerFactory.getLogger(SignUtils.class);
    private static final String DEFAULT_CHARSET = "UTF-8";
    private static final char[] DIGITS;

    public static String hmacSha256(String key, String data) {
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), mac.getAlgorithm());
            mac.init(signingKey);
            return encodeHex(mac.doFinal(data.getBytes()));
        } catch (Exception e) {
            LOG.error("execute hmacSHA256 error", e);
        }

        return null;
    }

    private static String encrypt(String algorithm, String data, String charset) {
        try {
            byte[] msg = data.getBytes(charset);
            MessageDigest md = MessageDigest.getInstance(algorithm);
            return encodeHex(md.digest(msg));
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
        }
        return null;
    }

    public static String md5(String data, String charset) {
        return encrypt("MD5", data, charset);
    }

    public static String sha1(String data, String charset) {
        return encrypt("SHA1", data, charset);
    }

    public static String sha1(String data) {
        return sha1(data, DEFAULT_CHARSET);
    }

    public static String sha256(String data, String charset) {
        return encrypt("SHA-256", data, charset);
    }

    public static String sha256(String data) {
        return sha256(data, DEFAULT_CHARSET);
    }

    public static String sha512(String data, String charset) {
        return encrypt("SHA-512", data, charset);
    }

    public static String sha512(String data) {
        return sha512(data, DEFAULT_CHARSET);
    }

    private static String encodeHex(byte[] data) {
        int l = data.length;
        char[] out = new char[l << 1];
        int i = 0;

        for (int j = 0; i < l; ++i) {
            out[j++] = DIGITS[(240 & data[i]) >>> 4];
            out[j++] = DIGITS[15 & data[i]];
        }

        return new String(out);
    }

    static {
        DIGITS = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    }
    
    public static void main(String[] args) {
        //UPJW1u
        //1d0c7526881640dfb2a7018c9e2328a3b520b6236bf53378b42059578cc603ffa81c159384119c5bcf280d16503abe32d747104e7c409d53c90ced1e7136fe10
        String salt=RandomStringUtils.randomAlphanumeric(6);
        System.out.println(salt+" "+sha512("123456"+salt));
    }
}
View Code

shiro加密校验:

/**
 * Copyright (c) 2020, All Rights Reserved.
 *
*/

package com.micropattern.urp.common.shiro;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
import org.apache.shiro.subject.PrincipalCollection;
import com.micropattern.urp.common.utils.SignUtils;
import com.micropattern.urp.domain.entity.system.User;

/**
 * 自定义shiro密码校验<br/>
 *
 * @author zuo
 * @Date 2020年4月14日 下午5:30:44
 * @since 1.0.0
 *  
 */
public class CustomCredentialsMatcher extends SimpleCredentialsMatcher {
    
    @Override
    public boolean doCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) {
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        PrincipalCollection principals = info.getPrincipals();
        User user = (User) principals.getPrimaryPrincipal();
        String salt = user.getSalt();
        String password = String.valueOf(token.getPassword());
        Object tokenCredentials = encrypt(password, salt);
        Object accountCredentials = getCredentials(info);
        //将密码加密与系统加密后的密码校验,内容一致就返回true,不一致就返回false
        return equals(tokenCredentials, accountCredentials);
    }

    //密码加密方法
    private String encrypt(String password, String salt) {
        return SignUtils.sha512(password + salt);
    }

    
}
View Code

页面按钮控制:

<@shiro.hasPermission name="sysuser:add">
<button class="btn btn-primary btn-xs" id="addBtn"><i class="ace-icon glyphicon glyphicon-plus"></i>新增</button>
</@shiro.hasPermission>

标签:return,String,DEFAULT,id,sm,import,权限,public,shiro
来源: https://www.cnblogs.com/chong-zuo3322/p/12777786.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有