springboot web集成shiro框架
1.引入maven依赖
<!--shiro整合springboot web的自动装配包-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.9.0</version>
</dependency>
<!--SpringBoot中实现Shiro控制ThymeLeaf界面按钮级权限控制-->
<!-- https://mvnrepository.com/artifact/com.github.theborakompanioni/thymeleaf-extras-shiro -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.6.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.配置文件
有默认值可以不去配置
3.配置类
shrioConfig.java
package com.config;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.dao.MyRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authc.credential.PasswordMatcher;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.mgt.SessionsSecurityManager;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.util.ThreadContext;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author lzj
* @date 2021/8/29
*/
@Configuration
public class shiroConfig {
// 注入我们的realm
@Bean
public MyRealm userRealm() {
MyRealm userRealm = new MyRealm();
//配置使用哈希 密码匹配MyRealm
// userRealm.setCredentialsMatcher(new PasswordMatcher());
return userRealm;
}
// 配置url过滤器
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
// anon可以匿名访问
// authc需要权限
chainDefinition.addPathDefinition("/login", "anon");
chainDefinition.addPathDefinition("/", "anon");
chainDefinition.addPathDefinition("/**", "authc");
return chainDefinition;
}
// 设置用于匹配密码的CredentialsMatcher
@Bean
public HashedCredentialsMatcher credentialsMatcher() {
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
credentialsMatcher.setHashAlgorithmName(Sha256Hash.ALGORITHM_NAME);
// 散列算法,这里使用更安全的sha256算法 c
credentialsMatcher.setStoredCredentialsHexEncoded(false);
// 数据库 存储的密码字段使用HEX还是BASE64方式加密
credentialsMatcher.setHashIterations(1024);
// 散列迭代次数
return credentialsMatcher;
}
//配置security并设置
//userReaml,避免xxxx required a bean named 'authorizer'
//that could not be found.的报错
@Bean
public SessionsSecurityManager securityManager() {
DefaultWebSecurityManager securityManager =
new DefaultWebSecurityManager();
securityManager.setRealm(userRealm());
// 我引入的是 shiro-spring-boot-web-starter
// 在junit测试下 这个要加上 但是 在controller里面加不加都可以
ThreadContext.bind(securityManager);
return securityManager;
}
/*** shiro方言 支持shiro标签 * @return */
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
}
MyRealm.java
package com.dao;
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.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.subject.PrincipalCollection;
import java.util.Arrays;
/**
* 操作数据库的 我们可以注入一格dao层
* @author lzj
* @date 2021/8/14
*/
public class MyRealm extends JdbcRealm {
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("MYRealm authenication");
String username = (String) token.getPrincipal();
// 从数据库里查询 然后设置属性
String pwd = "123";
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,pwd,getName());
return simpleAuthenticationInfo;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String)principals.getPrimaryPrincipal();
//数据库中根据用户名查询角色权限
System.out.println("MYRealm authorization" + username);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRoles(Arrays.asList("admin","host"));
info.addStringPermissions(Arrays.asList("user:add","user:delete"));
return info;
}
}
4.使用
UsernamePasswordToken token = new UsernamePasswordToken("123", "123");
SecurityUtils.getSubject().login(token);
5.注意那个绑定的问题
直接在web中使用没有异常,但是springtest下会报错
在junit测试下 这个要加上 但是 在controller里面加不加都可以 ThreadContext.bind(securityManager);
注意
只有当下面两个一起用的时候才能过滤static下的文件,否则默认static下的文件访问直接在跟路径/下面
chainDefinition.addPathDefinition("/static/**", "anon");
mvc:
static-path-pattern: /static/**
通过thymeleaf访问
<link rel="stylesheet" th:href="@{/static/css/font.css}">
<link rel="stylesheet" th:href="@{/static/css/xadmin.css}">
<script th:src="@{/static/lib/layui/layui.js}" charset="utf-8"></script>
<script type="text/javascript" th:src="@{/static/js/xadmin.js}"></script>