SpringBoot整合Shiro实现权限管理

//创建默认安全管理器

DefaultSecurityManager securityManager = new DefaultSecurityManager();

//安全管理器配置自定义Realm

MyRealm realm = new MyRealm();

//创建密码匹配器

HashedCredentialsMatcher md5 = new HashedCredentialsMatcher(“md5”);

//设置迭代次数

md5.setHashIterations(10);

//配置匹配器

realm.setCredentialsMatcher(md5);

securityManager.setRealm(realm);

//SecurityUtils配置安全管理器

SecurityUtils.setSecurityManager(securityManager);

//获得Subject对象

Subject subject = SecurityUtils.getSubject();

//创建账号密码token

UsernamePasswordToken user = new UsernamePasswordToken(“zhang”, “123456”);

//登录验证

subject.login(user);

//权限判断

System.out.println(“是否登录成功:” + subject.isAuthenticated());

System.out.println(“是否拥有role1角色:” + subject.hasRole(“role1”));

System.out.println(“是否拥有delete权限:” + subject.isPermitted(“user:delete”));

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VzpaSypf-1608710040672)(shiro.assets/1608618247076.png)]

SpringBoot+MyBatis+Shiro整合

========================================================================================

1、表设计

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XS3cRTkB-1608710040674)(shiro.assets/1608618965879.png)]

  • s_user 用户表

  • s_role 角色表

  • s_menu 菜单表(权限表)

  • s_user_menu 用户角色中间表

  • s_role_menu 角色菜单中间表

2、添加依赖

org.springframework.boot

spring-boot-starter-web

org.projectlombok

lombok

true

com.baomidou

mybatis-plus-boot-starter

3.3.2

mysql

mysql-connector-java

8.0.16

org.apache.shiro

shiro-spring-boot-web-starter

1.7.0

org.springframework.boot

spring-boot-starter-thymeleaf

com.github.theborakompanioni

thymeleaf-extras-shiro

2.0.0

2、SpringBoot配置

jdbc配置

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.datasource.url=jdbc:mysql://localhost:3306/erp_db?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8

spring.datasource.username=root

spring.datasource.password=123456

mybatis配置

mybatis-plus.type-aliases-package=com.blb.blb_erp.entity

mybatis-plus.mapper-locations=classpath:mapper/*.xml

shiro配置

登录页面

shiro.loginUrl=/pages/login.html

登录失败跳转页面

shiro.unauthorizedUrl=/pages/failed.html

登录成功跳转页面

shiro.successUrl=/pages/index.html

3、编写Mapper接口

需要三个方法:

  1. 按用户名查找用户

  2. 按用户id查询所有菜单

  3. 按用户id查询所有角色

/**

  • 用户接口

*/

public interface SUserMapper extends BaseMapper{

/**

  • 通过用户名查询用户

  • @param username

  • @return

*/

SUser selectUserByUsername(String username);

}

映射文件:

<?xml version="1.0" encoding="UTF-8"?>

select * from s_user where user_name = #{username}

/**

  • 菜单接口

*/

public interface SMenuMapper extends BaseMapper{

/**

  • 根据userId查询所有权限

  • @param userId

  • @return

*/

List selectMenusByUserId(String userId);

}

映射文件:

<?xml version="1.0" encoding="UTF-8"?>

select m.* from s_user u,s_role r,s_user_role ur,s_menu m,s_role_menu rm

where ur.role_id = r.id and ur.user_id = u.id and rm.role_id = r.id and rm.menu_id = m.id

and u.id = #{userId}

/**

  • 角色接口

*/

public interface SRoleMapper extends BaseMapper{

/**

  • 根据用户id查询所有角色

  • @param userId

  • @return

*/

List selectRolesByUserId(String userId);

}

映射文件:

<?xml version="1.0" encoding="UTF-8"?>

select r.* from s_user_role ur

join s_user u on ur.user_id = u.id

join s_role r on ur.role_id = r.id

where ur.user_id = #{userId}

4、自定义Realm

/**

  • 用户Realm

*/

