闲着无聊动手整理一下shiro的简单使用。
<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
我的配置类
package mlt.boot.config;
import java.util.LinkedHashMap;
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;
/**
* shiro 配置类
* @author ljw 2020年9月25日08:46:03
*
*/
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
//添加shiro的内置过滤器
/*
anon: 无需认证就可访问
authc:必须认证才能访问
user:必须拥有记住我功能才能访问
perms: 拥有对某个资源的权限才能访问
role:拥有某个角色权限才能访问
*/
// 配置访问权限 必须是LinkedHashMap,因为它必须保证有序
LinkedHashMap<String, String> filterMap = new LinkedHashMap<>();
//授权
filterMap.put("/static/**", "anon");//静态资源不拦截
//filterMap.put("/user/add","perms[user:add]");
//common下的请求都需要进行认证 遵从从上到下即从小到大原则
filterMap.put("/common/tonewfolder","roles[new]");
filterMap.put("/common/*","authc");
//设置退出
filterMap.put("/logout", "logout");
//设置登录请求
bean.setLoginUrl("/toLogin");
bean.setSuccessUrl("/");
//设置未授权页面
bean.setUnauthorizedUrl("/noPermission");
bean.setFilterChainDefinitionMap(filterMap);
return bean;
}
@Bean(name="securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("myRealm") MyRealm myRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myRealm);
return securityManager;
}
/**
* 自定义realm
* @return
*/
@Bean(name = "myRealm")
public MyRealm myRealm(){
return new MyRealm();
}
}
//开启shiro aop注解支持 作用在方法上
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager){
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
我的自定义realm
package mlt.boot.config;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import mlt.boot.entity.User;
import mlt.boot.mapper.UserMapper;
public class MyRealm extends AuthorizingRealm{
@Autowired
private UserMapper userMapper;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
Subject subject = SecurityUtils.getSubject();
Session session = subject.getSession();
User user = (User)session.getAttribute("loginUser");
System.err.println("currentUser="+user);
if(user == null){
return null;
}
info.addRole("new");
info.addRole("show");
info.addStringPermission("show");
//在这里可以配置角色和权限
//info.addStringPermission(permission);
//info.addStringPermission(permissions);//集合
//info.addRole(role);
//info.addRoles(roles);//集合
return info;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken userToken = (UsernamePasswordToken)token;
String username = userToken.getUsername();
User user = userMapper.findUserByName(username);
if(user==null){
return null;
}
//将登陆用户存入session中
Subject currentSubject = SecurityUtils.getSubject();
Session session = currentSubject.getSession();
session.setAttribute("loginUser",user);
return new SimpleAuthenticationInfo("", user.getPassword(), "");
}
}
几个controller
@RequestMapping("/toLogin")
public String toLogin(){
return "login";
}
@RequestMapping("/login")
public String login(String username,String password){
//获取当前用户
Subject subject = SecurityUtils.getSubject();
//封装用户登录数据
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);
return "index/index";
} catch (Exception e) {
return "login";
}
}
@RequestMapping("/noPermission")
@ResponseBody
public String noPermission(){
return "noPermission";
}
@RequestMapping("logout")
public String logout(){
Subject currentSubject = SecurityUtils.getSubject();
currentSubject.logout();
return "login";
}
上效果图
这是没认证的/common/newfolder请求
这是没认证的/common/update请求
这是认证后没有相应角色的/common/newfolder请求
关于页面上元素的显示也可以使用shiro标签控制;我这里用的jsp演示的
直接先加上
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<shiro:hasPermission name="test1">
有权限为test1的显示
</shiro:hasPermission>
<shiro:hasRole name="test2">
有角色为test2的显示
</shiro:hasRole>
以上就是简单的基本使用,下面搞一下我平时如何使用的
用户表里面直接存角色,也可以单独存另一张表:
角色表很简单
菜单表,这里面主要多了个perm字段
角色菜单表,每个角色对应的菜单栏
使用的时候在这处理,可以每次查询该角色拥有的权限
查询SQL如下:,由于用in的话,没有两边的’’ 所以这里改用find_in_set
在对应请求上加上相应注解即可
普通用户 测试如下:
有权限的:
无权限的: