目录
springboot 整合Shiro:
什么是Shiro
权限,角色,用户之间的关系
Shiro 核心组件
Shiro的运行机制
编写认证和授权规则
具体操作
-
什么是Shiro
是一款主流的java安全框架,不依赖任何容器,可以运行javase,和javaee项目中,它的主要作用是对访问系统用户进行身份认证,授权,会话管理,加密等操作。
用来解决安全管理的系统化框架
-
权限,角色,用户之间的关系
-
Shiro 核心组件
UsernamePasswordToken: Shiro 用来封装用户登录信息,使用用户的登录信息来创建令牌Token。
SecurityManager: Shiro 的核心部分,负责安全认证和授权。
Subject: Shiro 的一个抽象概念,包含了用户信息。
Realm :开发者自定义的模块,根据项目的需求,验证和授权的逻辑全部写在Realm中。
AuthenticationInfo: 用户的角色信息集合,认证时使用。
AuthorzationInfo: 角色的权限信息集合,授权时使用。
DefaultWebSecurityManager: 安全管理器,开发者自定义的Realm需要注入到DefaultWebSecurityManager进行管理才能生效。
ShiroFilterFactoryBean: 过滤器工厂,Shiro的基本运行机制是开发者定制规则,Shiro去执行,具体的作用就是由ShiroFilterFactoryBean 创建的一个个Filter对象来完成。
-
Shiro的运行机制
-
编写认证和授权规则
认证过滤器:
anon:无需认证
authc:必须认证
authcBasic:需要通过HTTPBasic认证
user:不一定通过认证,只要曾经被Shiro记录即可,比如:记住我````授权过滤器:
perms:必须拥有某个权限才能访问
role:必须拥有某个角色才能访问
port:请求的端口必须是指定值才可以
rest:请求必须基于RESTful,POST,GET,DELETE
ssl:必须是安全的URL请求,协议HTTPS*
-
具体操作
1. 加入 Shiro 相关的依赖
2. 创建自定义的realm类
package com.example.demospringboot.shiro.realm;
import com.example.demospringboot.domain.User;
import com.example.demospringboot.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;
public class UserReaml extends AuthorizingRealm {
@Autowired
UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了授权方法");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
Subject subject = SecurityUtils.getSubject();
User currentUser = (User) subject.getPrincipal();
//设置当前用户的权限
info.addStringPermission(currentUser.getPerms());
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("执行了认证方法");
UsernamePasswordToken token=(UsernamePasswordToken) authenticationToken;
User user= userService.findByUsername(token.getUsername());
if(user!=null){
return new SimpleAuthenticationInfo(user,user.getPassword(),getName());
}
return null;
}
}
3. 配置类
package com.example.demospringboot.shiro.config;
import com.example.demospringboot.shiro.realm.UserReaml;
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 {
@Bean
UserReaml userReaml(){
return new UserReaml();
}
@Bean
DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userReaml") UserReaml userReaml) {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(userReaml);
return manager;
}
@Bean
ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(defaultWebSecurityManager);
Map map = new LinkedHashMap<>();
//需要有user:add权限才可以
map.put("/index","perms[user:add]");
//认证
map.put("/login", "anon");
map.put("/**", "authc");
bean.setFilterChainDefinitionMap(map);
bean.setUnauthorizedUrl("/noauth");
bean.setLoginUrl("/dologin");
// bean.setSuccessUrl("/index");
return bean;
}
}
在这里进行 Shiro 的配置主要配置 3 个 Bean :
首先需要提供一个 Realm 的实例。
需要配置一个 SecurityManager,在 SecurityManager 中配置 Realm。
配置一个 ShiroFilterFactoryBean ,在 ShiroFilterFactoryBean 中指定路径拦截规则等。配置登录和测试接口。
其中,ShiroFilterFactoryBean 的配置稍微多一些,配置含义如下:setSecurityManager 表示指定 SecurityManager。
setUnauthorizedUrl:表示指定无权限时显示的页面
setLoginUrl 表示指定登录页面。
setSuccessUrl 表示指定登录成功页面。
接下来的 Map 中配置了路径拦截规则,**注意,要有序**。
4.配置登录 Controller
package com.example.demospringboot.controller;
import com.example.demospringboot.domain.User;
import com.example.demospringboot.dto.UserLoginDto;
import com.example.demospringboot.dto.UserRegisterDto;
import com.example.demospringboot.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController//@Controller 代表这个类会被springboot 接管
//被@Controller这个注解的类,中的所有方法,如果返回值是String,并且有具体的页面可以跳转,那么就会被视图解析器解析
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/login")
public String loginIn(@RequestBody UserLoginDto userLoginDto) {
if (userLoginDto == null) {
return "操作失败";
}
Subject subject = SecurityUtils.getSubject();
try {
//可以加密。。。
subject.login(new UsernamePasswordToken(userLoginDto.getUsername(), userLoginDto.getPassword()));
return "登录成功!";
} catch (AuthenticationException e) {
e.printStackTrace();
return "登录失败!";
}
}
@RequestMapping("/dologin")
public String login(){
return "login";
}
@RequestMapping("/findAll")
public List findAll() {
return userService.findAll();
}
@RequestMapping("/noauth")
public String unauthorized(){
return "未经授权无法查看此页面";
}
}
5.测试
首先访问 /findAll 接口,由于未登录,所以会自动跳转到 /dologin 接口
然后调用 /login 接口完成登录
再次访问 /findAll 接口,就可以成功访问了
参考文章:
(43条消息) spring boot整合shiro实现登录认证授权你_qq_59776041的博客-CSDN博客_springshiro集成shiro进行登录权限认证