public class UserRealm extends AuthorizingRealm {

@Autowired

private SUserMapper userMapper;

@Autowired

private SRoleMapper roleMapper;

@Autowired

private SMenuMapper menuMapper;

@Override

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

//获得用户对象

SUser user = (SUser) principalCollection.getPrimaryPrincipal();

//查询权限和角色

List menus = menuMapper.selectMenusByUserId(user.getId());

List roles = roleMapper.selectRolesByUserId(user.getId());

//保存权限和角色名称的集合

List strRoles = new ArrayList<>();

roles.forEach(r -> strRoles.add(r.getRoleName()));

List strMenus = new ArrayList<>();

menus.forEach(m -> strMenus.add(m.getMenuName()));

//返回带有角色和权限名称的授权信息

SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

info.addRoles(strRoles);

info.addStringPermissions(strMenus);

return info;

}

@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

//获得账号

String username = authenticationToken.getPrincipal().toString();

//通过账号查询用户

SUser user = userMapper.selectUserByUsername(username);

if(user == null){

throw new UnknownAccountException(“此用户不存在”);

}

//返回验证信息 参数:1、用户对象 2、正确密码 3、盐 4、realm名称

return new SimpleAuthenticationInfo(user,user.getPassWord(), ByteSource.Util.bytes(user.getSalt()),getName());

}

}

5、Shiro配置类

/**

  • Shiro配置

*/

@Configuration

public class ShiroConfig {

//返回Realm

@Bean

public UserRealm myRealm(){

UserRealm myRealm = new UserRealm();

//设置密码匹配器

HashedCredentialsMatcher md5 = new HashedCredentialsMatcher(“md5”);

md5.setHashIterations(10);

myRealm.setCredentialsMatcher(md5);

//关闭缓存

myRealm.setCachingEnabled(false);

return myRealm;

}

//返回面向Web开发的安全管理器

@Bean

public DefaultWebSecurityManager defaultWebSecurityManager(){

DefaultWebSecurityManager sm = new DefaultWebSecurityManager();

//设置自定义Realm

sm.setRealm(myRealm());

return sm;

}

//返回Shiro过滤器链定义

@Bean

public ShiroFilterChainDefinition shiroFilterChainDefinition() {

DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();

//定义过滤器链key为url,value为anon不验证,authc验证

//anon在前,authc在后,需要使用LinkedHashMap保留顺序

LinkedHashMap<String, String> map = new LinkedHashMap<>();

map.put(“/pages/login.html”,“anon”);

map.put(“/user/login”,“anon”);

map.put(“/**”,“authc”);

chainDefinition.addPathDefinitions(map);

return chainDefinition;

}

//启动thymeleaf的shiro标签

@Bean

public ShiroDialect shiroDialect(){

return new ShiroDialect();

}

}

6、启动类

@MapperScan(“com.blb.blb_erp.mapper”)

@SpringBootApplication

public class BlbErpApplication {

public static void main(String[] args) {

SpringApplication.run(BlbErpApplication.class, args);

}

}

7、控制器

@Data

@AllArgsConstructor

@NoArgsConstructor

public class JsonResult {

private int code;

private Object data;

}

@RestController

@RequestMapping(“/user”)

public class UserController {

@PostMapping(“/login”)

public JsonResult login(String username,String password){

//创建Token

UsernamePasswordToken token = new UsernamePasswordToken(username, password);

//获得subject

Subject subject = SecurityUtils.getSubject();

try {

subject.login(token);

return new JsonResult(1,“登录成功”);

}catch (AuthenticationException ex){

ex.printStackTrace();

}

return new JsonResult(0,“账号或密码错误”);

}

@RequiresRoles(“管理员”)

@GetMapping(“/role-admin”)

public String testRole(){

return “有管理员角色”;

}

@RequiresPermissions(“部门管理”)

@GetMapping(“/menu-dept”)

public String testMenu(){

return “有部门管理权限”;

}

}

@RequiresRoles、@RequiresPermissions写在控制器的方法上,登录用户有对应的角色和权限才能访问。

RememberMe

========================================================================

可以在登录页面上添加记住我功能,勾选后下次不用登录直接进去系统了

1、页面上添加RememberMe复选框

登录

系统登录

记住我

<el-button type=“primary” @click=“login”>登 录

取 消

2、修改登录方法

@PostMapping(“/login”)

public JsonResult login(String username,String password,Boolean rememberMe){

//创建Token

最后

分布式技术专题+面试解析+相关的手写和学习的笔记pdf

还有更多Java笔记分享如下:

image

取 消

2、修改登录方法

@PostMapping(“/login”)

public JsonResult login(String username,String password,Boolean rememberMe){

//创建Token

最后

分布式技术专题+面试解析+相关的手写和学习的笔记pdf

还有更多Java笔记分享如下:

[外链图片转存中…(img-947RFXDN-1719174128767)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值