网站会员和discuz会员同步,淘宝店铺网站策划,重庆企业公司网站建设,规划网站总结文章目录需求安排一、前期准备1. maven依赖2. 创建数据库初始化表数据3. 实体类4. mapper接口5. mapper接口映射文件6. service接口7. service实现类8. 首页控制器9. 用户控制器10. 全局配置文件11. 启动类加注解二、页面准备2.1. 首页页面2.2. 登录页面2.3. 未授权页面2.4. 用…
文章目录需求安排一、前期准备1. maven依赖2. 创建数据库初始化表数据3. 实体类4. mapper接口5. mapper接口映射文件6. service接口7. service实现类8. 首页控制器9. 用户控制器10. 全局配置文件11. 启动类加注解二、页面准备2.1. 首页页面2.2. 登录页面2.3. 未授权页面2.4. 用户添加页面2.5. 用户更新页面三、Shiro 配置3.1. 自定义UserRealm3.2. ShiroConfig四、需求测试五、源码链接需求安排
需求分析
1. 匿名允许访问页面首页和登录页面
2. 默认登录页面
3. admin用户只有用户添加权限
4. test用户只有用户更新权限
5. 访问授权页面默认跳转登录页面
6. 登录认证通过访问无权限页面默认跳转未授权页面
7. 登录认证通过进行资源授权角色授权后,访问各自有权限的页面
注第6条企业内部采用无权限的页面采用shiro和页面整合策略直接不会显示一、前期准备
1. maven依赖 propertiesproject.build.sourceEncodingUTF-8/project.build.sourceEncodingproject.reporting.outputEncodingUTF-8/project.reporting.outputEncodingjava.version1.8/java.versiondruid.version1.0.28/druid.versionmybatis-spring-boot.version2.1.2/mybatis-spring-boot.versionshiro-spring.version1.5.2/shiro-spring.versionthymeleaf-extras-shiro.version2.0.0/thymeleaf-extras-shiro.version/propertiesdependencies!--lombok--dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependency!--thymeleaf模板引擎--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-thymeleaf/artifactId/dependency!--springMvc启动器--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!-- shiro与spring整合依赖 --dependencygroupIdorg.apache.shiro/groupIdartifactIdshiro-spring/artifactIdversion${shiro-spring.version}/version/dependency!--mybatis启动器--dependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion${mybatis-spring-boot.version}/version/dependency!--MYSQL--dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdscoperuntime/scope/dependency!-- 集成druid数据源 --dependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion${druid.version}/version/dependency!-- thymel对shiro的扩展坐标 --dependencygroupIdcom.github.theborakompanioni/groupIdartifactIdthymeleaf-extras-shiro/artifactIdversion${thymeleaf-extras-shiro.version}/version/dependency/dependencies2. 创建数据库初始化表数据
数据库名shiro 表名user
DROP TABLE IF EXISTS user;
CREATE TABLE user (id int(11) NOT NULL AUTO_INCREMENT COMMENT 用户id,name varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 用户名,password varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 密码,perms varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 授权字段,PRIMARY KEY (id) USING BTREE
) ENGINE InnoDB AUTO_INCREMENT 4 CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT Dynamic;-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO user VALUES (1, admin, admin, user:add);
INSERT INTO user VALUES (2, test, test, user:update);3. 实体类
package com.gblfy.entity;import lombok.Data;
import java.io.Serializable;Data
public class User implements Serializable {private Integer id;private String name;private String password;private String perms;
}4. mapper接口
package com.gblfy.mapper;import com.gblfy.entity.User;public interface UserMapper {/*** 通过id查询用户信息** param id* return*/User selectByPrimaryKey(Integer id);/*** 根据用户名查询用户信息** param name* return*/User selectByName(String name);}
5. mapper接口映射文件
在resources目录下面创建mapping文件夹
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.gblfy.mapper.UserMapperresultMap idBaseResultMap typecom.gblfy.entity.Userid columnid propertyid jdbcTypeINTEGER/result columnname propertyname jdbcTypeVARCHAR/result columnpassword propertypassword jdbcTypeVARCHAR/result columnperms propertyperms jdbcTypeVARCHAR//resultMapsql idBase_Column_Listid, name, password, perms/sqlselect idselectByPrimaryKey resultMapBaseResultMap parameterTypejava.lang.Integerselectinclude refidBase_Column_List/from userwhere id #{id,jdbcTypeINTEGER}/selectselect idselectByName resultMapBaseResultMap parameterTypejava.lang.Stringselectinclude refidBase_Column_List/from userwhere name #{name,jdbcTypeVARCHAR}/select
/mapper6. service接口
package com.gblfy.service;import com.gblfy.entity.User;public interface UserService {/*** 根据用户名查询用户信息** param name* return*/User selectByName(String name);/*** 通过id查询用户信息** param id* return*/User selectByPrimaryKey(Integer id);
}
7. service实现类
package com.gblfy.service.impl;import com.gblfy.entity.User;
import com.gblfy.mapper.UserMapper;
import com.gblfy.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;Service
public class UserServiceImpl implements UserService {Autowiredprivate UserMapper userMapper;/*** 根据用户名查询用户信息** param name* return*/Overridepublic User selectByName(String name) {return userMapper.selectByName(name);}/*** 通过id查询用户信息** param id* return*/Overridepublic User selectByPrimaryKey(Integer id) {return userMapper.selectByPrimaryKey(id);}}
8. 首页控制器
package com.gblfy.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;Controller
public class IndexController {RequestMapping(index)public String index() {return index;}
}
9. 用户控制器
package com.gblfy.controller;import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;Controller
public class UserController {//跳转登录页面RequestMapping(/toLogin)public String toLogin() {return login;}//用户添加RequestMapping(/add)public String add() {return /user/add;}//用户更新RequestMapping(/update)public String update() {return /user/update;}//未授权跳转页面RequestMapping(noAuth)public String noAuth() {return noAuth;}//登录处理RequestMapping(login)public String login(String username, String password, Model model) {/*** 编写shiro认证操作* 1.获取subject* 2.封装用户数据* 3.执行登录方法*///1.获取subjectSubject subject SecurityUtils.getSubject();//2.封装用户数据 认证时会用到UsernamePasswordToken token new UsernamePasswordToken(username, password);//3.执行登录方法try {subject.login(token);//登陆成功} catch (UnknownAccountException e) {e.printStackTrace();//登陆失败 场景1model.addAttribute(msg, 用户名不存在);return login;} catch (IncorrectCredentialsException e) {e.printStackTrace();//登陆失败 场景2model.addAttribute(msg, 密码错误);return login;}//登陆成功model.addAttribute(msg, username 登陆成功跳转首页);return index;}
}
10. 全局配置文件
#server 端口
server:port: 80tomcat:min-spare-threads: 30max-threads: 1000#Mysql配置
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/shiro?useSSLtrueserverTimezoneGMTallowMultiQueriestrueuseUnicodetruecharacterEncodingUTF-8username: rootpassword: roottype: com.alibaba.druid.pool.DruidDataSource# Mybatis Mapper映射文件实体类配置
mybatis:type-aliases-package: com.gblfy.entitymapperLocations:- classpath*:/mapping/*.xml
11. 启动类加注解
package com.gblfy;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;SpringBootApplication
MapperScan(com.gblfy.mapper)
public class SpringbootShiroApplication {public static void main(String[] args) {SpringApplication.run(SpringbootShiroApplication.class, args);}}
二、页面准备
2.1. 首页页面
!DOCTYPE html
html langen xmlns:thhttp://www.thymeleaf.orgxmlns:shirohttp://www.pollix.at/thymeleaf/shiroheadmeta charsetUTF-8title系统首页/title
/head
body
h3 th:text${msg} stylecolor: red/h3
div进入用户添加页面:ensp;ensp;ensp;a href/add用户添加/a
/div
br/
div进入用户更新页面:ensp;ensp;ensp;a href/update用户更新/a
/div
/body
/html
2.2. 登录页面
!DOCTYPE html
html langzh xmlns:thhttp://www.thymeleaf.orgheadmeta charsetUTF-8title登录页面/title
/head
body
h3 th:text${msg} stylecolor: red登录/h3
form methodpost action/login用户名:input typetext nameusername/br/密ensp;码input typepassword namepassword/br/input typesubmit value登录/
/form
/body
/html
2.3. 未授权页面
!DOCTYPE html
html langzh xmlns:thhttp://www.thymeleaf.orgheadmeta charsetUTF-8title未授权页面/title
/head
body
未授权页面请联系管理员进行授权操作
/body
/html
2.4. 用户添加页面
!DOCTYPE html
html langzh xmlns:thhttp://www.thymeleaf.orgheadmeta charsetUTF-8title添加页面/title
/head
body
h3添加页面/h3
/body
/html
2.5. 用户更新页面
!DOCTYPE html
html langzh xmlns:thhttp://www.thymeleaf.orgheadmeta charsetUTF-8title更新页面/title
/head
body
h3更新页面/h3
/body
/html
三、Shiro 配置
3.1. 自定义UserRealm
package com.gblfy.realm;import com.gblfy.entity.User;
import com.gblfy.service.UserService;
import org.apache.shiro.SecurityUtils;
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.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;/*** 自定义 UserRealm* 固定写法extends AuthorizingRealm*/
public class UserRealm extends AuthorizingRealm {Autowiredprivate UserService userService;/*** 认证** param token* return* throws AuthenticationException*/Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//1.得到用户名和密码 因为登录已存因此能取UsernamePasswordToken usernamePasswordToken (UsernamePasswordToken) token;String username usernamePasswordToken.getUsername();//默认获取password的类型为char[]转换处理String password new String(usernamePasswordToken.getPassword());//2.从数据库根据用户名查询用户信息User user userService.selectByName(username);//判断查询出的用户对象(sysUser)是否为空if (user null) {throw new UnknownAccountException(用户不存在);}//判断查询出的用户对象的用户密码和页面从页面传递过来的密码进行比较是否相同if (!user.getPassword().equals(password)) {throw new IncorrectCredentialsException(密码有误);}//认证通过 登陆成功SimpleAuthenticationInfo info new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());return info;}/*** 授权** param principalCollection* return*/Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {SimpleAuthorizationInfo info new SimpleAuthorizationInfo();//通过id用户信息Subject subject SecurityUtils.getSubject();//认证时存的是user因此可以强转成user对象User user (User) subject.getPrincipal();User userPerms userService.selectByPrimaryKey(user.getId());//从user对象动态获取权限放到认证容器info.addStringPermission(userPerms.getPerms());return info;}}
3.2. ShiroConfig
package com.gblfy.config;import com.gblfy.realm.UserRealm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.LinkedHashMap;
import java.util.Map;Configuration
public class ShiroConfig {/*** 1.创建Realm*/Bean(name userRealm)public UserRealm getRealm() {return new UserRealm();}/*** 2.创建DefaultWebSecurityManager*/Bean(name securityManager)public DefaultWebSecurityManager getDefaultWebSecurityManager(Qualifier(userRealm) UserRealm userRealm) {DefaultWebSecurityManager securityManager new DefaultWebSecurityManager();//关联realmsecurityManager.setRealm(userRealm);return securityManager;}/*** 3.创建ShiroFilterFactoryBean*/Beanpublic ShiroFilterFactoryBean getShiroFilterFactoryBean(Qualifier(securityManager) DefaultWebSecurityManager securityManager) {ShiroFilterFactoryBean shiroFilterFactoryBean new ShiroFilterFactoryBean();//设置安全管理器shiroFilterFactoryBean.setSecurityManager(securityManager);//指定登录页面shiroFilterFactoryBean.setLoginUrl(/toLogin);//指定未授权页面shiroFilterFactoryBean.setUnauthorizedUrl(/noAuth);//添加Shiro内置过滤器/*** Shiro内置过滤器可以实现权限相关的拦截器* 常用的过滤器* anon: 无需认证登录可以访问* authc: 必须认证才可以访问* user: 如果使用rememberMe的功能可以直接访问* perms 该资源必须得到资源权限才可以访问* role: 该资源必须得到角色权限才可以访问*/MapString, String filterMap new LinkedHashMapString, String();//设置允许匿名访问filterMap.put(/index, anon);filterMap.put(/login, anon);//配置授权过滤器 第一种filterMap.put(/add, perms[user:add]);filterMap.put(/update, perms[user:update]);//授权才可以访问filterMap.put(/*, authc);shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);return shiroFilterFactoryBean;}}
四、需求测试
测试计划;
1. 访问http://localhost/index和http://localhost/login 是否可以匿名访问
2. 访问http://localhost/index页面点击进入添加页面是否跳转登录页面
3. 访问http://localhost/index页面点击进入更新页面是否跳转登录页面
4. 访问几个不存在的url测试是否默认统一跳转登录页面。例如: http://localhost/xxx
5. 使用admin账户访问登录页面做一下测试1输入不存在的账户点击登录不输密码测试是否提示用户名不存在2输入存在的账户admin不输密码点击登录测试是否提示密码错误3输入存在的正确的账户admin输入正确的密码点击登录测试点击用户添加是否可以进入用户添加页面4输入存在的正确的账户admin输入正确的密码点击登录测试点击用户更新是否跳转未授权页面
6. 使用test账户访问登录页面做一下测试1输入不存在的账户点击登录不输密码测试是否提示用户名不存在2输入存在的账户test不输密码点击登录测试是否提示密码错误3输入存在的正确的账户test输入正确的密码点击登录测试点击用户更新是否可以进入用户更新页面4输入存在的正确的账户test输入正确的密码点击登录测试点击用户添加是否跳转未授权页面到此除了成功登录后角色授权就都演示完了
五、源码链接