shiro爱springboot中使用 ,还有thymeleaf前端框架。主要是如何配置
pom.xml配置依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com</groupId>
<artifactId>bpms</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>bpms</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--json格式转换-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<!--分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency> <!--认证,授权,加密相关-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>
<!--Druid提供强大的监控和扩展功能-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.14</version>
</dependency> <!--thyemleaf中支持shiro-->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.7</version>
<configuration>
<overwrite>true</overwrite>
<configurationFile>${basedir}/src/main/resources/generatorConfig.xml</configurationFile>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
</dependencies> </plugin>
</plugins>
</build> </project>
Shiro配置文件的设置
package com.bpms.config; import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.bpms.shiro.CustomRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
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.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
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; /*shiro的注册,springboot没有配置文件,只有通过java类的形式进行注册,
关于shiro一共用 普通java类,SSM框架,springboot分别写了三遍,原理大致是一样的。区别在于怎么配置
1.shiro过滤器, 对登录的用户进行 认证,授权。对url路径进行的拦截,需要shiro过滤器
2.shiro管理器,管理认证 授权 缓存 等等。但是都需要创建配置。首先创建安全管理器,去管理各种组件。
3.shiro自定义域。shiro安全管理器中认证需要的组件
4.密码匹配器。
5.缓存
6.使shiro权限注解生效
7.对类进行aop代理
8.对thymeleaf进行支持
*/
@Configuration//说明这个被为配置信息类,spring 把这个类作为配置文件处理,把里面被@Bean修饰的方法返回的对象交给IOC容器管理。注入需要的地方
//这个注入,好像时方法中的参数。会被自动调用
public class ShiroConfig { //Shiro过滤器配置,并注入安全管理器
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("sm") DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setLoginUrl("/login.html");
bean.setUnauthorizedUrl("/403.html");
Map map = new LinkedHashMap();
map.put("/login.html", "anon");
map.put("/doLogin", "anon");
map.put("/css/**", "anon");
map.put("/static/**", "anon");
map.put("/js/**", "anon");
map.put("/images/**", "anon");
map.put("/*", "authc");
bean.setFilterChainDefinitionMap(map);
bean.setSecurityManager(securityManager);
return bean;
} //Shiro安全管理器,把域放入安全管理器
@Bean("sm")
public DefaultWebSecurityManager securityManager(CustomRealm customRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(customRealm);
return securityManager;
} //配置自定义域,可以注入密码匹配器
@Bean
public CustomRealm customRealm(HashedCredentialsMatcher matcher, MemoryConstrainedCacheManager manager) {
CustomRealm realm = new CustomRealm();
realm.setCredentialsMatcher(matcher);//注入
realm.setCacheManager(manager);
return realm;
} //密码匹配器
@Bean
public HashedCredentialsMatcher matcher() {
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
matcher.setHashAlgorithmName("md5");
matcher.setHashIterations(2);
return matcher;
} //缓存
@Bean
public MemoryConstrainedCacheManager cacheManager() {
MemoryConstrainedCacheManager manager = new MemoryConstrainedCacheManager();
return manager;
} //使Shiro权限注解生效。让controller中添加的 对权限,或者角色 后台拦截的标签生效
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
} //对类进行aop代理。shiro的认证功能 属于在请求到达方法前进行的,切面编程。执行aop代理
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
creator.setProxyTargetClass(true);
return creator;
} //支持thyemleaf
@Bean
public ShiroDialect shiroDialect() {
ShiroDialect dialect = new ShiroDialect();
return dialect;
}
}
Shiro配置文件中需要的自定义域的编写,和Shiro第二斩的中一致
package com.bpms.shiro; import com.bpms.pojo.User;
import com.bpms.service.AuthService;
import com.bpms.service.UserService;
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.List;
import java.util.Set; public class CustomRealm extends AuthorizingRealm {
@Autowired
private UserService userService; @Autowired
private AuthService authService; @Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
User user = (User)principalCollection.getPrimaryPrincipal();
List<String> list = authService.findPerms(user.getUserId());
for(String str : list){
System.out.println("授权:"+str);
}
Set<String> perms= new HashSet<>(list);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setStringPermissions(perms);
return info;
} @Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String userName = (String) authenticationToken.getPrincipal();
User user = userService.findUserByName(userName);
if(user == null){
throw new UnknownAccountException("unkown account");
}
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),this.getClass().getName());
info.setCredentialsSalt(ByteSource.Util.bytes(user.getSalt()));
return info;
}
}
前端使用thymeleaf框架,使用shiro的标签
//在thymeleaf框架中,shiro:hasPermission="sys:user:save" 修饰的标签,如果当前用户的权限中没有 匹配 sys:user:save 字段的。就不会显示。后台的拦截,参考shiro第二斩
//就是配置的方式不同,在使用方面是一样的。
//在html标签中做一下声明,这个HTML页面为thymeleaf ,并且可以使用 shiro标签
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> <a shiro:hasPermission="sys:user:save" class="easyui-linkbutton" data-options="iconCls:'icon-add'" onclick="oepnAddDialog()">添加</a>
<a shiro:hasPermission="sys:user:update" class="easyui-linkbutton" data-options="iconCls:'icon-edit'" onclick="openModifyDialog()">修改</a>
<a shiro:hasPermission="sys:user:delete" class="easyui-linkbutton" data-options="iconCls:'icon-remove'" onclick="deleteUser()">删除</a>