shiro授权-SSM

一、shiro授权角色、权限

1.Mapper层

①.SysUserMapper

package com.zking.ssm.book.mapper;

import com.zking.ssm.book.model.SysUser;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.Set;

@Repository
public interface SysUserMapper {

    /**
     * 根据用户账号查询用户对象信息
     *
     * @param username
     * @return
     */
    SysUser userLogin(@Param("username") String username);

    /**
     * 根据username查询该用户的所有角色,用于角色验证
     */

    Set<String> findRoles(@Param("username") String username);

    /**
     * 根据username查询他所拥有的权限信息,用于权限判断
     */

    Set<String> findPermissions(@Param("username") String username);
}

②.SysUserMapper.xml

<select id="findRoles" resultType="java.lang.String">
        select
        r.rolename
        from
        t_sys_user u,t_sys_user_role ur,t_sys_role r
        where
        u.userid=ur.userid and ur.roleid=r.roleid
        and u.username=#{username}
    </select>
  <select id="findPermissions" resultType="java.lang.String">
    select
    p.permission
    from
    t_sys_user u,t_sys_user_role ur,t_sys_role r,
    t_sys_role_permission rp,t_sys_permission p
    where
    u.userid=ur.userid and ur.roleid=r.roleid and
    r.roleid=rp.roleid and rp.perid=p.perid and
    u.username=#{username}
  </select>

2.Service层

①.ISysUserService

package com.zking.ssm.book.service;

import com.zking.ssm.book.model.SysUser;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.Set;

public interface ISysUserService {

    /**
     * 根据用户账号查询用户对象信息
     *
     * @param username
     * @return
     */
    SysUser userLogin(String username);

    /**
     * 根据username查询该用户的所有角色,用于角色验证
     */

    Set<String> findRoles(String username);

    /**
     * 根据username查询他所拥有的权限信息,用于权限判断
     */

    Set<String> findPermissions(String username);

}

②.SysUserServiceImpl

package com.zking.ssm.book.service.impl;

import com.zking.ssm.book.mapper.SysUserMapper;
import com.zking.ssm.book.model.SysUser;
import com.zking.ssm.book.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Set;

@Service
public class SysUserServiceImpl implements ISysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Override
    public SysUser userLogin(String username) {
        return sysUserMapper.userLogin(username);
    }

    @Override
    public Set<String> findRoles(String username) {
        return sysUserMapper.findRoles(username);
    }

    @Override
    public Set<String> findPermissions(String username) {
        return sysUserMapper.findPermissions(username);
    }
}

3.重写自定义Realm配置Shiro授权认证

package com.zking.ssm.book.shiro;

import com.zking.ssm.book.model.SysUser;
import com.zking.ssm.book.service.ISysUserService;
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 org.springframework.stereotype.Component;

import java.util.Set;

/**
 * 自定义Realm的安全数据源,采用数据库方式
 * spring-shiro.xml
 * <bean id="" class="ShiroRealm">
 */
public class ShiroRealm extends AuthorizingRealm {

    @Autowired
    private ISysUserService sysUserService;

