1. 程式人生 > >springMVC 整合shiro

springMVC 整合shiro

本人小白一枚,初次接觸shiro,花了兩天時間搞了一下可算能用了,當然雖然spring security功能更強大,但是太繁瑣了,不容易入門,並且shiro功能感覺也完全夠用了;各位童鞋可以參考別人的文章:http://jinnianshilongnian.iteye.com/blog/2049092

1、web.xml中增加spring-shiro.xml配置

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
    	classpath:spring-shiro.xml,
    	classpath:beans.xml
    </param-value>
  </context-param>

不多說,和別的spring配置檔案都在啟動時通過contextConfigLocation一塊載入

2、spring-shiro.xml內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<!-- ========================================================= Shiro Core 
		Components - Not Spring Specific ========================================================= -->
	<!-- Shiro's main business-tier object for web-enabled applications (use 
		DefaultSecurityManager instead when there is no web environment) -->
	<!-- 1.配置securityManager -->
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<property name="cacheManager" ref="cacheManager" />
		<!-- 單個realm的時候用下面的這個 -->
<!-- 		<property name="realm" ref="jdbcRealm" /> -->
		<!-- 多個的時候用下面這個 -->
		<property name="authenticator" ref="authenticator" />
	</bean>

	<!-- Let's use some enterprise caching support for better performance. You 
		can replace this with any enterprise caching framework implementation that 
		you like (Terracotta+Ehcache, Coherence, GigaSpaces, etc -->
	<!-- 2.配置CatchManager
		2.1 需要加入ehcatch 的jar包及配置檔案。
	 -->
	<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
		<!-- Set a net.sf.ehcache.CacheManager instance here if you already have 
			one. If not, a new one will be creaed with a default config: <property name="cacheManager" 
			ref="ehCacheManager"/> -->
		<!-- If you don't have a pre-built net.sf.ehcache.CacheManager instance 
			to inject, but you want a specific Ehcache configuration to be used, specify 
			that here. If you don't, a default will be used.: -->
		<property name="cacheManagerConfigFile" value="classpath:ehcache.xml" />
	</bean>
	
	<bean id="authenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
		<property name="realms">
			<list>
				<ref bean="jdbcRealm"/>
				<!--<ref bean="secondRealm"/>-->
</list> </property> <!-- FirstSuccessfulStrategy 只要有一個Realm驗證成功,只返回第一個Realm身份驗證成功的認證資訊,其他忽略; --> <!-- AtLeastOneSuccessfulStrategy 只要有一個返回成功即可,與FirstSuccessfulStrategy不同的是,他會返回所有Realm身份認證成功的認證資訊; --> <!-- AllSuccessfulStrategy 所有的Realm驗證成功才算成功,且返回所有Realm身份驗證成功的認證資訊,如果有一個失敗就失敗了 --> <!-- <property name="authenticationStrategy"> --> <!-- <bean class="org.apache.shiro.authc.pam.AllSuccessfulStrategy"></bean> --> <!-- </property> --> </bean> <!-- Used by the SecurityManager to access security data (users, roles, etc). Many other realm implementations can be used too (PropertiesRealm, LdapRealm, etc. --> <!-- 3. 配置realm --> <!-- 3.1 直接配置實現了Realm介面的bean --> <bean id="jdbcRealm" class="com.neusoft.core.shiro.ShiroRealm"> <property name="credentialsMatcher"> <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="MD5"></property> <property name="hashIterations" value="1024"></property> </bean> </property> <property name="userService" ref="userService" /> </bean> <bean id="userService" class="com.neusoft.demo.service.UserService" /> <!--<bean id="secondRealm" class="com.neusoft.core.shiro.SecondRealm"> <property name="credentialsMatcher"> <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="SHA1"></property> <property name="hashIterations" value="1024"></property> </bean> </property> </bean>--> <!-- ========================================================= Shiro Spring-specific integration ========================================================= --> <!-- Post processor that automatically invokes init() and destroy() methods for Spring-configured Shiro objects so you don't have to 1) specify an init-method and destroy-method attributes for every bean definition and 2) even know which Shiro objects require these methods to be called. --> <!-- 4.配置 LifecycleBeanPostProcessor。可以自動的呼叫配置在spring IOC容器中Shiro bean的生命週期方法--> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /> <!-- Enable Shiro Annotations for Spring-configured beans. Only run after the lifecycleBeanProcessor has run: --> <!-- 5.啟用IOC 容器中 使用Shiro的註解。但必須在配置了lifecycleBeanProcessor 之後才可以使用 <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor" /> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager" /> </bean>
--> <!-- Define the Shiro Filter here (as a FactoryBean) instead of directly in web.xml - web.xml uses the DelegatingFilterProxy to access this bean. This allows us to wire things with more control as well utilize nice Spring things such as PropertiesPlaceholderConfigurer and abstract beans or anything else we might need: --> <!-- 6. 配置 shiroFilter 6.1 id 必須和web.xml 檔案中配置的DelegatingFilterProxy的 <filter-name> 一致 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <!-- 登入頁面 --> <property name="loginUrl" value="/login.jsp" /> <!-- 登入成功後的頁面 --> <property name="successUrl" value="/index.jsp" /> <!-- 沒有許可權的頁面 --> <property name="unauthorizedUrl" value="/unauthorized.jsp" /> <!-- The 'filters' property is not necessary since any declared javax.servlet.Filter bean defined will be automatically acquired and available via its beanName in chain definitions, but you can perform overrides or parent/child consolidated configuration here if you like: --> <!-- <property name="filters"> <util:map> <entry key="aName" value-ref="someFilterPojo"/> </util:map> </property> --> <!-- 配置哪些頁面需要受保護 以及訪問這些頁面需要的許可權。 1.anno 可以被匿名訪問 2.auchc 必須認證即登入後才可以訪問的頁面 --> <property name="filterChainDefinitions"> <value> #靜態檔案 /bootstrap/** = anon /build/** = anon /dist/** = anon /documentation/** = anon /echart/** = anon /font-awesome-4.7.0/** = anon /ionicons-2.0.1/** = anon /js/** = anon /plugins/** = anon /resources/** = anon /**.css = anon /**.js = anon #登入頁面 /login.jsp = anon /shiro/login = anon # everything else requires authentication: /** = authc </value> </property> </bean> </beans>

第一個地方,本配置檔案是引用多個realm的例項,就跟spring的filter和struts的過濾器一樣,你可以校驗多層,我覺得一般系統一層就夠了,無非就是校驗使用者資訊,角色許可權資訊;

第二個地方,一定要註釋,不然啟用shiro的註解springmvc的註解就不好用了,提示can not autowird......

第三個地方,anon是指可以匿名登入,就是不用認證就可以呼叫,authc必須認證通過,session中儲存了你的登入資訊後你才可以配置角色許可權訪問別的頁面。

3、ehcache.xml

<ehcache>

    <!-- Sets the path to the directory where cache .data files are created.

         If the path is a Java System Property it is replaced by
         its value in the running VM.

         The following properties are translated:
         user.home - User's home directory
         user.dir - User's current working directory
         java.io.tmpdir - Default temp file path -->
    <diskStore path="java.io.tmpdir"/>
    
<!--     <cache name="authorizationCache" -->
<!--            eternal="false" -->
<!--            timeToIdleSeconds="3600" -->
<!--            timeToLiveSeconds="0" -->
<!--            overflowToDisk="false" -->
<!--            statistics="true"> -->
<!--     </cache> -->

<!--     <cache name="authenticationCache" -->
<!--            eternal="false" -->
<!--            timeToIdleSeconds="3600" -->
<!--            timeToLiveSeconds="0" -->
<!--            overflowToDisk="false" -->
<!--            statistics="true"> -->
<!--     </cache> -->

<!--     <cache name="shiro-activeSessionCache" -->
<!--            eternal="false" -->
<!--            timeToIdleSeconds="3600" -->
<!--            timeToLiveSeconds="0" -->
<!--            overflowToDisk="false" -->
<!--            statistics="true"> -->
<!--     </cache> -->

    <!--Default Cache configuration. These will applied to caches programmatically created through
        the CacheManager.

        The following attributes are required for defaultCache:

        maxInMemory       - Sets the maximum number of objects that will be created in memory
        eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element
                            is never expired.
        timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
                            if the element is not eternal. Idle time is now - last accessed time
        timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
                            if the element is not eternal. TTL is now - creation time
        overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache
                            has reached the maxInMemory limit.

        -->
    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
        />

    <!--Predefined caches.  Add your cache configuration settings here.
        If you do not have a configuration for your cache a WARNING will be issued when the
        CacheManager starts

        The following attributes are required for defaultCache:

        name              - Sets the name of the cache. This is used to identify the cache. It must be unique.
        maxInMemory       - Sets the maximum number of objects that will be created in memory
        eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element
                            is never expired.
        timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
                            if the element is not eternal. Idle time is now - last accessed time
        timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
                            if the element is not eternal. TTL is now - creation time
        overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache
                            has reached the maxInMemory limit.

        -->

    <!-- Sample cache named sampleCache1
        This cache contains a maximum in memory of 10000 elements, and will expire
        an element if it is idle for more than 5 minutes and lives for more than
        10 minutes.

        If there are more than 10000 elements it will overflow to the
        disk cache, which in this configuration will go to wherever java.io.tmp is
        defined on your system. On a standard Linux system this will be /tmp"
        -->
    <cache name="sampleCache1"
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="300"
        timeToLiveSeconds="600"
        overflowToDisk="true"
        />

    <!-- Sample cache named sampleCache2
        This cache contains 1000 elements. Elements will always be held in memory.
        They are not expired. -->
    <cache name="sampleCache2"
        maxElementsInMemory="1000"
        eternal="true"
        timeToIdleSeconds="0"
        timeToLiveSeconds="0"
        overflowToDisk="false"
        /> -->

    <!-- Place configuration for your caches following -->

</ehcache>
hibernate也有快取,因為用的是mybatis,shiro可以整合ehcache處理快取的問題,提高工作效率,喜歡研究的可以測試下用快取能夠提高訪問速度。紅色的地方只有是false的時候,下面設定的快取時間和快取間隔時間才能生效。

4、編寫頁面,我採用的ajax非同步提交,通過controller返回的資訊在登入首頁顯示認證返回的資訊,成功後才跳轉到index.jsp頁面

$.mpbAjax("/shiro/login",{
			type : "POST",
			async : false,
			data : {
				"_method"  : "POST",
				"userName" : $("#userName").val(),
				"password" : $("#password").val()
			},
			success : function(data){
				if($.isNotBlank(data)){					
					if(!data.success){
						do_notice(data.msg);
					}else{
						$.mpbJumpNotOpen("/index.jsp");
					}
				}
			}
		});
5、controller關鍵程式碼
UsernamePasswordToken token = new UsernamePasswordToken(
				user.getUserName(), user.getPassword());
		token.setRememberMe(true);

		// shiro登陸驗證
		try {
			SecurityUtils.getSubject().login(token);
		} catch (UnknownAccountException ex) {
			return "使用者不存在!";
		} catch (LockedAccountException ex) {
			return "使用者鎖定!";
	    } catch (IncorrectCredentialsException ex) {
			return "使用者名稱/密碼驗證失敗!";
		} catch (Exception ex) {
			ex.printStackTrace();
			return "內部異常!";
		}

6、呼叫.login方法時,自動進入註冊的過濾器ShiroRealm.java
package com.neusoft.core.shiro;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import com.neusoft.demo.entity.OrgUser;
import com.neusoft.demo.service.UserService;

public class ShiroRealm extends AuthenticatingRealm {
	
	@Autowired
	private UserService userService;
	public static final String SESSION_USER_KEY = "gray";

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken token) throws AuthenticationException {
		UsernamePasswordToken upToken = (UsernamePasswordToken) token;
		String username = upToken.getUsername();
		// 驗證使用者是否可以登入  
        OrgUser ui = userService.selectUsers(username);
		if (ui == null) {
			throw new UnknownAccountException("使用者不存在");

		} else if ("1".equals(ui.getDeleteFlag())) {
			throw new LockedAccountException("使用者被鎖定");
		}
		// 設定session  
        Session session = SecurityUtils.getSubject().getSession();  
        session.setAttribute(ShiroRealm.SESSION_USER_KEY, ui); 
		// 以下資訊從資料庫中獲取
		// 1 principal : 認證的實體資訊,可以是username,也可以是資料表對應的實體物件。
		Object principal = username;
		// 3 realmName : 當前realm 物件的name , 呼叫父類的 getName() 方法即可
		String realmName = getName();

		// 4.鹽值
		ByteSource credentialsSalt = ByteSource.Util.bytes(username);
		// 這個是不加鹽的 new SimpleAuthenticationInfo(principal, credentials,
		// realmName);
		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal,
				ui.getPassword(), credentialsSalt, realmName);

		return info;
	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}



	public static void main(String[] args) {
		String algorithmName = "MD5";
		Object credential = "123";
		Object salt = ByteSource.Util.bytes("admin");
		int hashIterations = 1024;
		Object result = new SimpleHash(algorithmName, credential, salt,
				hashIterations);
		System.out.println(result);
	}

}
只寫了個校驗使用者資訊,還有個重寫的方法校驗許可權和角色的,自行補腦

