springboot集成shiro实现身份认证
github地址:https://github.com/peterowang/shiro
pom文件
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- mysql驱动; -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.22</version>
</dependency> <!--shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.2</version>
</dependency> <!-- Spirng data JPA依赖; -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
1.集成spring data jpa
2.使用thymeleaf 见application.properties
spring.application.name=spring-boot-shiro
server.port=8080 spring.thymeleaf.mode=LEGACYHTML5 这里的设置主要是因为thymeleaf校验html文件的时候会特别严格,比如<input> 必须加上/结尾,这里需要依赖nekohtml.
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/ 这里相当于springmvc里的视图解析器
spring.thymeleaf.suffix=.html ########################################################
###datasource
########################################################
spring.datasource.url = jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.max-active=20
spring.datasource.min-active=10
spring.datasource.max-idle=8
spring.datasource.initial-size=10 ########################################################
### Java Persistence Api
########################################################
# Specify the DBMS
spring.jpa.database = MYSQL
# Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
#[org.hibernate.cfg.ImprovedNamingStrategy | org.hibernate.cfg.DefaultNamingStrategy]
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.DefaultNamingStrategy
# stripped before adding them to the entity manager)
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
目录结构 :

3.配置realm
在
config包下再建一个包Shiro,然后在Shiro包下建一个MyShiroRealm类,继承AuthorizingRealm抽象类。package com.example.demo.config.shiro; import com.example.demo.model.UserInfo;
import com.example.demo.service.UserInfoService;
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.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; /**
* Created by BFD-593 on 2017/8/8.
*/
public class MyShiroRealm extends AuthorizingRealm{
private static final Logger logger = LoggerFactory.getLogger(MyShiroRealm.class);
@Autowired
private UserInfoService userInfoService; @Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
logger.info("开始身份验证");
String username = (String) token.getPrincipal();
UserInfo userInfo = userInfoService.findByUsername(username);
if(userInfo==null) {
return null;
}
SimpleAuthenticationInfo auth = new SimpleAuthenticationInfo(
userInfo,
userInfo.getPassword(), //密码
getName() //realm name
);
return auth;
} @Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
}
4.配置自定义密码比较器(shiro会根据这个来将用户输入的密码加密成注册时的密码,与db里的密码比较)
package com.example.demo.config.shiro; 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;
import org.apache.shiro.crypto.hash.Md5Hash; /**
* Created by BFD-593 on 2017/8/8.
*/
public class CredentialsMatcher extends SimpleCredentialsMatcher { @Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
UsernamePasswordToken utoken=(UsernamePasswordToken) token;
//获得用户输入的密码:(可以采用加盐(salt)的方式去检验)
String password = String.valueOf(utoken.getPassword());
String username = String.valueOf(utoken.getUsername());
Md5Hash md5 = new Md5Hash(password,username, 2);
String inPassword = md5.toString();
//获得数据库中的密码
String dbPassword=(String) info.getCredentials();
//进行密码的比对
return this.equals(inPassword, dbPassword);
} }
5.shiroConfig配置类
package com.example.demo.config.shiro; import org.apache.shiro.mgt.SecurityManager;
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; /**
* Created by BFD-593 on 2017/8/8.
*/
@Configuration
public class ShiroConfiguration {
@Bean(name="shiroFilter")
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") SecurityManager manager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(manager); Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/favicon.ico", "anon");
filterChainDefinitionMap.put("/**", "authc");
//authc表示需要验证身份才能访问,还有一些比如anon表示不需要验证身份就能访问等。
//关于为什么设置filterChainDefinitionMap.put("/favicon.ico", "anon");,请参考Shiro登录后下载favicon.ico问题 shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setSuccessUrl("/index");
// shiroFilterFactoryBean.setUnauthorizedUrl("/403"); //这里设置403并不会起作用,参考http://www.jianshu.com/p/e03f5b54838c shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
} /**
* 不指定名字的话,自动创建一个方法名第一个字母小写的bean
* @Bean(name = "securityManager")
* @return
*/
@Bean(name="securityManager")
public SecurityManager securityManager(@Qualifier("authRealm") MyShiroRealm authRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(authRealm);
return securityManager;
} /**
* Shiro Realm 继承自AuthorizingRealm的自定义Realm,即指定Shiro验证用户登录的类为自定义的
*
* @param
* @return
*/
@Bean(name="authRealm")
public MyShiroRealm userRealm(@Qualifier("credentialsMatcher") CredentialsMatcher matcher) {
MyShiroRealm userRealm = new MyShiroRealm();
//告诉realm,使用credentialsMatcher加密算法类来验证密文
userRealm.setCredentialsMatcher(matcher);
return userRealm;
} /**
* 密码比较器
* @return
*/
@Bean(name="credentialsMatcher")
public CredentialsMatcher credentialsMatcher() {
return new CredentialsMatcher();
}
} 6.web层
package com.example.demo.web; import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest;
import java.util.Map; /**
* Created by BFD-593 on 2017/8/8.
*/
@Controller
public class HomeController {
@RequestMapping({"/","/index"})
public String index() {
return "index";
} /**
* logout由shiro实现,我们只需提供入口即可
* filterChainDefinitionMap.put("/logout", "logout");
* @return
*/
@RequestMapping({"/logout"})
public String logout(){
return "login";
} /**
* 因为设置了setLoginUrl("/login");登录url如果没有登录,
* 所有的请求都发送到这里。shiro会自动调用securityManager
* 此方法不处理登录成功,由shiro进行处理。
* @param request
* @param map
* @return
* @throws Exception
*/
@RequestMapping("/login")
public String login(HttpServletRequest request, Map<String, Object> map) throws Exception {
// 登录失败从request中获取shiro处理的异常信息。
// shiroLoginFailure:就是shiro异常类的全类名.
String exceptionClassName = (String)request.getAttribute("shiroLoginFailure");
String error = null;
if(UnknownAccountException.class.getName().equals(exceptionClassName)) {
error = "用户名/密码错误";
} else if(IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
error = "用户名/密码错误";
} else if(exceptionClassName != null) {
error = "其他错误:" + exceptionClassName;
}
map.put("msg", error);
return "login";
}
}
7.UserInfo:
package com.example.demo.model; import javax.persistence.*;
import java.io.Serializable; /**
* Created by archerlj on 2017/6/30.
*/ @Entity
@Table(name="user_info")
public class UserInfo implements Serializable { private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;//用户id; @Column(unique = true, name = "username")
private String username;//账号.
@Column(name = "password")
private String password; //密码;
@Column(name = "salt")
private String salt;//加密密码的盐
@Column(name = "state")
private byte state;//用户状态,0:创建未认证(比如没有激活,没有输入验证码等等)--等待验证的用户 , 1:正常状态,2:用户被锁定. public long getId() {
return id;
} public void setId(long id) {
this.id = id;
} 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 String getSalt() {
return salt;
} public void setSalt(String salt) {
this.salt = salt;
} public byte getState() {
return state;
} public void setState(byte state) {
this.state = state;
} }
8.UserInfoRespository
package com.example.demo.dao; import com.example.demo.model.UserInfo;
import org.springframework.data.jpa.repository.JpaRepository; /**
* Created by BFD-593 on 2017/8/8.
*/
public interface UserInfoRepository extends JpaRepository<UserInfo,Long> {
public UserInfo findByUsername(String username); public UserInfo save(UserInfo userInfo);
}
9.UserInfoService:
import com.example.demo.dao.UserInfoRepository;
import com.example.demo.model.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; /**
* Created by BFD-593 on 2017/8/8.
*/
@Service
public class UserInfoService {
@Autowired
private UserInfoRepository userInfoRepository; public UserInfo findByUsername(String username){
return userInfoRepository.findByUsername(username);
}
}
10.配置jpa请看之前博客
springboot集成shiro实现身份认证的更多相关文章
- springboot集成shiro实现权限认证
github:https://github.com/peterowang/shiro 基于上一篇:springboot集成shiro实现身份认证 1.加入UserController package ...
- SpringBoot集成Shiro并用MongoDB做Session存储
之前项目鉴权一直使用的Shiro,那是在Spring MVC里面使用的比较多,而且都是用XML来配置,用Shiro来做权限控制相对比较简单而且成熟,而且我一直都把Shiro的session放在mong ...
- SpringBoot集成Shiro 实现动态加载权限
一.前言 本文小编将基于 SpringBoot 集成 Shiro 实现动态uri权限,由前端vue在页面配置uri,Java后端动态刷新权限,不用重启项目,以及在页面分配给用户 角色 . 按钮 .ur ...
- SpringBoot学习笔记(五):SpringBoot集成lombok工具、SpringBoot集成Shiro安全框架
SpringBoot集成lombok工具 什么是lombok? 自动生成setget方法,构造函数,打印日志 官网:http://projectlombok.org/features/index. 平 ...
- Shiro之身份认证、与spring集成(入门级)
目录 1. Shro的概念 2. Shiro的简单身份认证实现 3. Shiro与spring对身份认证的实现 前言: Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在 JavaSE 环境 ...
- SpringBoot学习:整合shiro(身份认证和权限认证),使用EhCache缓存
项目下载地址:http://download.csdn.NET/detail/aqsunkai/9805821 (一)在pom.xml中添加依赖: <properties> <shi ...
- springboot集成shiro 实现权限控制(转)
shiro apache shiro 是一个轻量级的身份验证与授权框架,与spring security 相比较,简单易用,灵活性高,springboot本身是提供了对security的支持,毕竟是自 ...
- 【Shiro】SpringBoot集成Shiro
项目版本: springboot2.x shiro:1.3.2 Maven配置: <dependency> <groupId>org.apache.shiro</grou ...
- SpringBoot集成Shiro实现权限控制
Shiro简介 Apache Shiro是一个功能强大且易于使用的Java安全框架,用于执行身份验证,授权,加密和会话管理.使用Shiro易于理解的API,您可以快速轻松地保护任何应用程序-从最小的移 ...
随机推荐
- 【LeetCode】062. Unique Paths
题目: A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). ...
- win32 UNICODE 支持
#include <string> #ifdef _UNICODE #define tstring std::wstring #define __T(quote) L##quote #el ...
- HDU4027(线段树单点更新区间)
Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65768/65768 K ...
- 【转】Pro Android学习笔记(一):Android 平台 2013.6.4
本系列是阅读<Pro Android4>的读书笔记,也包括网络阅读资料的整理,以及个人心得. 由于智能手机引入AP(应用处理器),Android在某种意义上是个人计算机,具有桌面计算机的完 ...
- VS2008 查找失效怎么办
按Ctrl+F没有反应? visual studio 里 查找替换 显示不出来; 还能用 让他查找个不存在的文本还会弹出找不到的提示; 就是看不到 查找替换的操作框了; 问题解决方法: ...
- stm32之复位与待机唤醒
一.复位 stm32复位有三种类型,分别为系统复位.电源复位和备份域复位. 其中系统复位又分为: NRST引脚低电平(外部复位) 窗口看门狗计数结束 独立看门狗计数结束 软件复位 低功耗管理复位 二. ...
- hadoop--谷歌三大论文
学习大数据必读的三个论文: http://pan.baidu.com/s/1c0FA69U 在我的网盘,大家可以去下载 Google File System中文版 Google Bigtable中文版 ...
- Linux运行Tomcat下的war文件
1.查看Tomcat进程: ps -ef |grep tomcat 2.关闭Tomcat进程: kill -9 pid 3.关闭Tomcat运行: bin目录下执行 ./shutdown.sh 4. ...
- PLSQ创建用户L
1.首先使用dba权限角色登陆PLSQL 2.选择File-New-User 输入需要创建的账户及密码,选择表空间 3.一定要分配的权限:Role privileges 角色权限,至少分配conn ...
- 后缀数组dc3算法模版(待补)
模版: ; #define F(x) ((x)/3+((x)%3==1?0:tb)) #define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2) int wa[maxn ...