欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Shiro Demo:SpringBoot+Shiro+Druid+MyBatis

程序员文章站 2023-09-09 18:46:46
访问start.spring.io生成项目: 然后选择依赖: pom.xml: 数据库: 实体类: Permission: package org.dreamtech.demo.model; public class Permission { private Integer pid; private ......

访问start.spring.io生成项目:

Shiro Demo:SpringBoot+Shiro+Druid+MyBatis

 

然后选择依赖:

Shiro Demo:SpringBoot+Shiro+Druid+MyBatis

 

pom.xml:

<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
    xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelversion>4.0.0</modelversion>
    <parent>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-parent</artifactid>
        <version>1.5.20.release</version>
        <relativepath />
    </parent>
    <groupid>org.dreamtech</groupid>
    <artifactid>demo</artifactid>
    <version>0.0.1-snapshot</version>
    <packaging>war</packaging>
    <name>demo</name>
    <description>demo project for apache shiro</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- 默认配置 -->
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-web</artifactid>
        </dependency>
        <dependency>
            <groupid>org.mybatis.spring.boot</groupid>
            <artifactid>mybatis-spring-boot-starter</artifactid>
            <version>1.3.4</version>
        </dependency>
        <dependency>
            <groupid>mysql</groupid>
            <artifactid>mysql-connector-java</artifactid>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-tomcat</artifactid>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-test</artifactid>
            <scope>test</scope>
        </dependency>
        <!-- shiro -->
        <dependency>
            <groupid>org.apache.shiro</groupid>
            <artifactid>shiro-core</artifactid>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupid>org.apache.shiro</groupid>
            <artifactid>shiro-spring</artifactid>
            <version>1.2.3</version>
        </dependency>
        <!-- druid -->
        <dependency>
            <groupid>com.alibaba</groupid>
            <artifactid>druid</artifactid>
            <version>1.1.14</version>
        </dependency>
        <!-- 配合依赖 -->
        <dependency>
            <groupid>org.apache.commons</groupid>
            <artifactid>commons-lang3</artifactid>
            <version>3.4</version>
        </dependency>
        <dependency>
            <groupid>org.springframework</groupid>
            <artifactid>spring-context-support</artifactid>
            <version>4.2.3.release</version>
        </dependency>
        <!-- jsp -->
        <dependency>
            <groupid>org.apache.tomcat.embed</groupid>
            <artifactid>tomcat-embed-jasper</artifactid>
        </dependency>
        <dependency>
            <groupid>javax.servlet</groupid>
            <artifactid>javax.servlet-api</artifactid>
        </dependency>
        <dependency>
            <groupid>javax.servlet</groupid>
            <artifactid>jstl</artifactid>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupid>org.springframework.boot</groupid>
                <artifactid>spring-boot-maven-plugin</artifactid>
            </plugin>
        </plugins>
    </build>

</project>

 

数据库:

/*
 * 使用数据库shiro_demo
 */
use shiro_demo;
/*
 * 权限表
 */
create table permission(
   pid int(11) not null auto_increment,
   name varchar(255) not null default '',
   url varchar(255) default '',
   primary key (pid)
) engine=innodb default charset=utf8;
insert into permission values ('1','add','');
insert into permission values ('2','delete','');
insert into permission values ('3','edit','');
insert into permission values ('4','query','');
/*
 * 用户表
 */
create table user(
   uid int(11) not null auto_increment,
   username varchar(255) not null default '',
   password varchar(255) not null default '',
   primary key (uid)
) engine=innodb default charset=utf8;
insert into user values ('1','admin','admin');
insert into user values ('2','xuyiqing','xuyiqing');
/*
 * 角色表
 */
create table role(
   rid int(11) not null auto_increment,
   rname varchar(255) not null default '',
   primary key (rid)
) engine=innodb default charset=utf8;
insert into role values ('1','admin');
insert into role values ('2','customer');
/*
 * 权限角色关系表
 */
create table permission_role(
   rid int(11) not null,
   pid int(11) not null,
   key idx_rid (rid),
   key idx_pid (pid)
) engine=innodb default charset=utf8;
insert into permission_role values ('1','1');
insert into permission_role values ('1','2');
insert into permission_role values ('1','3');
insert into permission_role values ('1','4');
insert into permission_role values ('2','1');
insert into permission_role values ('2','4');
/*
 * 用户角色关系表
 */
create table user_role(
   uid int(11) not null,
   rid int(11) not null,
   key idx_uid (uid),
   key idx_pid (rid)
) engine=innodb default charset=utf8;
insert into user_role values ('1','1');
insert into user_role values ('2','2');

 

实体类:

permission:

package org.dreamtech.demo.model;

public class permission {
    private integer pid;
    private string name;
    private string url;

    public integer getpid() {
        return pid;
    }

    public void setpid(integer pid) {
        this.pid = pid;
    }

    public string getname() {
        return name;
    }

    public void setname(string name) {
        this.name = name;
    }

    public string geturl() {
        return url;
    }

    public void seturl(string url) {
        this.url = url;
    }
}

role:

package org.dreamtech.demo.model;

import java.util.hashset;
import java.util.set;

public class role {
    private integer rid;
    private string rname;
    private set<permission> permissions = new hashset<permission>();
    private set<user> users = new hashset<user>();

    public integer getrid() {
        return rid;
    }

    public void setrid(integer rid) {
        this.rid = rid;
    }

    public string getname() {
        return rname;
    }

    public void setname(string rname) {
        this.rname = rname;
    }

    public set<permission> getpermissions() {
        return permissions;
    }

    public void setpermissions(set<permission> permissions) {
        this.permissions = permissions;
    }

    public set<user> getusers() {
        return users;
    }

    public void setusers(set<user> users) {
        this.users = users;
    }
}

user:

package org.dreamtech.demo.model;

import java.util.hashset;
import java.util.set;

public class user {
    private integer uid;
    private string username;
    private string password;
    private set<role> roles = new hashset<role>();

    public integer getuid() {
        return uid;
    }

    public void setuid(integer uid) {
        this.uid = uid;
    }

    public string getusername() {
        return username;
    }

    public void setusername(string username) {
        this.username = username;
    }

    public string getpassword() {
        return password;
    }

    public void setpassword(string password) {
        this.password = password;
    }

    public set<role> getroles() {
        return roles;
    }

    public void setroles(set<role> roles) {
        this.roles = roles;
    }
}

 

application.properties:

# tomcat 
server.tomcat.uri-encoding=utf-8
# server
server.port=80
# database
spring.datasource.type=com.alibaba.druid.pool.druiddatasource
spring.datasource.drive-class-name=com.mysql.jdbc.driver
spring.datasource.url=jdbc:mysql://localhost:3306/shiro_demo?characterencoding=utf-8
spring.datasource.username=root
spring.datasource.password=xuyiqing
# mybatis
mybatis.mapper-locations=mappers/*.xml
mybatis.type-aliases-package=org.dreamtech.demo.model
# jsp
spring.mvc.view.prefix=/pages/
spring.mvc.view.suffix=.jsp

 

mapper:

package org.dreamtech.demo.mapper;

import org.apache.ibatis.annotations.param;
import org.dreamtech.demo.model.user;

public interface usermapper {
    user findbyusername(@param("username") string username);
}
<?xml version="1.0" encoding="utf-8"?>
<!doctype mapper
    public "-//mybatis.org//dtd mapper 3.0//en"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dreamtech.demo.mapper.usermapper">
    <resultmap type="org.dreamtech.demo.model.user" id="usermap">
        <id property="uid" column="uid" />
        <result property="username" column="username" />
        <result property="password" column="password" />
        <collection property="roles"
            oftype="org.dreamtech.demo.model.role">
            <id property="rid" column="rid" />
            <result property="rname" column="rname" />
            <collection property="permissions"
                oftype="org.dreamtech.demo.model.permission">
                <id property="pid" column="pid" />
                <result property="name" column="name" />
                <result property="url" column="url" />
            </collection>
        </collection>
    </resultmap>
    <select id="findbyusername" parametertype="string"
        resultmap="usermap">
        select
        u.*,r.*,p.*
        from
        user u
        inner join
        user_role ur
        on
        ur.uid=u.uid
        inner join
        role r
        on
        r.rid=ur.rid
        inner join
        permission_role pr
        on
        pr.rid=r.rid
        inner join
        permission p
        on
        p.pid=pr.pid
        where
        u.username=#{username}
    </select>
</mapper>

 

service:

package org.dreamtech.demo.service;

import org.dreamtech.demo.model.user;

public interface userservice {
    user findbyusername(string username);
}
package org.dreamtech.demo.service.impl;

import org.dreamtech.demo.mapper.usermapper;
import org.dreamtech.demo.model.user;
import org.dreamtech.demo.service.userservice;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.stereotype.service;

@service
public class userserviceimpl implements userservice {

    @autowired
    private usermapper usermapper;
    
    @override
    public user findbyusername(string username) {
        return usermapper.findbyusername(username);
    }

}

 

controller:

package org.dreamtech.demo.controller;

import javax.servlet.http.httpsession;

import org.apache.shiro.securityutils;
import org.apache.shiro.authc.usernamepasswordtoken;
import org.apache.shiro.subject.subject;
import org.dreamtech.demo.model.user;
import org.springframework.stereotype.controller;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.requestparam;
import org.springframework.web.bind.annotation.responsebody;

@controller
public class testcontroller {

    @requestmapping("/login")
    public string login() {
        return "login";
    }

    @requestmapping("/index")
    public string index() {
        return "index";
    }

    @requestmapping("/admin")
    @responsebody
    public string admin() {
        return "admin success";
    }
    @requestmapping("/edit")
    @responsebody
    public string edit() {
        return "edit success";
    }

    @requestmapping("/unauthorized")
    @responsebody
    public string unauthorized() {
        return "没有权限访问";
    }

    @requestmapping("/logout")
    public string logout() {
        subject subject = securityutils.getsubject();
        if (subject != null) {
            subject.logout();
        }
        return "login";
    }

    @requestmapping("/loginuser")
    public string loginuser(@requestparam("username") string username, @requestparam("password") string password,
            httpsession session) {
        usernamepasswordtoken token = new usernamepasswordtoken(username, password);
        subject subject = securityutils.getsubject();
        try {
            subject.login(token);
            user user = (user) subject.getprincipal();
            session.setattribute("user", user);
            return "index";
        } catch (exception e) {
            system.out.println("用户名或密码错误");
            return "login";
        }
    }

}

 

shiro配置:

package org.dreamtech.demo;

import java.util.linkedhashmap;

import org.apache.shiro.cache.memoryconstrainedcachemanager;
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.beans.factory.annotation.qualifier;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;

/**
 * shiro配置
 * 
 * @author xu yiqing
 *
 */
@configuration
public class shiroconfiguration {

    @bean("credentialmatcher")
    public credentialmatcher credentialmatcher() {
        return new credentialmatcher();
    }

    @bean("authrealm")
    public authrealm authrealm(@qualifier("credentialmatcher") credentialmatcher matcher) {
        authrealm authrealm = new authrealm();
        authrealm.setcredentialsmatcher(matcher);
        // 设置缓存在内存中
        authrealm.setcachemanager(new memoryconstrainedcachemanager());
        return authrealm;
    }

    @bean("securitymanager")
    public securitymanager securitymanager(@qualifier("authrealm") authrealm realm) {
        defaultwebsecuritymanager manager = new defaultwebsecuritymanager();
        manager.setrealm(realm);
        return manager;
    }

    @bean("shirofilter")
    public shirofilterfactorybean shirofilter(@qualifier("securitymanager") securitymanager manager) {
        shirofilterfactorybean bean = new shirofilterfactorybean();
        bean.setsecuritymanager(manager);

        // 登陆路径/login
        bean.setloginurl("/login");
        // 登陆成功路径/index
        bean.setsuccessurl("/index");
        // 权限不足或认证失败路径/unauthorized
        bean.setunauthorizedurl("/unauthorized");

        linkedhashmap<string, string> filterchaindefinitionmap = new linkedhashmap<string, string>();
        // 需要经过身份认证才可以访问/index
        filterchaindefinitionmap.put("/index", "authc");
        // 可以匿名使用
        filterchaindefinitionmap.put("/login", "anon");
        filterchaindefinitionmap.put("/loginuser", "anon");
        filterchaindefinitionmap.put("/druid/**", "anon");
        // 登陆后的所有角色都可以访问/**
        filterchaindefinitionmap.put("/**", "user");
        // 只有admin角色才可以访问/admin
        filterchaindefinitionmap.put("/admin", "roles[admin]");
        // 只有拿到edit权限的用户才可以访问/edit
        filterchaindefinitionmap.put("/edit", "perms[edit]");

        bean.setfilterchaindefinitionmap(filterchaindefinitionmap);
        return bean;
    }

    @bean("authorizationattributesourceadvisor")
    public authorizationattributesourceadvisor authorizationattributesourceadvisor(
            @qualifier("securitymanager") securitymanager securitymanager) {
        authorizationattributesourceadvisor advisor = new authorizationattributesourceadvisor();
        advisor.setsecuritymanager(securitymanager);
        return advisor;
    }

    /**
     * 实现spring的自动代理
     * 
     * @return
     */
    @bean("defaultadvisorautoproxycreator")
    public defaultadvisorautoproxycreator defaultadvisorautoproxycreator() {
        defaultadvisorautoproxycreator creator = new defaultadvisorautoproxycreator();
        creator.setproxytargetclass(true);
        return creator;
    }
}
package org.dreamtech.demo;

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;

public class credentialmatcher extends simplecredentialsmatcher {
    /**
     * 密码校验规则重写
     */
    @override
    public boolean docredentialsmatch(authenticationtoken token, authenticationinfo info) {
        usernamepasswordtoken usernamepasswordtoken = (usernamepasswordtoken) token;
        string password=new string(usernamepasswordtoken.getpassword());
        string dbpassword=(string) info.getcredentials();
        return this.equals(password,dbpassword);
    }
}
package org.dreamtech.demo;

import java.util.arraylist;
import java.util.list;
import java.util.set;

import org.apache.commons.collections.collectionutils;
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.authz.authorizationinfo;
import org.apache.shiro.authz.simpleauthorizationinfo;
import org.apache.shiro.realm.authorizingrealm;
import org.apache.shiro.subject.principalcollection;
import org.dreamtech.demo.model.permission;
import org.dreamtech.demo.model.role;
import org.dreamtech.demo.model.user;
import org.dreamtech.demo.service.userservice;
import org.springframework.beans.factory.annotation.autowired;

public class authrealm extends authorizingrealm {

    @autowired
    private userservice userservice;

    /**
     * 认证
     */
    @override
    protected authorizationinfo dogetauthorizationinfo(principalcollection principals) {
        user user = (user) principals.fromrealm(this.getclass().getname()).iterator().next();
        list<string> permissionlist = new arraylist<string>();
        list<string> rolenamelist= new arraylist<string>();
        set<role> roleset = user.getroles();
        if (collectionutils.isnotempty(roleset)) {
            for (role role : roleset) {
                rolenamelist.add(role.getname());
                set<permission> permissionset = role.getpermissions();
                if (collectionutils.isnotempty(permissionset)) {
                    for (permission permission : permissionset) {
                        permissionlist.add(permission.getname());
                    }
                }
            }
        }
        simpleauthorizationinfo info = new simpleauthorizationinfo();
        info.addstringpermissions(permissionlist);
        info.addroles(rolenamelist);
        return info;
    }

    /**
     * 授权登陆
     */
    @override
    protected authenticationinfo dogetauthenticationinfo(authenticationtoken token) throws authenticationexception {
        usernamepasswordtoken usernamepasswordtoken = (usernamepasswordtoken) token;
        string username = usernamepasswordtoken.getusername();
        user user = userservice.findbyusername(username);
        return new simpleauthenticationinfo(user, user.getpassword(), this.getclass().getname());
    }
}

 

druid配置:

package org.dreamtech.demo;

import javax.sql.datasource;

import org.mybatis.spring.sqlsessionfactorybean;
import org.springframework.beans.factory.annotation.qualifier;
import org.springframework.boot.autoconfigure.jdbc.datasourcebuilder;
import org.springframework.boot.context.properties.configurationproperties;
import org.springframework.boot.web.servlet.filterregistrationbean;
import org.springframework.boot.web.servlet.servletregistrationbean;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.context.annotation.primary;
import org.springframework.core.io.support.pathmatchingresourcepatternresolver;
import org.springframework.dao.annotation.persistenceexceptiontranslationpostprocessor;

import com.alibaba.druid.support.http.statviewservlet;
import com.alibaba.druid.support.http.webstatfilter;

/**
 * druid连接池的配置
 * 
 * @author xu yiqing
 *
 */
@configuration
public class druidconfiguration {
    /**
     * 给druid注册servlet
     * 
     * @return
     */
    @bean
    public servletregistrationbean statviewservlet() {
        servletregistrationbean servletregistrationbean = new servletregistrationbean(new statviewservlet(),
                "/druid/*");
        // 白名单
        servletregistrationbean.addinitparameter("allow", "127.0.0.1");
        // ip黑名单
        servletregistrationbean.addinitparameter("deny", "192.168.1.100");
        // 登录查看信息的账号密码.
        servletregistrationbean.addinitparameter("loginusername", "druid");
        servletregistrationbean.addinitparameter("loginpassword", "xuyiqing");
        // 是否能够重置数据.
        servletregistrationbean.addinitparameter("resetenable", "false");
        return servletregistrationbean;
    }

    /**
     * 给druid注册filter
     * 
     * @return
     */
    @bean
    public filterregistrationbean statfilter() {
        filterregistrationbean filterregistrationbean = new filterregistrationbean(new webstatfilter());
        // 添加过滤规则
        filterregistrationbean.addurlpatterns("/*");
        // 添加不需要忽略的格式信息
        filterregistrationbean.addinitparameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterregistrationbean;
    }

    /**
     * 配置持久性异常转换后处理器(翻译过来的)
     * 
     * @return
     */
    @bean
    public persistenceexceptiontranslationpostprocessor persistenceexceptiontranslationpostprocessor() {
        return new persistenceexceptiontranslationpostprocessor();
    }

    /**
     * 配置数据库的基本连接信息
     * 
     * @return
     */
    @bean(name = "datasource")
    @primary
    @configurationproperties(prefix = "spring.datasource")
    public datasource datasource() {
        return datasourcebuilder.create().type(com.alibaba.druid.pool.druiddatasource.class).build();
    }

    /**
     * 配置sqlsessionfactorybean
     * 
     * @param datasource
     * @return
     * @throws exception
     */
    @bean
    public sqlsessionfactorybean sqlsessionfactory(@qualifier("datasource") datasource datasource) throws exception {
        sqlsessionfactorybean bean = new sqlsessionfactorybean();
        bean.setdatasource(datasource);
        pathmatchingresourcepatternresolver resolver = new pathmatchingresourcepatternresolver();
        bean.setmapperlocations(resolver.getresources("classpath:/mappers/*.xml"));
        return bean;
    }
}

 

页面:webapp/pages/*

首页

<%@ page language="java" contenttype="text/html; charset=utf-8"%>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>home</title>
</head>
<body>
    <h1>欢迎登陆:${user.username}</h1>
</body>
</html>

登陆

<%@ page language="java" contenttype="text/html; charset=utf-8"%>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>login</title>
</head>
<body>
    <h1>欢迎登陆</h1>
    <form action="/loginuser" method="post">
        <input type="text" name="username"><br /> <input
            type="password" name="password"><br /> <input type="submit"
            value="登陆">
    </form>
</body>
</html>