shiro(入门二)shiro集成spring+mybatis+springMvc+Redis(附带源码)

1.准备工作

1.1准备所需要的依赖架包
<dependencies>
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-contextartifactId>
      <version>4.3.10.RELEASEversion>
    dependency>

    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-webartifactId>
      <version>4.3.10.RELEASEversion>
    dependency>

    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-webmvcartifactId>
      <version>4.3.10.RELEASEversion>
    dependency>

    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-testartifactId>
      <version>4.3.10.RELEASEversion>
    dependency>

    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-txartifactId>
      <version>4.3.10.RELEASEversion>
    dependency>

    <dependency>
      <groupId>org.apache.shirogroupId>
      <artifactId>shiro-coreartifactId>
      <version>1.3.2version>
    dependency>

    <dependency>
      <groupId>org.apache.shirogroupId>
      <artifactId>shiro-springartifactId>
      <version>1.3.2version>
    dependency>

    <dependency>
      <groupId>org.apache.shirogroupId>
      <artifactId>shiro-webartifactId>
      <version>1.3.2version>
    dependency>
    <dependency>
      <groupId>junitgroupId>
      <artifactId>junitartifactId>
      <version>4.12version>
    dependency>

    <dependency>
      <groupId>mysqlgroupId>
      <artifactId>mysql-connector-javaartifactId>
      <version>5.1.41version>
    dependency>

    <dependency>
      <groupId>com.alibabagroupId>
      <artifactId>druidartifactId>
      <version>1.0.29version>
    dependency>
    
    <dependency>
      <groupId>org.mybatisgroupId>
      <artifactId>mybatisartifactId>
      <version>3.1.0version>
    dependency>
    
    <dependency>
      <groupId>org.mybatisgroupId>
      <artifactId>mybatis-springartifactId>
      <version>1.3.1version>
    dependency>

    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-jdbcartifactId>
      <version>4.3.10.RELEASEversion>
    dependency>

    <dependency>
      <groupId>org.aspectjgroupId>
      <artifactId>aspectjweaverartifactId>
      <version>1.8.10version>
    dependency>



  dependencies>
1.2 demo路径结构:

shiro(入门二)shiro集成spring+mybatis+springMvc+Redis(附带源码)_第1张图片

1.3 配置文件:

jdbc.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
username=root
password=123456
#定义初始连接数
initialSize=1
#定义最大连接数
maxActive=20
#定义最小空闲
minIdle=1
#定义最长等待时间
maxWait=60000

spring.xml


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    
    <context:component-scan base-package="com.baidu.shiro" />

    
    <bean id="propertyConfigurer"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:spring/jdbc.properties" />
    bean>

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close">
        <property name="driverClassName" value="${driver}" />
        <property name="url" value="${url}" />
        <property name="username" value="${username}" />
        <property name="password" value="${password}" />
        
        <property name="initialSize" value="${initialSize}">property>
        
        <property name="maxActive" value="${maxActive}">property>
        
        <property name="minIdle" value="${minIdle}">property>
        
        <property name="maxWait" value="${maxWait}">property>
    bean>

    
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        
        <property name="typeAliasesPackage" value="com/baidu/shiro/domain" />
        <property name="dataSource" ref="dataSource" />
        
        <property name="mapperLocations" value="classpath*:com/baidu/shiro/mapping/*.xml">property>
    bean>

    
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com/baidu/shiro/dao" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory">property>
    bean>


    
    
    
    
    
    
    
    
   <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager" />
            <property name="loginUrl" value="login.html" />
            <property name="unauthorizedUrl" value="403.html" />
            <property name="filterChainDefinitions">
                <value>
                    /login.html = anon
                    /subLogin = anon
                    /testRole = roles["admin"]
                    /testRole1 = roles["admin", "admin1"]
                    /testRole2 = rolesOr["admin", "admin1"]
                    /testPerms = perms["user:delete"]
                    /testPerms1 = perms["user:delete","user:update"]
                    /* = authc
                value>

            property>
   bean>

    
    <bean class="org.apache.shiro.web.mgt.DefaultWebSecurityManager" id="securityManager">
       <property name="realm" ref="realm" />

    bean>
    
    <bean class="com.baidu.shiro.realm.CustomRealm" id="realm">
        <property name="credentialsMatcher" ref="credentialsMatcher" />
    bean>
    
    <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher" id="credentialsMatcher">
        <property name="hashAlgorithmName" value="md5"/>
        <property name="hashIterations" value="1"/>
    bean>
beans>

配置注解都有详细介绍

springmvc:


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    
    <context:component-scan base-package="com.baidu.shiro.controller"/>

    <mvc:annotation-driven/>
    
    <mvc:resources location="/" mapping="/*"/>

    
    <aop:config proxy-target-class="true"/>
    
    <bean class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
    
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    bean>
beans>
1.4 数据库表字段:

shiro(入门二)shiro集成spring+mybatis+springMvc+Redis(附带源码)_第2张图片
shiro(入门二)shiro集成spring+mybatis+springMvc+Redis(附带源码)_第3张图片
在这里插入图片描述
在这里插入图片描述

2.核心源代码:

自定义realm

package com.baidu.shiro.realm;

import com.baidu.shiro.domain.User;
import com.baidu.shiro.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.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class CustomRealm extends AuthorizingRealm {

    @Resource
    private UserService userService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String username = (String) principals.getPrimaryPrincipal();
        // 从数据库或者缓存中获得角色数据
        Set<String> roles = getRolesByUserName(username);
        //获得权限数据
        Set<String> permissions = getPermissionsByUserName(username);

        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.setStringPermissions(permissions);
        simpleAuthorizationInfo.setRoles(roles);

        return simpleAuthorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 1.从主体传过来的认证信息中,获得用户名
        String username = (String) token.getPrincipal();

        // 2.通过用户名到数据库中获取凭证
        String password = getPasswordByUsername(username);
        if (password == null) {
            return null;
        }
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,
                password, "customRealm");
        //加盐
        simpleAuthenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(username));
        return simpleAuthenticationInfo;
    }

    //通过用户名获得密码
    private String getPasswordByUsername(String username) {
        User user = userService.getUserByUserName(username);
        return user.getPassword();
    }

    //通过用户名获得角色信息
    private Set<String> getRolesByUserName(String username) {
        List<String> roles = userService.getRolesByUserName(username);
        Set<String> sets = new HashSet<String>(roles);
        return sets;
    }
    //通过用户名获得权限信息
    private Set<String> getPermissionsByUserName(String username) {
        Set<String> sets = new HashSet<String>();
        sets.add("user:delete");
        sets.add("user:add");
        return sets;
    }

    public static void main(String[] args) {
        Md5Hash md5Hash = new Md5Hash("123456", "Mark");
        System.out.println(md5Hash.toString());
    }
}

自定义拦截器:RolesOrFilter

package com.baidu.shiro.filter;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;

/**
 * @Author: WH
 * @Date: 2019/3/4 10:23
 * @Version 1.0
 */
