springboot-shiro:请求授权

承接:springboot-shiro:整合mybatis

1 修改数据库中的用户表

增加了一个权限的字段

2 修改实体类,添加新增加的字段

src/main/java/com/lv/pojo/User.java

package com.lv.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String pwd;
private String perms;
}

3 在MyController中配置一个未授权的提示页面

src/main/java/com/lv/controller/MyController.java

@RequestMapping("/unauthorized")
@ResponseBody
public String unauthorized(){
return "未授权不能访问此页面";
}

4 在拦截器中编写授权逻辑

src/main/java/com/lv/config/ShiroConfig.java

package com.lv.config;
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 {
//ShiroFilterFactoryBean : 第三步
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
//拦截
Map<String,String> filterMap = new LinkedHashMap<>();
//授权,正常的情况下,没有授权会跳转到未授权的页面
filterMap.put("/user/add","perms[user:add]");
filterMap.put("/user/update","perms[user:update]");
filterMap.put("/user/*","authc");
bean.setFilterChainDefinitionMap(filterMap);
//设置登录的请求
bean.setLoginUrl("/toLogin");
//设置未授权页面
bean.setUnauthorizedUrl("/unauthorized");
return bean;
}
//DefaultWebSecurityManager : 第二步
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联userRealm
securityManager.setRealm(userRealm);
return securityManager;
}
//创建realm对象,需要自定义类 : 第一步
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
}

5 修改UserRealm

在自定义的授权认证中,获取登录的用户,从而实现动态认证授权操作

src/main/java/com/lv/config/UserRealm.java

package com.lv.config;
import com.lv.pojo.User;
import com.lv.service.UserService;
import org.apache.catalina.security.SecurityUtil;
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;
//自定义的UserRealm extends AuthorizingRealm
public class UserRealm extends AuthorizingRealm {
@Autowired
UserService userService;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了=>授权doGetAuthorizationInfo");
//SimpleAuthorizationInfo
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//拿到当前登录的这个对象
Subject subject = SecurityUtils.getSubject();
//获取到认证中提交的第一个参数user,拿到user对象
User currentUser = (User) subject.getPrincipal();
//设置当前用户的权限
info.addStringPermission(currentUser.getPerms());
return info;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行了=>认证doGetAuthorizationInfo");
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
//连接真实的数据库
User user = userService.queryUserByName(userToken.getUsername());
if (user == null){ //没有这个人
return null; //UnknownAccountException
}
//密码认证,交给shiro做(可以加密: MD5,MD5盐值加密)
return new SimpleAuthenticationInfo(user,user.getPwd(),"");
}
}

6 启动程序测试

登录,admin1,该用户只有add访问权限

点击add

成功进入add页面,然后访问update页面

跳转到了未授权提示页面,接下来登录admin2,该用户只用update访问权限

点击add

跳转到了未授权提示页面,然后访问update页面

成功进入update页面,如果登录admin3,该用户一个权限也没有,访问两个页面都会被拦截,这里就不演示了,至此实现了用户的授权控制

相关博文:
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示