一定要注意,shiro過濾器在springmvc之前過濾,autowired不起作用,需要你增加get set方法注入,丟擲的異常在controller捕獲返回到前臺;

框架搭建好了,後期增加驗證碼之類的就好加了

因為小白,也是網上各種方案,如有侵權,請通知刪帖。

相關推薦

springmvc整合shiro許可權控制

一、什麼是Shiro   Apache Shiro是一個強大易用的Java安全框架,提供了認證、授權、加密和會話管理等功能:  認證 - 使用者身份識別,常被稱為使用者“登入”; 授權 - 訪問控制; 密碼加密 - 保護或隱藏資料防止被偷窺; 會話

SpringMVC整合Shiro和Swagger產生的路徑過濾問題

SSM整合Swagger和Shiro時出現的問題: 一:啟動swagger報錯Unable to infer base url. This is common when using dynamic servlet解決方法 在shiro配置檔案的自定義的過濾鏈中加上一下程式碼: <!-- swa

springMvc整合shiro xml配置

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3

SpringMVC整合shiro許可權(附原始碼)

springMVC框架這裡就不多說了,下面是在springMVC框架上面直接整合shiro程式碼步驟 下面是我專案結構: 1、web.xml新增Shiro Filter <filter> <filter-nam

springmvc整合shiro後,session、request姓汪還是姓蔣?