public class RolesOrFilter extends AuthorizationFilter {


    protected boolean isAccessAllowed(javax.servlet.ServletRequest request, javax.servlet.ServletResponse response, Object mappedValue) throws Exception {
        Subject subject = getSubject(request, response);
        //获得角色
        String[] roles = (String[]) mappedValue;

        if (roles == null || roles.length == 0) {
            return  true;
        }
        for (String role : roles) {
            if (subject.hasRole(role)) {
                return  true;
            }
        }
        return  false;
    }
}

在spirng中加入如下配置


    <bean class="com.baidu.shiro.filter.RolesOrFilter" id="rolesOrFilter" />
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager" />
            <property name="loginUrl" value="login.html" />
            <property name="unauthorizedUrl" value="403.html" />
            <property name="filterChainDefinitions">
                <value>
                    /login.html = anon
                    /subLogin = anon
                    /testRole1 = roles["admin", "admin1"]
                    /testRole2 = rolesOr["admin", "admin1"]
                    /testPerms = perms["user:delete"]
                    /testPerms1 = perms["user:delete","user:update"]
                    /* = authc
                value>
            property>
            <property name="filters">
                <util:map>
                    <entry key="rolesOr" value-ref="rolesOrFilter" />
                util:map>
            property>
   bean>

controller:

package com.baidu.shiro.controller;

import com.baidu.shiro.domain.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;


@Controller
public class UserController {


    @RequestMapping(value = "/subLogin", method = RequestMethod.POST,produces = "application/json;charset=utf-8")
    @ResponseBody
    public String subLogin(User user) {
        System.out.println("aaa");
        Subject subject = SecurityUtils.getSubject();
        System.out.println("haha");
        UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());

        try {
            subject.login(token);
        } catch (AuthenticationException e) {
            return e.getMessage();
        }
        if (subject.hasRole("admin")) {
            return  "有admin权限";
        }

        return "无admin权限";
    }
    //注解判断是否有admin角色,有注解就不用配置/testRole = roles["admin"]
    @RequiresRoles("admin")
    @ResponseBody
    @RequestMapping(value = "/testRole", method = RequestMethod.GET)
    public String testRole() {
        return "testRole success";
    }
	//注解判断是否有admin1角色,有注解就不用配置/testRole1 = roles["admin1"]
    @RequiresPermissions("admin1")
    @ResponseBody
    @RequestMapping(value = "/testRole1", method = RequestMethod.GET)
    public String testRole1() {
        return "testRole success";
    }

    @ResponseBody
    @RequestMapping(value = "/testPerms", method = RequestMethod.GET)
    public String testPerms() {
        return "testPerms success";
    }
    //测试自定义filter
	@ResponseBody
    @RequestMapping(value = "/testRole2", method = RequestMethod.GET)
    public String testRole2() {
        return "testRole2 success";
    }

    @ResponseBody
    @RequestMapping(value = "/testPerms1", method = RequestMethod.GET)
    public String testPerms1() {
        return "testPerms1 success";
    }
}

3.完整demo下载:

点击下载

4.测试:

shiro(入门二)shiro集成spring+mybatis+springMvc+Redis(附带源码)_第4张图片
首先如果没有登入输入index.html 还是回跳转到login.html页面,因为没有登入
登入后跳转:
shiro(入门二)shiro集成spring+mybatis+springMvc+Redis(附带源码)_第5张图片
其他页面也可以自己测试!

你可能感兴趣的:(Shiro)