spring-shiro(三)-- spring boot + mybatis +shrio+spring mvc
阿新 • • 發佈:2018-12-03
前面對shiro記性了一些邏輯的操作,和具體的程式碼片段的操作,現在將我寫的一個小的案例,總結一下。總結完明天就上班了。
本案例使用的是spring boot + spring mvc +mybatis
專案的結構
首先對pom檔案進行操作
<?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> <groupId>com.sgqing</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>demo</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <!--用於進行資料連線的--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!--spring提供的模板檔案--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>net.sourceforge.nekohtml</groupId> <artifactId>nekohtml</artifactId> <version>1.9.22</version> </dependency> <!--包含spring mvc等web操作--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--shiro包--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency> <!--用的是mysql的資料庫--> <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> <!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency>--> <!--spring boot--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.0</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> </configuration> </plugin> </plugins> </build> </project>
下面對application.yml進行配置
<!--對資料庫進行配置--> spring: datasource: url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true username: root password: root driver-class-name: com.mysql.jdbc.Driver <!--對tomcat進行設定啟動的埠--> server: port: 9992 <!--對mybatis進行設定--> mybatis: typeAliasesPackage: com.sgqing.demo.dao mapperLocations: classpath:mapper/*.xml
下面對shiro的核心兩個類進行操作,這兩個類分別代表的是認證和授權
package com.sgqing.demo.comfig; import com.sgqing.demo.entity.SysPermission; import com.sgqing.demo.entity.SysRole; import com.sgqing.demo.entity.UserInfo; import com.sgqing.demo.sevice.UserInfoService; import org.apache.coyote.http2.ByteUtil; 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.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import org.springframework.beans.factory.annotation.Autowired; public class MyShiroRealm extends AuthorizingRealm { @Autowired private UserInfoService userInfoService; /** * 進行授權 * * @param principalCollection * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { // 進行獲取使用者資訊 UserInfo info = (UserInfo) principalCollection.getPrimaryPrincipal(); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); //對使用者和角色進行分別的獲取,然後新增到SimpleAuthorizationInfo返回 for (SysRole role : info.getRoleList()) { // 將角色放到SimpleAuthorizationInfo中 authorizationInfo.addRole(role.getRole()); for (SysPermission permission : role.getPermissions()) { authorizationInfo.addStringPermission(permission.getPermission()); } } return authorizationInfo; } /** * 進行認證 * * @param authenticationToken * @return * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { // 首先獲取頁面傳遞過來的資料 -- 使用者名稱 String name = (String) authenticationToken.getPrincipal(); System.out.println(authenticationToken.getCredentials()); UserInfo byUsername = userInfoService.findByUsername(name); System.out.println(" ByteSource.Util.bytes(byUsername.getCredentialsSalt()):" + ByteSource.Util.bytes(byUsername.getCredentialsSalt())); // ByteSource.Util.bytes(byUsername.getCredentialsSalt()), 對密碼進行加密操作,該引數是 鹽 md5 SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( name, byUsername.getPassword(), ByteSource.Util.bytes(byUsername.getCredentialsSalt()), getName() ); return authenticationInfo; } }
使用類的配置
package com.sgqing.demo.comfig;
import com.sgqing.demo.Except.MyExceptionResolver;
import org.aopalliance.aop.Advice;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
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 org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* Shiro的配置
*/
@Configuration
public class ShiroConfig {
/**
* 該bena是當用戶訪問某個許可權的時候,如果沒有指定的許可權進行跳轉的頁面
*
* @return
*/
@Bean
public MyExceptionResolver myExceptionResolver() {
MyExceptionResolver resolver = new MyExceptionResolver();
return resolver;
}
/**
* 因為在密碼返回的時候,我們加了鹽,所以需要進行解密
* @return
*/
@Bean
public HashedCredentialsMatcher credentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");
hashedCredentialsMatcher.setHashIterations(2);//相當於md5(md5(""))
return hashedCredentialsMatcher;
}
@Bean
public MyShiroRealm myShiroRealm() {
MyShiroRealm myShiroRealm = new MyShiroRealm();
// 因為在使用的時候設定了md5進行密碼的加密,所以需要進行解密
myShiroRealm.setCredentialsMatcher(credentialsMatcher());
return myShiroRealm;
}
//設定SecurityManager
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager defaultWebSecurityManager =
new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(myShiroRealm());
return defaultWebSecurityManager;
}
//首先設定shiro的工廠類
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 進行攔截器的設定
Map<String, String> filterMap = new HashMap<>();
filterMap.put("/static/**", "anon");
filterMap.put("/logout", "logout");
filterMap.put("/**", "authc");
shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setSuccessUrl("/index");
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
return shiroFilterFactoryBean;
}
// 開啟shiro的註解 開啟代理
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
/**
* 異常處理
*
* @return
*/
@Bean
public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {
SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
Properties properties = new Properties();
properties.setProperty("DatabaseException", "databaseError");//資料庫異常處理
properties.setProperty("UnauthorizedException", "403");
resolver.setExceptionMappings(properties);
resolver.setDefaultErrorView("error"); // No default
resolver.setExceptionAttribute("ex"); // Default is "exception"
return resolver;
}
}
配置的當沒有許可權的時候,跳轉的頁面
package com.sgqing.demo.Except;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 用於設定當沒有訪問許可權的時候,用於跳轉指定的頁面,用到ModelAndView來進行設定頁面的跳轉
*/
public class MyExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception ex) {
// TODO Auto-generated method stub
System.out.println("==============異常開始=============");
//如果是shiro無權操作,因為shiro 在操作auno等一部分不進行轉發至無許可權url
if (ex instanceof UnauthorizedException) {
ModelAndView mv = new ModelAndView("/403");
return mv;
}
ex.printStackTrace();
System.out.println("==============異常結束=============");
ModelAndView mv = new ModelAndView("/403");
return mv;
}
}
這是程式碼中一些重要的程式碼片段,如果有需要程式碼的,可以下載我們的案例,在案例中沒有提供資料庫的檢表語句,需要自己手動建立庫和表:https://gitee.com/sgqing/spring-boot--springmvc--shiro.git