Shiro 安全权限管理框架xml式开发

框架模型原理

Subject: 主体,即“当前操作用户”。这个用户不一定是一个具体的人,与当前应用交互的任何东西都是 Subject。即一个抽象概念;所有 Subject 都绑定到 SecurityManager。

SecurityManager:安全管理器,用于管理Subject 拿到其给到Realm 在Realm中进行用户的认证与授权,可以看出它是 Shiro 的核心,它负责与后边介绍的其他组件进行交互,与Spring-Security的安全上下文相似。

Realm:领域,充当Shiro与应用程序的安全数据之间的“桥梁”或“连接器。与数据层的安全数据交互实现认证与授权。

代码实现

1.引入相关依赖

<!--rbac框架 shiro-->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-all</artifactId>
    <version>1.7.1</version>
    <type>pom</type>
</dependency>

2.在applicationcContext.xml中加入

<!-- 注册自定义realm-->
 <bean id="rbacRealm" class="com.ssm.shiro.RBACRealm">
     <!--定义的MD5加密算法-->
     <property name="credentialsMatcher" >
         <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
             <!--加密算法-->
             <property name="hashAlgorithmName" value="MD5"/>
             <!--加密次数-->
             <property name="hashIterations" value="1024"/>
         </bean>
     </property>
 </bean>
 

 <!--shiro rbac 基于角色的权限控制-->
<!-- <bean class="org.apache.shiro.spring.web.ShiroFilterFactoryBean" id="shiroFilter">  这是原生自带的ShiroFilterFactoryBean 下面是重新定义的-->
 <bean class="com.ssm.shiro.FilterFactoryBean" id="shiroFilter">
     <!--注册安全管理器-->
     <property name="securityManager" ref="securityManager"/>
     <!-- 注入当前系统的登录页面 -->
     <property name="loginUrl" value="/page/login.jsp"/>
     <!-- 注入成功页面 -->
     <property name="successUrl" value="/page/main.jsp"/>
     <!-- 注入权限不足提示页面 -->
     <property name="unauthorizedUrl" value="/page/403.jsp"/>
     <!-- 注入URL拦截规则 -->
     <property name="filterChainDefinitions">
     <value>
         /css/** = anon
         /img/** = anon
         /js/** = anon
         /plugins/** = anon
         /login.jsp* = anon
         /user/login.pp = anon
         /user/logout.pp =logout
       <!--  /product/* = perms["product"]
         /* = authc -->
     </value>
 </property>
     <property name="filters">
         <map>
             <entry key="logout" value-ref="logoutFilter"/>
         </map>
     </property>
 </bean>

 <!--配置注销过滤器-->
 <bean id="logoutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter">
     <property name="redirectUrl" value="/page/login.jsp"/>
 </bean>

 <!-- 配置 shiro 的核心组件:securityManager -->
 <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
     <!-- 配置域realm,用户名,密码,角色都保存在域里:实现从数据库中获取用户信息,
     需要我们自己创建一个类(实现Realm接口) -->
     <property name="realm" ref="rbacRealm"/>
 </bean>

3定义一个2中的Realm和FilterFacoryBean

package com.ssm.shiro;

import com.ssm.dao.UsersMapper;
import com.ssm.pojo.Permission;
import com.ssm.pojo.Role;
import com.ssm.pojo.Users;
import com.ssm.pojo.UsersExample;
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.List;
import java.util.Set;

public class RBACRealm extends AuthorizingRealm {
    @Autowired
    private UsersMapper usersMapper;

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("开始");
        SimpleAuthorizationInfo sa=new SimpleAuthorizationInfo();
        Users primaryPrincipal =(Users) principalCollection.getPrimaryPrincipal();
        Set<Role> roleSet = primaryPrincipal.getRoleSet();
        if(roleSet!=null) {
            roleSet.forEach(role -> {
                sa.addRole(role.getRoleName());
                Set<Permission> permissionSet = role.getPermissionSet();
                permissionSet.forEach(permission -> {
                    sa.addStringPermission(permission.getUrl());
                });
            });
        }
        return sa;
    }
                    //认证
            @Override
            protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//从Subject拿到用户登录的信息
                UsernamePasswordToken upToken=(UsernamePasswordToken)authenticationToken;

                UsersExample usersExample= new UsersExample();
                usersExample.createCriteria().andEmailEqualTo(upToken.getUsername());
                List<Users> users = usersMapper.selectByExample(usersExample);
                //数据库中查到的信息
                Users user=users.size()==1?users.get(0):null;
                if(user!=null){
                    //密码已加密
                    String pd=user.getPassword();

                    ByteSource bytes = ByteSource.Util.bytes(upToken.getUsername());
                     //返回这个对象让shiro帮我们完成认证
                    return new SimpleAuthenticationInfo(user,pd,bytes,this.getClass().getSimpleName());
        }
        return null;
    }
}
package com.ssm.shiro;

import com.ssm.dao.PermissionMapper;
import com.ssm.pojo.Permission;
import org.apache.shiro.config.Ini;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.web.config.IniFilterChainResolverFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class FilterFactoryBean extends ShiroFilterFactoryBean {

    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public void setFilterChainDefinitions(String definitions) {
        List<Permission> permissions = permissionMapper.selectByExample(null);
        Map<String,String> otherChains= new HashMap<>();

        permissions.forEach(permission->{
            otherChains.put(permission.getUrl(),"perms["+permission.getPermissionCode()+"]");
        });

        //从配置文件加载权限配置
        Ini ini = new Ini();
        ini.load(definitions);
        Ini.Section section = ini.getSection(IniFilterChainResolverFactory.URLS);

        if (CollectionUtils.isEmpty(section)) {
            section = ini.getSection(Ini.DEFAULT_SECTION_NAME);
        }
        section.putAll(otherChains);
        //section.put("/**","authc");
        section.put("/**","user");
        setFilterChainDefinitionMap(section);
    }
}

4在用户登录的接口中的实现

Subject subject = SecurityUtils.getSubject();//默认为未认证状态
UsernamePasswordToken token= new UsernamePasswordToken(users.getEmail(),users.getPassword());

if(users!=null&&("on").equals(remember)){
    token.setRememberMe(true);
}

try {
    subject.login(token);
} catch (AuthenticationException e) {
    e.printStackTrace();
    return "login";
}catch (Exception e){
    e.printStackTrace();
    return "login";
}
//认证成功
Users user =(Users) subject.getPrincipal();
//查询用户身上携带的角色和权限
Users u1=userService.getWithRolePermission(user.getId());
user.setRoleSet(u1.getRoleSet());
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值