【原】无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础认证权限
开发环境搭建参见《【原】无脑操作:IDEA + maven + SpringBoot + JPA + Thymeleaf实现CRUD及分页》
需求:
① 除了登录页面,在地址栏直接访问其他URL,均跳转至登录页面
② 登录涉及帐号和密码,帐号错误提示帐号错误,密码错误提示密码错误
③ 登录成功跳转至首页,首页显示登录者帐号信息,并有注销帐号功能,点击注销退出系统
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
分析:
典型的运用认证权限的需求,考虑使用Shiro。了解一下Shiro框架,Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。
关键词汇:
① Subject:安全术语,本意是“当前的操作用户”。
在安全领域,术语“Subject”可以是人,也可以是第三方进程、后台帐户(Daemon Account)、定时作业(Corn Job)或其他类似事物。
它仅仅意味着“当前跟软件交互的东西”。但考虑到大多数目的和用途,你可以把它认为是Shiro的“用户”概念。
在程序中能轻易获得Subject,允许在任何需要的地方进行安全操作。
每个Subject对象都必须与一个SecurityManager进行绑定,访问Subject对象其实都是在与SecurityManager里的特定Subject进行交互。
② SecurityManager:安全管理器。
Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。
③ Realm:域,Shiro从Realm获取安全数据(如用户、角色、权限),
即SecurityManager要验证用户身份,需要从Realm获取相应用户进行比较以确定用户身份是否合法;
也就是说需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,安全数据源。
④ authentication:认证(发音:[ɔ:ˌθentɪ'keɪʃn])
⑤ authorization:授权(发音:[ˌɔ:θərəˈzeɪʃn])
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0、数据库建表init.sql
- DROP TABLE sys_user;
- CREATE TABLE sys_user
- (
- userid INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户编号',
- username VARCHAR(10) NOT NULL COMMENT '用户名称',
- `password` VARCHAR(10) NOT NULL COMMENT '用户密码'
- );
- INSERT INTO sys_user VALUES(NULL, 'admin', ''), (NULL, 'test', '');
- SELECT * FROM sys_user;
1、编写项目对象模型文件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>
- <groupId>cn.temptation</groupId>
- <artifactId>studyShiro</artifactId>
- <version>1.0-SNAPSHOT</version>
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.0.4.RELEASE</version>
- </parent>
- <dependencies>
- <!-- web -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <!-- thymeleaf -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-thymeleaf</artifactId>
- </dependency>
- <!-- spring data jpa -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-jpa</artifactId>
- </dependency>
- <!-- mariadb -->
- <dependency>
- <groupId>org.mariadb.jdbc</groupId>
- <artifactId>mariadb-java-client</artifactId>
- <version>2.2.5</version>
- </dependency>
- <!-- shiro -->
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-spring</artifactId>
- <version>1.4.0</version>
- </dependency>
- <!-- 热启动 -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-devtools</artifactId>
- <optional>true</optional>
- </dependency>
- </dependencies>
- </project>
2、编写项目配置文件application.properties
- # 数据库访问配置
- # 对应MariaDB驱动
- spring.datasource.driverClassName=org.mariadb.jdbc.Driver
- # 数据源配置
- spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test
- spring.datasource.username=root
- spring.datasource.password=sa
- # 配置Springboot默认支持的Hikari数据库连接池
- spring.datasource.type=com.zaxxer.hikari.HikariDataSource
- spring.datasource.hikari.minimum-idle=5
- spring.datasource.hikari.maximum-pool-size=15
- spring.datasource.hikari.auto-commit=true
- spring.datasource.hikari.idle-timeout=30000
- spring.datasource.hikari.pool-name=DatebookHikariCP
- spring.datasource.hikari.max-lifetime=1800000
- spring.datasource.hikari.connection-timeout=30000
- spring.datasource.hikari.connection-test-query=SELECT 1
- # Spring Data JPA配置
- spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
- spring.jpa.properties.hibernate.hbm2ddl.auto=update
- spring.jpa.show-sql=true
- spring.jpa.properties.hibernate.format_sql=true
- # 格式化输出的json字符串
- spring.jackson.serialization.indent_output=true
- # 设置控制台彩色打印
- spring.output.ansi.enabled=ALWAYS
3、编写项目启动类Application.java
- package cn.temptation;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- @SpringBootApplication
- public class Application {
- public static void main(String[] args) {
- // SpringBoot项目启动
- SpringApplication.run(Application.class, args);
- }
- }
4、编写登录页面login.html 和 首页页面index.html
登录页面:login.html
- <!DOCTYPE html>
- <html xmlns:th="http://www.thymeleaf.org">
- <head>
- <meta charset="UTF-8">
- <title>系统登录</title>
- </head>
- <body>
- <div th:text="${msg}" style="color: red"></div>
- <form action="doLogin" method="post">
- 帐号:<input type="text" id="txtUsername" name="username" /><br/>
- 密码:<input type="password" id="txtPassword" name="password" /><br/><br/>
- <input type="submit" value="提交" /> <input type="reset" value="重置" />
- </form>
- </body>
- </html>
首页页面:index.html
- <!DOCTYPE html>
- <html xmlns:th="http://www.thymeleaf.org">
- <head>
- <meta charset="UTF-8">
- <title>系统首页</title>
- </head>
- <body>
- <div th:text="${'欢迎您,' + currentuser}" style="color: red;float: left;"></div>
- <div style="color: red;float: right;"><a href="doLogout">注销</a></div>
- </body>
- </html>
5、编写Shiro框架用配置类ShiroConfig.java 和 自定义Realm类MyRealm.java
配置类ShiroConfig.java
- package cn.temptation.shiro;
- 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;
- /**
- * Shiro配置类
- */
- @Configuration
- public class ShiroConfig {
- // 1、创建ShiroFilterFactoryBean
- @Bean
- public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
- ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
- // 设置安全管理器
- shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
- // 设置登录跳转页面
- shiroFilterFactoryBean.setLoginUrl("/login");
- /**
- * Shiro内置过滤器:实现权限相关的拦截
- * 常用过滤器:
- * anon(认证用):无需认证(登录)即可访问
- * authc(认证用):必须认证才可访问
- * user(少用):使用rememberMe功能可以访问
- * perms(授权用):必须得到资源权限才可访问
- * role(授权用):必须得到角色权限才可访问
- */
- Map<String, String> filterMap = new LinkedHashMap<>();
- // 放行登录请求
- filterMap.put("/doLogin", "anon");
- // 配置退出过滤器,退出代码Shiro已经实现
- filterMap.put("/logout", "logout");
- // 过滤链定义,从上向下顺序执行,一般将/*放在最下边
- filterMap.put("/*", "authc");
- shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
- return shiroFilterFactoryBean;
- }
- // 2、创建DefaultWebSecurityManager
- @Bean(name = "securityManager")
- public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("myRealm") MyRealm myRealm) {
- DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
- // 关联Realm
- defaultWebSecurityManager.setRealm(myRealm);
- return defaultWebSecurityManager;
- }
- // 3、创建Realm
- @Bean(name = "myRealm")
- public MyRealm getRealm() {
- return new MyRealm();
- }
- }
自定义Realm类MyRealm.java
- package cn.temptation.shiro;
- import cn.temptation.dao.UserDao;
- import cn.temptation.domain.User;
- import org.apache.shiro.authc.*;
- import org.apache.shiro.authz.AuthorizationInfo;
- import org.apache.shiro.realm.AuthorizingRealm;
- import org.apache.shiro.subject.PrincipalCollection;
- import org.springframework.beans.factory.annotation.Autowired;
- /**
- * 自定义Realm
- */
- public class MyRealm extends AuthorizingRealm {
- @Autowired
- private UserDao userDao;
- // 授权处理
- @Override
- protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
- return null;
- }
- // 认证处理
- @Override
- protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
- // 编写Shiro判断逻辑,判断账号和密码
- // 1、判断账号
- UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
- User user = userDao.findByUsername(token.getUsername());
- if (user == null) {
- // 账号错误,Shiro底层会抛出UnknownAccountException异常
- return null;
- }
- // 2、判断密码
- return new SimpleAuthenticationInfo("", user.getPassword(), "");
- }
- }
6、编写实体类User.java
- package cn.temptation.domain;
- import javax.persistence.*;
- @Entity
- @Table(name = "sys_user")
- public class User {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- @Column(name = "userid")
- private Integer userid;
- @Column(name = "username")
- private String username;
- @Column(name = "password")
- private String password;
- public Integer getUserid() {
- return userid;
- }
- public void setUserid(Integer userid) {
- this.userid = userid;
- }
- 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;
- }
- }
7、编写控制器类UserController.java
- package cn.temptation.web;
- 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("/login")
- public String login() {
- return "login";
- }
- // 访问首页
- @RequestMapping("/index")
- public String index() {
- return "index";
- }
- // 登录处理
- @RequestMapping("/doLogin")
- public String doLogin(String username, String password, Model model) {
- // 使用Shiro编写认证处理
- // 1、获取Subject
- Subject subject = SecurityUtils.getSubject();
- // 2、封装用户数据
- UsernamePasswordToken token = new UsernamePasswordToken(username, password);
- // 3、执行登录
- try {
- // 登录成功
- subject.login(token);
- // 返回当前用户的帐号
- model.addAttribute("currentuser", token.getUsername());
- return "index";
- } catch (UnknownAccountException exception) {
- // 返回错误信息
- model.addAttribute("msg", "账号错误!");
- return "login";
- } catch (IncorrectCredentialsException exception) {
- // 返回错误信息
- model.addAttribute("msg", "密码错误!");
- return "login";
- }
- }
- // 注销处理
- @RequestMapping("/doLogout")
- public String doLogout() {
- // 1、获取Subject
- Subject subject = SecurityUtils.getSubject();
- // 2、执行注销
- try {
- subject.logout();
- } catch (Exception ex) {
- ex.printStackTrace();
- } finally {
- return "login";
- }
- }
- }
8、编写数据访问接口UserDao.java
- package cn.temptation.dao;
- import cn.temptation.domain.User;
- import org.springframework.data.jpa.repository.JpaRepository;
- import org.springframework.data.jpa.repository.Query;
- import org.springframework.data.repository.query.Param;
- public interface UserDao extends JpaRepository<User, Integer> {
- // 根据账号查询用户
- @Query(value = "SELECT * FROM sys_user WHERE username=:username", nativeQuery = true)
- User findByUsername(@Param("username") String username);
- }
9、项目结构
10、运行效果
【原】无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础认证权限的更多相关文章
- 【原】无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础授权权限
上一篇<[原]无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础认证权限>介绍了实现Shiro的基础认证.本篇谈谈实现 ...
- 【原】无脑操作:EasyUI Tree实现左键只选择叶子节点、右键浮动菜单实现增删改
Easyui中的Tree组件使用频率颇高,经常遇到的需求如下: 1.在树形结构上,只有叶子节点才能被选中,其他节点不能被选中: 2.在叶子节点上右键出现浮动菜单实现新增.删除.修改操作: 3.在非叶子 ...
- 【原】无脑操作:express + MySQL 实现CRUD
基于node.js的web开发框架express简单方便,很多项目中都在使用.这里结合MySQL数据库,实现最简单的CRUD操作. 开发环境: IDE:WebStorm DB:MySQL ------ ...
- 【原】无脑操作:eclipse + maven搭建SSM框架
网上看到一些Spring + Spring MVC + MyBatis框架的搭建教程,不是很详细或是时间久远了,自己动手整一个简单无脑的! 0.系统环境 1)Windows 10 企业版 2)JDK ...
- 【原】无脑操作:ElasticSearch学习笔记(01)
开篇来自于经典的“保安的哲学三问”(你是谁,在哪儿,要干嘛) 问题一.ElasticSearch是什么?有什么用处? 答:截至2018年12月28日,从ElasticSearch官网(https:// ...
- Springboot+JPA+Thymeleaf 校园博客完整小网站
本文所属[知识林]:http://www.zslin.com/web/article/detail/35 此项目是一个比较简易的校园博客.麻雀虽小五脏俱全,虽然是比较简易的但是涉及的知识点还是比较全面 ...
- 【原】无脑操作:IDEA + maven + SpringBoot + JPA + Thymeleaf实现CRUD及分页
一.开发环境: 1.windows 7 企业版 2.IDEA 14 3.JDK 1.8 4.Maven 3.5.2 5.MariaDB 6.SQLYog 二.Maven设置: Maven目录下的con ...
- 【原】无脑操作:IDEA + maven + SpringBoot + JPA + EasyUI实现CRUD及分页
背景:上一篇文章的界面太丑.没有条件查询功能.所以做一些改进,整合EasyUI做实现.(仅以此文纪念表格中出现的这些朋友工作六周年,祭奠一下逝去的青春^_^) 一.开发环境(参照上一篇文章) 补充:E ...
- 【原】无脑操作:eclipse创建maven工程时,如何修改默认JDK版本?
问题描述:eclipse建立maven项目时,JDK版本默认是1.5,想创建时默认版本设置为1.8,如何修改? 解决方案: 找到本机maven仓库存放位置,比如:${user.home}/.m2/路径 ...
随机推荐
- 远程备份binlog服务
Ⅰ.bonlog server介绍 对于binlog的备份,之前文章里说的是有从机,一般不备份,那现在人家就是 要备份嘛,怎么办嘛, 写个脚本每天夜里去把前一天产生的binlog拷贝出来可以不? 行啊 ...
- 【数据结构】B-Tree, B+Tree, B*树介绍
[摘要] 最近在看Mysql的存储引擎中索引的优化,神马是索引,支持啥索引.全是浮云,目前Mysql的MyISAM和InnoDB都支持B-Tree索引,InnoDB还支持B+Tree索引,Memory ...
- java基础之接口(抽象类与接口的区别)
概述 猫狗案例,我们想想狗一般就是看门,猫一般就是作为宠物了,对不.但是,现在有很多的驯养员或者是驯的,这应该属于经过特殊的培训训练出来的,对不.所以,这些额外的动作定义到动物类中就不合适,也不适合直 ...
- 整合 ucenter 注册自动激活
http://my.oschina.net/banbo/blog/311691 应用整合 UCenter,同步注册到 Discuz 的用户,在 Discuz 登录时得手动激活,用户体验很不好,不过解决 ...
- 26.app后端怎么架设推送服务
推送服务已经是app的标配了.架设推送服务,除了可以使用第三方服务商外,也有大量的开源技术可以选择. 现在推送主要分两块,android推送和ios推送,在下面分别论述: 1. Android推 ...
- 跟我学ASP.NET MVC之二:第一个ASP.NET MVC程序
摘要: 本篇文章带你一步一步创建一个简单的ASP.NET MVC程序. 创建新ASP.NET MVC工程 点击“OK”按钮后,打开下面的窗口: 这里选择“Empty”模板以及“MVC”选项.这次不创 ...
- Mac下将文件复制到移动硬盘
在Mac下将移动硬盘格式化成exfat,这样Mac和Windows都可以对移动硬盘进行识别
- 用beego开发服务端应用
用beego开发服务端应用 说明 Quick Start 安装 创建应用 编译运行 打包发布 代码生成 开发文档 目录结构说明 使用配置文件 beego默认参数 路由设置 路由的表述方式 直接设置路由 ...
- bzoj 3343 教主的魔法 分块
修改直接对整块打标记,两边暴力. 查询需要保证每个整块有序,所以在修改时排序就好啦 #include<cstdio> #include<cstring> #include< ...
- BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元
BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元 题意: 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机 ...