一、Shiro
Apache Shiro是一个Java安全框架。
1、官网:http://shiro.apache.org/
2、三个核心组件
Subject:即“当前操作用户”,可以指人、第三方进程、后台帐户或其他类似事物。Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。
SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。
Realm:Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。
从这个意义上讲,Realm实质上是一个安全相关的DAO:它封装了数据源的连接细节,并在需要时将相关数据提供给Shiro。当配置Shiro时,配置多个Realm是可以的,但是至少需要一个。
二、SpringBoot集成Shiro
1、依赖配置
<?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 https://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>2.1.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.wjy</groupId> <artifactId>shirodemo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>shirodemo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <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> <scope>runtime</scope> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2、Shiro配置
package com.wjy.shirodemo; import java.util.HashMap; import java.util.Map; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); Map<String, String> filterChainDefinitionMap = new HashMap<String, String>(); //登录时访问的地址,即没有登录时访问任何页面跳转的地址 shiroFilterFactoryBean.setLoginUrl("/login"); //认证未通过访问的地址,即经过认证但是没有相应的权限时跳转的地址 shiroFilterFactoryBean.setUnauthorizedUrl("/unauthc"); //设置认证成功之后转向的地址 shiroFilterFactoryBean.setSuccessUrl("/authc/index"); // /* anon表示不拦截 允许任何人访问 filterChainDefinitionMap.put("/*", "anon"); // /authc/index 必须登录才能访问 filterChainDefinitionMap.put("/authc/index", "authc"); // /authc/admin 需要有admin角色才能访问 filterChainDefinitionMap.put("/authc/admin", "roles[admin]"); // /authc/renewable 需要有Create,Update权限 filterChainDefinitionMap.put("/authc/renewable", "perms[Create,Update]"); // /authc/removable需要有Delete权限 filterChainDefinitionMap.put("/authc/removable", "perms[Delete]"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } @Bean public HashedCredentialsMatcher hashedCredentialsMatcher() { HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); // 散列算法 hashedCredentialsMatcher.setHashAlgorithmName(PasswordHelper.ALGORITHM_NAME); // 散列次数 hashedCredentialsMatcher.setHashIterations(PasswordHelper.HASH_ITERATIONS); return hashedCredentialsMatcher; } @Bean public EnceladusShiroRealm shiroRealm() { EnceladusShiroRealm shiroRealm = new EnceladusShiroRealm(); // 原来在这里 shiroRealm.setCredentialsMatcher(hashedCredentialsMatcher()); return shiroRealm; } @Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(shiroRealm()); return securityManager; } @Bean public PasswordHelper passwordHelper() { return new PasswordHelper(); } }
其他代码参考:githup
验证:
(1)注册:http://localhost:8088/register?username=wjy&password=123456
(2)未登录而访问index:http://localhost:8088/authc/index 会跳转到登录页面: http://localhost:8088/login
(3)使用错误密码登录:http://localhost:8088/doLogin?username=wjy&password=123
(4)登录成功:http://localhost:8088/doLogin?username=wjy&password=123456 跳转到http://localhost:8088/authc/index