    /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取登录账号
        String username = principalCollection.getPrimaryPrincipal().toString();
        //根据username获取用户对应角色
        Set<String> roles = sysUserService.findRoles(username);
        //根据username获取用户对应角色权限
        Set<String> permissions = sysUserService.findPermissions(username);
        //创建SimpleAuthorizationInfo
        SimpleAuthorizationInfo simple=new SimpleAuthorizationInfo();
        //填充用户的角色和权限
        simple.setRoles(roles);
        simple.setStringPermissions(permissions);
        return simple;
    }

    /**
     * 认证
     * @param authenticationToken 传入的账号密码令牌Token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //获取账号
        String username = authenticationToken.getPrincipal().toString();
        //获取密码
        String password = authenticationToken.getCredentials().toString();
        //根据账号查询数据库中的用户对象信息
        SysUser sysUser = sysUserService.userLogin(username);
        //判断sysUser是否为空
        if(null==sysUser)
            throw new UnknownAccountException("账号不存在!");
        //创建SimpleAuthenticationInfo,传入正确的账号和密码(来自于数据库)
        SimpleAuthenticationInfo simple1=new SimpleAuthenticationInfo(
                sysUser.getUsername(),
                sysUser.getPassword(),
                ByteSource.Util.bytes(sysUser.getSalt()),
                this.getName()
        );
        return simple1;
    }
}

4.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.xsd">

    <!--1.注册自定义的Realm,采用数据库方式-->
    <bean id="shiroRealm" class="com.zking.ssm.book.shiro.ShiroRealm">

        <!--开启缓存-->
        <property name="cachingEnabled" value="true"/>
        <!--开启授权缓存-->
        <property name="authorizationCachingEnabled" value="true"/>
        <!--设置ehcache的中的缓存对象名-->
        <property name="authorizationCacheName" value="shiroAuthzCache"/>

        <!--配置Shiro明文密码如何进行加密-->
        <!--注意:重要的事情说三次~~~~~~此处加密方式要与用户注册时的算法一致 -->
        <!--注意:重要的事情说三次~~~~~~此处加密方式要与用户注册时的算法一致 -->
        <!--注意:重要的事情说三次~~~~~~此处加密方式要与用户注册时的算法一致 -->
        <!--以下三个配置告诉shiro将如何对用户传来的明文密码进行加密-->
        <property name="credentialsMatcher">
            <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                <!--指定hash算法为MD5-->
                <property name="hashAlgorithmName" value="md5"/>
                <!--指定散列次数为1024次-->
                <property name="hashIterations" value="1024"/>
                <!--true指定Hash散列值使用Hex加密存. false表明hash散列值用用Base64-encoded存储-->
                <property name="storedCredentialsHexEncoded" value="true"/>
            </bean>
        </property>
    </bean>
    <!--2.创建安全管理器SecurityManage,并更换Realm-->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="shiroRealm" />
        <!--配置会话管理器-->
        <property name="sessionManager" ref="sessionManager"/>
        <!--配置缓存管理器-->
        <property name="cacheManager" ref="cacheManager"/>
    </bean>
    <!--3.配置Shiro核心过滤器-->
    <!--Shiro核心过滤器-->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- Shiro的核心安全接口,这个属性是必须的 -->
        <property name="securityManager" ref="securityManager" />
        <!-- 身份验证失败,跳转到登录页面 -->
        <property name="loginUrl" value="/home/index.html"/>
        <!-- 身份验证成功,跳转到指定页面 -->
        <!--<property name="successUrl" value="/index.jsp"/>-->
        <!-- 权限验证失败,跳转到指定页面 -->
        <!--<property name="unauthorizedUrl" value="/noauthorizeUrl.jsp"/>-->
        <!-- Shiro连接约束配置,即过滤链的定义 -->
        <property name="filterChainDefinitions">
            <value>
                <!--anon 表示匿名访问,不需要认证以及授权-->
                <!--authc表示需要认证 没有进行身份认证是不能进行访问的-->
                /user/userLogin=anon
                /book/**=authc
                <!-- /css/**               = anon
                 /images/**            = anon
                 /js/**                = anon
                 /                     = anon
                 /user/logout          = logout
                 /user/**              = anon
                 /userInfo/**          = authc
                 /dict/**              = authc
                 /console/**           = roles[admin]
                 /**                   = anon-->
            </value>
        </property>
    </bean>
    <!--4.配置Shiro的生命周期-->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

shiro好处:安全性高

shiro坏处:性能差

二、注解式开发

1.常用注解介绍

  @RequiresAuthenthentication:表示当前Subject已经通过login进行身份验证;即 Subjecj.isAuthenticated()返回 true
  @RequiresUser:表示当前Subject已经身份验证或者通过记住我登录的
  @RequiresGuest:表示当前Subject没有身份验证或者通过记住我登录过,即是游客身份
  @RequiresRoles(value = {"admin","user"},logical = Logical.AND):表示当前Subject需要角色admin和user
  @RequiresPermissions(value = {"user:delete","user:b"},logical = Logical.OR):表示当前Subject需要权限user:delete或者user:b

注:
  必须将Shiro注解的开启放置到spring-mvc.xml中(即放在springMVC容器中加载),不然Shiro注解开启无效!!!

2.注解的使用

①.BookController

/**
     * 返回List<T>格式的JSON数据
     * @param book
     * @param req
     * @return
     */
    @RequiresRoles(value = {"管理员","高级用户"},logical = Logical.OR)
    @RequestMapping("/queryLstBook")
    @ResponseBody
    public List<Book> queryLstBook(Book book,HttpServletRequest req){
        PageBean pageBean=new PageBean();
        pageBean.setRequest(req);
        List<Book> books = bookService.queryBookPager(book,pageBean);
        return books;
    }

    /**
     * 查询返回JSON数据的混合格式
     * 例如:
     * {'total':81,'rows':[{},{},{},...]}
     * @param book
     * @param req
     * @return
     */
    @RequiresPermissions("bookmanager:book:update")
    @RequestMapping("/queryLstBook1")
    @ResponseBody
    public Map<String,Object> queryLstBook1(Book book,HttpServletRequest req){
        PageBean pageBean=new PageBean();
        pageBean.setRequest(req);
        List<Book> books = bookService.queryBookPager(book,pageBean);
        Map<String,Object> json=new HashMap<>();
        json.put("total",pageBean.getTotal());
        json.put("rows",books);
        return json;
    }

②.Spring-mvc.xml

<!--配置Shiro注解式权限-->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
          depends-on="lifecycleBeanPostProcessor">
        <property name="proxyTargetClass" value="true"></property>
    </bean>
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    </bean>

最后执行结果为: 

至此,shiro授权-SSM介绍完毕,由于作者水平有限难免有疏漏,欢迎留言纠错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值