一、最简单的集成
只解决需要登录的功能
1.创建maven工程
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 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.4.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.jyj</groupId>
<artifactId>springbootshiro</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springbootshiro</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-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.1</version>
</dependency>
</dependencies>
<!--阿里镜像 可配置到setting.xml也可以配置在项目里-->
<repositories>
<repository>
<id>nexus-aliyun</id>
<name>nexus-aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<build>
<!--打包的名称-->
<finalName>springbootshiro</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.自定义域
package com.jyj.springbootshiro.comm;
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 java.util.HashSet;
import java.util.Set;
/**
* @class: com.jyj.springbootshiro.comm.UserRealm
* @description: 自定义权限域
* @author: jiangzengkui
* @company: 教育家
* @create: 2021-01-05 15:02
*/
public class UserRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("获得相关权限===================");
//得到登录用户账号
String login_code=(String) principalCollection.getPrimaryPrincipal();
//获得角色信息
Set<String> roles=getRole(login_code);
//获得权限信息
Set<String> permissions=getPermission(login_code);
//new SimpleAuthorizationInfo,设置相关的角色和权限数据
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
info.setRoles(roles);
info.setStringPermissions(permissions);
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("登录==============================");
//用户名+密码
String name = "root";
String password="123";
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
if (!token.getUsername().equals(name)){
return null; //return null 会自动抛出异常
}
//密码认证,shiro做
return new SimpleAuthenticationInfo("",password,"");
}
/**模拟从数据库
* 通过用户账号获得角色信息
* @param login_code
* @return
*/
private Set<String> getRole(String login_code) {
Set<String> roles=new HashSet<>();
roles.add("role1");
roles.add("role2");
roles.add("role3");
return roles;
}
/**
* m模拟从数据库获得权限数据
* @param login_code
* @return
*/
private Set<String> getPermission(String login_code) {
Set<String> permission=new HashSet<>();
permission.add("user:delete");
permission.add("user:update");
permission.add("user:create");
return permission;
}
}
3.集成shiro类
package com.jyj.springbootshiro.comm;
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;
/**
* @class: com.jyj.springbootshiro.comm.ShiroConfig
* @description: shiro配置类
* @author: jiangzengkui
* @company: 教育家
* @create: 2021-01-05 15:13
*/
@Configuration
public class ShiroConfig {
//ShiroFilterFactoryBean(步骤3)
@Bean(name = "shiroFilterFactoryBean")
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager")DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
bean.setSecurityManager(defaultWebSecurityManager);
bean.setSecurityManager(defaultWebSecurityManager);
/*
* anon:无需认证就可以访问
* authc:必须认证了才能访问
* user:必须用有了 记住我 功能才能用
* perms:拥有对某个资源的权限才能访问
* role:拥有某个角色权限才能访问
*/
Map<String ,String> filterMap = new LinkedHashMap<>();
filterMap.put("/user/add","authc");
filterMap.put("/user/update","authc");
filterMap.put("/index","authc");
filterMap.put("/logout","logout");//注销
bean.setFilterChainDefinitionMap(filterMap);
return bean;
}
//DefaultWebSecurityManager(步骤2)
@Bean(name = "defaultWebSecurityManager")
public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
securityManager.setRealm(userRealm());
return securityManager;
}
//创建realm对象(步骤1)
@Bean(name = "userRealm")
public UserRealm userRealm(){
return new UserRealm();
}
/**
* 开启shiro aop注解支持.否则@RequiresRoles等注解无法生效
* 使用代理方式;
* @param securityManager
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager securityManager){
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
/**
* Shiro生命周期处理器
* @return
*/
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
return new LifecycleBeanPostProcessor();
}
/**
* 自动创建代理
* @return
*/
@Bean
@DependsOn({"lifecycleBeanPostProcessor"})
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}
}
4.mvc配置
为追求简单,没有使用freemarker等模板技术,直接用html
application.properties
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.html
5.静态html文件
保存再static资源目录里
index.html | |
login_index.html | |
add.html | |
update.html | |
5.control控制类代码
package com.jyj.springbootshiro.control;
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.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @class: com.jyj.springbootshiro.control.DemoContrl
* @description: 测试
* @author: jiangzengkui
* @company: 教育家
* @create: 2021-01-05 14:58
*/
@Controller
public class DemoContrl {
/**
* 通过以来注入
*/
@Autowired
DefaultWebSecurityManager defaultWebSecurityManager;
@RequestMapping("/index")
public String index(){
System.out.println("===================");
return "index";
}
/**
* 通过注解鉴权
* @return
*/
@RequestMapping("/user/add")
@RequiresRoles("role1")
@RequiresPermissions("user:create")
public String add(){
System.out.println("=======add============");
return "add";
}
/**
* 硬编码鉴权
* @return
*/
@RequestMapping("/user/update")
public String update(){
//硬编码鉴权
if(defaultWebSecurityManager==null){
System.out.println("defaultWebSecurityManager==null");
}
else{
SecurityUtils.setSecurityManager(defaultWebSecurityManager);
Subject subject=SecurityUtils.getSubject();
//单个角色
subject.checkRole("role1");//注意这个不会返回bool,而是通过UnauthorizedException异常
System.out.println("role role1 is "+subject.isAuthenticated());
//单个权限
System.out.println("Permission[user:create] is "+subject.isPermitted("user:updatex"));
}
System.out.println("=======update============");
return "update";
}
@RequestMapping("/login_index")
public String loginIndex(){
return "login_index";
}
@RequestMapping("/login")
public String login(String userName,String pwd){
//获取当前的用户
Subject subject = SecurityUtils.getSubject();
//封装用户的登录数据
UsernamePasswordToken token = new UsernamePasswordToken(userName, pwd);
try {
subject.login(token); //执行登录方法,如果没有异常说明OK
return "index";
} catch (UnknownAccountException e) { //用户名不存在
return "login_index";
} catch (IncorrectCredentialsException e) { //密码错误
return "login_index";
}
}
/**
* 注销
* @return
*/
@RequestMapping("/logout")
public String logout(){
//获取当前的用户
//Subject subject = SecurityUtils.getSubject();
// subject.logout();//注销
return "login_index";
}
}
6、总结:
代码结构图
代码下载地址
https://gitee.com/jiangsanwa/security