thymeleaf模板+Shiro标签对按钮权限的控制
环境介绍
SpringBoot+Shiro+thymeleaf模板+Layui(前端)
这两天学习了shiro相关的技术,碰到一个问题:如何根据登录的不同角色,来控制不同的url。这个问题对于shiro来说非常简单,但是我的url请求在ajax里面,每次虽然拦截成功了,但是不显示拦截之后的界面(比如:您没有权限操作…)。
为了解决这个问题,我搜了很多方法,配置了拦截器来跳转页不管用(主要是我技术太菜了QAQ…)
后来我突然想到,我为啥要对url进行控制呢,直接对按钮进行控制不就得了
比如按钮可见:
管理员: 查看、编辑、删除
vip用户: 查看、编辑
普通用户:查看
正巧thymeleaf又支持shiro标签,问题就解决了~
1、相关配置
1、
pom.xml中,引入thymeleaf对shiro标签支持的依赖
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
2、
在shiro的config配置中,添加声明
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
3、
在html页面中使用标签
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="detail" >查看</a>
<a class="layui-btn layui-btn-xs" lay-event="edit" shiro:hasRole="vip">编辑</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del" shiro:hasPermission="admin">删除</a>
2、结果演示
3、完整配置文件
为了方便和我一样的小白学习,这里把我完整的配置列出来,方便共同学习~
ShiroConfig.class
package com.braisedpanda.shirotest.shiro;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
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(name = "shiroFilter")
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//这里设置没有登录时,跳转界面
shiroFilterFactoryBean.setLoginUrl("/");
//这里是没有授权时,跳转的界面
shiroFilterFactoryBean.setUnauthorizedUrl("/notRole");
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/webjars/**", "anon");
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/", "anon");
filterChainDefinitionMap.put("/userlist/**", "roles[ds]");
filterChainDefinitionMap.put("/images/**", "anon");
filterChainDefinitionMap.put("/layui/**", "anon");
filterChainDefinitionMap.put("/lib/**", "anon");
filterChainDefinitionMap.put("/student/delete/**","perms['swds']");
// filterChainDefinitionMap.put("/userlist/**", "perms['swds']");
filterChainDefinitionMap.put("/admin/**", "authc");
filterChainDefinitionMap.put("/user/**", "authc");
//主要这行代码必须放在所有权限设置的最后,不然会导致所有 url 都被拦截 剩余的都需要认证
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
defaultSecurityManager.setRealm(customRealm());
return defaultSecurityManager;
}
@Bean
public CustomRealm customRealm() {
CustomRealm customRealm = new CustomRealm();
return customRealm;
}
//注解
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
}
CustomRealm.class
package com.braisedpanda.shirotest.shiro;
import com.braisedpanda.shirotest.bean.User;
import com.braisedpanda.shirotest.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.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.HashSet;
import java.util.Set;
public class CustomRealm extends AuthorizingRealm {
@Autowired
UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("-------开始权限认证--------");
String username = (String) SecurityUtils.getSubject().getPrincipal();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRole("student");
// info.addStringPermission("s1");
return info;
}
//重写验证身份的方法
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("-------开始身份认证--------");
String username = (String) authenticationToken.getPrincipal();
String password = new String((char[]) authenticationToken.getCredentials());
User user = userService.getUser(username,password);
System.out.println("用户信息" + user);
if (user == null) {
throw new AccountException("用户名或密码错误");
}
return new SimpleAuthenticationInfo(username, password, getName());
}
}