前言:html
Shiro是一個權限、會話管理的開源Java安全框架;Spring Boot集成Shiro後能夠方便的使用Session;java
工程概述:mysql
(工程結構圖)git
1、創建Spring Boot工程github
參照http://www.cnblogs.com/liangblog/p/5207855.html 創建一個SpringBoot工程;web
2、修改pom.xml,引入所需jar包spring
<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.ddd</groupId> <artifactId>programme</artifactId> <version>0.0.1</version> <packaging>jar</packaging> <name>programme</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.2.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-commons</artifactId> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jdbc-core</artifactId> <version>1.2.1.RELEASE</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>7.0</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-cas</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.jasig.cas.client</groupId> <artifactId>cas-client-core</artifactId> <version>3.4.1</version> </dependency> </dependencies> <!-- Package as an executable jar --> <build> <defaultGoal>compile</defaultGoal> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <!-- Add Spring repositories --> <!-- (you don't need this if you are using a .RELEASE version) --> <!-- <repositories> <repository> <id>spring-snapshots</id> <url>http://repo.spring.io/snapshot</url> <snapshots><enabled>true</enabled></snapshots> </repository> <repository> <id>spring-milestones</id> <url>http://repo.spring.io/milestone</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-snapshots</id> <url>http://repo.spring.io/snapshot</url> </pluginRepository> <pluginRepository> <id>spring-milestones</id> <url>http://repo.spring.io/milestone</url> </pluginRepository> </pluginRepositories> --> </project>
主要引入日誌、數據庫,shrio相關的jar包sql
3、添加配置文件和日誌文件數據庫
配置文件須要放到resource文件夾下(指向classpath),並取名aplication.properties,工程會自動查找到文件配置信息apache
配置文件:
displayname = pm server.port=8011 server.session.timeout=1000 server.tomcat.uri-encoding=UTF-8 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.max-idle=10 spring.datasource.max-wait=10000 spring.datasource.min-idle=5 spring.datasource.initial-size=5 logging.config=classpath:pm-logback.xml logging.path=log
日誌文件:
<configuration scan="true" scanPeriod="10 seconds"> <include resource="org/springframework/boot/logging/logback/base.xml" /> <!-- 日誌的級別:debug,info,warn,error --> <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>DEBUG</level> </filter> --> <File>${LOG_PATH}/info.log</File> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_PATH}/pm-info-%d{yyyyMMdd}.log.%i</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <maxHistory>2</maxHistory> </rollingPolicy> <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n </Pattern> </layout> </appender> <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter> <File>${LOG_PATH}/error.log</File> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_PATH}/pm-error-%d{yyyyMMdd}.log.%i </fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <maxHistory>2</maxHistory> </rollingPolicy> <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n </Pattern> </layout> </appender> <root level="INFO"> <appender-ref ref="INFO_FILE" /> <appender-ref ref="ERROR_FILE" /> </root> </configuration>
部署工程時能夠放到工程jar所在文件夾內,部署的工程會自動找到文件;
4、添加Shiro支持功能:
一、新建shiro配置類,Shiro的主要配置信息都在此文件內實現;
package com.ddd.program.config; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; import org.apache.shiro.cache.ehcache.EhCacheManager; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.session.SessionListener; import org.apache.shiro.session.mgt.SessionManager; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ShiroConfiguration { /** * ShiroFilterFactoryBean 處理攔截資源文件問題。 * 注意:單獨一個ShiroFilterFactoryBean配置是或報錯的 * 初始化ShiroFilterFactoryBean的時候須要注入:SecurityManager */ @Bean public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); // 必須設置 SecurityManager shiroFilterFactoryBean.setSecurityManager(securityManager); // 攔截器. Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>(); //filterChainDefinitionMap.put("/page/*", "authc"); // 配置退出過濾器,其中的具體的退出代碼Shiro已經替咱們實現了 //filterChainDefinitionMap.put("/security/logoff", "logout"); shiroFilterFactoryBean.setLoginUrl("/#/login"); // 未受權界面; shiroFilterFactoryBean.setUnauthorizedUrl("/403"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } @Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); MyRealm myRealm = new MyRealm(); securityManager.setRealm(myRealm); securityManager.setSessionManager(sessionManager()); securityManager.setCacheManager(ehCacheManager()); return securityManager; } @Bean public SessionManager sessionManager() { DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); Collection<SessionListener> listeners = new ArrayList<SessionListener>(); listeners.add(new MySessionListener()); sessionManager.setSessionListeners(listeners); return sessionManager; } @Bean public EhCacheManager ehCacheManager() { EhCacheManager ehCacheManager = new EhCacheManager(); //ehCacheManager.setCacheManagerConfigFile("classpath:encache.xml"); return ehCacheManager; } }
二、新建登陸驗證和Session監聽的類(上面的類所須要的兩個類)
登陸相關:
package com.ddd.program.config; 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.authc.UnknownAccountException; import org.apache.shiro.authc.UsernamePasswordToken; 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.slf4j.Logger; import org.slf4j.LoggerFactory; import com.cdv.nsite.program.model.AppUser; import com.cdv.nsite.program.services.impl.AppUserServiceImpl; public class MyRealm extends AuthorizingRealm { private final static Logger logger = LoggerFactory.getLogger(MyRealm.class); @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { logger.debug("登陸驗證後進行權限認證...."); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); return info; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { logger.debug("登陸操做進行登陸認證......"); UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken; AppUser user = SpringContextUtils.getBean(AppUserServiceImpl.class).getUserByName(token.getUsername()); if (user == null) { // 沒找到賬號 throw new UnknownAccountException( "沒有在本系統中找到對應的用戶信息。"); } //簡單驗證 SimpleAuthenticationInfo info = new SimpleAuthenticationInfo( user.getUsername(),user.getPassword(),getName()); return info; } }
Session相關:
package com.ddd.program.config; import java.util.concurrent.atomic.AtomicInteger; import org.apache.shiro.session.Session; import org.apache.shiro.session.SessionListener; import org.springframework.stereotype.Component; @Component public class MySessionListener implements SessionListener { private final AtomicInteger sessionCount = new AtomicInteger(0); @Override public void onStart(Session session) { sessionCount.incrementAndGet(); System.out.println("登陸+1=="+sessionCount.get()); } @Override public void onStop(Session session) { sessionCount.decrementAndGet(); System.out.println("登陸退出-1=="+sessionCount.get()); } @Override public void onExpiration(Session session) { sessionCount.decrementAndGet(); System.out.println("登陸過時-1=="+sessionCount.get()); } public int getSessionCount() { return sessionCount.get(); } }
三、添加靜態頁面:
在resource文件夾下新建static或public文件夾,工程會默認找static文件夾下的index.*,沒有在找public文件夾下的index.*;
四、新建登陸的接口和實現
完整代碼---> https://github.com/liangguang/springboot_18
結述:
以上代碼只是個例子,主要是得到登陸的Session用做其餘用途;
---------------------------------------------------添加熱部署支持-----------------------
<!-- 模板引擎 暫時不用 --> <!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> --> <!-- devtools能夠實現熱部署。devtools會監聽classpath下的文件變更,而且會當即重啓應用(發生在保存時機),注意:由於其採用的虛擬機機制,該項重啓是很快的 若是設置SpringApplication.setRegisterShutdownHook(false),則自動重啓將不起做用。 設置 spring.devtools.restart.enabled 屬性爲false,能夠關閉該特性。 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> <!-- optional=true,依賴不會傳遞,--> </dependency>
spring.devtools.restart.enabled = true
application.properties中添加配置項;