shiro三连斩之第三斩,整合 springboot
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>