1. 疑問 我們在專案中使用了spring mvc作為MVC框架,shiro作為許可權控制框架,在使用過程中慢慢地產生了下面幾個疑惑,本篇文章將會帶著疑問慢慢地解析shiro原始碼,從而解開心裡面的那點小糾糾。 (1)在spring controller中,request有

SpringMVC整合Shiro

這裡用的是SpringMVC-3.2.4和Shiro-1.2.2,示例程式碼如下 首先是web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="htt

springMVC整合shiro與cas實現SSO單點登入

一、前言 Apache Shiro與Spring Security一樣是Java的一個安全框架。那為什麼與Spring整合卻用Shiro?其實我個人是認為Spring Security太過於笨重,要寫太多的過濾器,Shiro的配置簡單這就是我選擇的理由,何況Spring官方

SpringBoot/SpringMVC整合Shiro:實現登入與註冊(MD5加鹽加密)

本文轉載於:https://blog.csdn.net/Colton_Null/article/details/78992836 ----------------------------------超級囂張的分割線---------------------------------------

springMVC 整合shiro

本人小白一枚,初次接觸shiro,花了兩天時間搞了一下可算能用了,當然雖然spring security功能更強大,但是太繁瑣了,不容易入門,並且shiro功能感覺也完全夠用了;各位童鞋可以參考別人的文章:http://jinnianshilongnian.iteye.co

Springmvc整合Shiro實現許可權管理

package com.authc.utils; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.util.Rand

SpringMVC整合Shiro許可權框架

最近在學習Shiro,首先非常感謝開濤大神的《跟我學Shiro》系列,在我學習的過程中發揮了很大的指導作用。學習一個新的東西首先就是做一個demo,多看不如多敲,只有在實踐中才能發現自己的欠缺,下面記錄下來我整合shiro的過程。如果有不足之處,還望各位看官多多指出。 一、

Shiro】- springmvc 整合 shiro

浪費了“黃金五年”的Java程式設計師,還有救嗎? >>>   

java框架整合Springmvc+mybatis+shiro+lucene+rest+webser

獲取 roi 架構師 tpc maven項目 組管理 col 公司 log 框架整合: Springmvc + Mybatis + Shiro(權限) + REST(服務) + WebService(服務) + JMS(消息) + Lucene(搜搜引擎) + Quartz

shirospringmvc整合

飛哥路徑 1.1shiro與springweb專案的整合 shiro 與 springweb 基於 url攔截,整合注意兩點 : 1、shiro 與 spring整合 2、加入shiro對web應用的支援 1.2 加入shiro的jar包 shiro-sprin

maven專案中SSM+Shiro整合配置中,在有SpringMVC+MyBatis配置下整合shiro的配置步驟

      最近在做SSM(SpringMVC+Shiro+MyBatis)整合的一個專案,對於shiro的配置不是特別熟練,於是想要寫下來,加深一下印象。在有SpringMVC+MyBatis配置的基礎上整合shiro:       首先進入shiro的官方網站(http

springMVCShiro框架整合使用簡單示例

一、目錄結構 首先是目錄結構如圖: 二、pom.xml檔案 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instan

【spring系列】- Springmvc整合apache shiro安全框架

shiro: shiro是apache開源的安全框架,可以方便用來處理使用者資訊認證、使用者授權控制、資訊加密等功能,因為其小巧而功能強大在很多SSM架構的web應用系統中被廣泛採用,shiro的架構設計個人覺得結構很清晰,對於想向更高層次發展的開發人員來說,

spring+springmvc+mybatis+shiro+ehcache整合demo

實際使用shiro的時候大部分都是和spring等框架結合使用,主要就是配置web.xml將shiro的filter和spring容器bean的filter關聯起來,生命週期由servlet容器來控制,然後配置shiro的spring的xml檔案,其中主要配置s

SpringMVCShiro的最簡單整合(不包含許可權管理)

1.Maven 引入依賴 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifa

shiro springmvc整合第一步

shiro 做為一個輕量級的安全認證,許可權框架,與spring有很好的相容性 具體shiro是什麼這裡不在多說 直接上程式碼 <filter> <filter-name>shiroFilter</filter-name&