<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.4.0</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-ehcache</artifactId> <version>1.4.0</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency>
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <display-name>Archetype Created Web Application</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <--! DelegatingFilterProxy 做用是自動到 Spring容器查找名字爲 shiroFilter(filter-name) 的 bean 並把全部 Filter的操做委託給它 --> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>encoding</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
注:DelegatingFilterProxy的filter-name要和spring-shiro中的shiroFilterFactoryBean中的id相同,不然報錯,或者使用如下方法(在DelegatingFilterProxy中加入<init-param>)java
<filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>targetBeanName</param-name> <param-value>name</param-value> </init-param> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
此時spring-shiro中的shiroFilterFactoryBean中的id和param-value相同,即nameweb
<?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"> <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager"></bean> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="cacheManager" ref="cacheManager"></property> <property name="authenticator" ref="authenticator"></property> <property name="rememberMeManager" ref="rememberManager"></property> <property name="realms"> <list> <ref bean="firstRealm"></ref> <ref bean="secondRealm"></ref> </list> </property> </bean> <!--配置realm認證策略--> <bean id="authenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator"> <property name="authenticationStrategy"> <!-- <bean class="org.apache.shiro.authc.pam.FirstSuccessfulStrategy"></bean>--> <bean class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"></bean> <!--<bean class="org.apache.shiro.authc.pam.AllSuccessfulStrategy"></bean>--> </property> </bean> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"></property> <property name="loginUrl" value="/login"></property> <property name="successUrl" value="/success"></property> <property name="unauthorizedUrl" value="/error"></property> <!--filterChainDefinitionMap和filterChainDefinitions只能存在一個--> <property name="filterChainDefinitionMap" ref="filterChainDefinitionMap"></property> <!-- <property name="filterChainDefinitions"> <value> /logout=logout /doLogin=anon /admin=roles[admin] /user=roles[user] /vip=roles[vip] /**=authc </value> </property>--> </bean> <!--設置cookie--> <bean id="rememberCookie" class="org.apache.shiro.web.servlet.SimpleCookie"> <constructor-arg value="jizhuwo"></constructor-arg> <property name="httpOnly" value="true"></property> <property name="maxAge" value="100"></property> </bean> <!--記住我配置--> <bean id="rememberManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager"> <property name="cookie" ref="rememberCookie"></property> </bean> <bean id="firstRealm" class="com.shiro.realms.FirstRealm"> <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> </bean> <bean id="secondRealm" class="com.shiro.realms.SecondRealm"> <property name="credentialsMatcher"> <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="SHA1"></property> <property name="hashIterations" value="1024"/> </bean> </property> </bean> <!--註解生效--> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"> <property name="proxyTargetClass" value="true"/> </bean> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"/> </bean> <!--buildFilterChainDefinitionMap實例工廠--> <bean id="filterChainDefinitionMapFactory" class="com.shiro.factory.FilterChainDefinitionMapFactory"></bean> <bean id="filterChainDefinitionMap" factory-bean="filterChainDefinitionMapFactory" factory-method="buildFilterChainDefinitionMap"></bean> </beans>
@RequestMapping("/doLogin") public String doLogin(String username, String password) { System.out.println("doLogin............."); Subject subject= SecurityUtils.getSubject(); if(!subject.isAuthenticated()){ UsernamePasswordToken token=new UsernamePasswordToken(username,password,true); try { subject.login(token); } catch (AuthenticationException e) { System.out.println("認證失敗。"); } } return "redirect:success"; }
public class FirstRealm extends AuthorizingRealm{ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { UsernamePasswordToken uptoken=(UsernamePasswordToken) token; String username = uptoken.getUsername(); String credentials=null; if("zhangsan".equals(username)){ credentials="2a0d136ceacafe198ea64ac09daaf1b6"; }else if("lisi".equals(username)){ credentials = "8c702ae443795331c91cfab48f3f3833"; } ByteSource byteSource=new ByteSource.Util().bytes(username); AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, credentials, byteSource, getName()); // new SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName); return authenticationInfo; } public static void main(String[] args) { String hashAlgorithmName = "MD5"; Object credentials = "123456"; Object salt = ByteSource.Util.bytes("lisi");; int hashIterations = 1024; Object result = new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations); System.out.println(result); } @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("FirstRealm..2222........."); Object primaryPrincipal = principals.getPrimaryPrincipal(); Set<String> roles = new HashSet<>(); if("zhangsan".equals(primaryPrincipal)){ roles.add("user"); roles.add("vip"); }else if("abc".equals(primaryPrincipal)){ roles.add("user"); } SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); simpleAuthorizationInfo.addRoles(roles); return simpleAuthorizationInfo; } }
public class SecondRealm extends AuthorizingRealm{ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { UsernamePasswordToken uptoken=(UsernamePasswordToken) token; String username = uptoken.getUsername(); String credentials=null; if("abc".equals(username)){ credentials="31420b87dd2e42f39d7dc7bdc3a7ee12e4053de8"; }else if("qwe".equals(username)){ credentials = "466c492b84308fb956c6d1acf4301743cbc19037"; } ByteSource byteSource=new ByteSource.Util().bytes(username); AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, credentials, byteSource, getName()); // new SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName); return authenticationInfo; } public static void main(String[] args) { String hashAlgorithmName = "SHA1"; Object credentials = "123"; Object salt = ByteSource.Util.bytes("qwe");; int hashIterations = 1024; Object result = new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations); System.out.println(result); } @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("secondRealm...。。。.........."); Object primaryPrincipal = principals.getPrimaryPrincipal(); Set<String> roles = new HashSet<>(); if("zhangsan".equals(primaryPrincipal)){ roles.add("admin"); }else if("abc".equals(primaryPrincipal)){ roles.add("admin"); } SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(roles); return simpleAuthorizationInfo; } }
realm的認證策略:算法
public class FilterChainDefinitionMapFactory { public LinkedHashMap<String,String> buildFilterChainDefinitionMap(){ LinkedHashMap<String, String> map = new LinkedHashMap<>(); map.put("/doLogin", "anon"); map.put("/logout", "logout"); map.put("/admin", "authc,roles[admin]"); map.put("/user", "roles[user]"); map.put("/test", "user"); map.put("/vip", "user"); map.put("/success", "user"); map.put("/**", "authc"); return map; } }
rememberMe功能若是要認證才能夠操做的的除了加權限還要加authc 例如:map.put("/admin", "authc,roles[admin]");不然能夠經過記住我直接訪問/adminspring
@RequiresRoles(value = {"admin","vip"},logical = Logical.AND) @RequestMapping(value = {"/testAnnotation2"}) public String testAnnotation2(){ System.out.println("testAnnotation2222。"); return "success"; }
若是要在Controller層使用註解,要在springmvc.xml中添加apache
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"> <property name="proxyTargetClass" value="true" /> </bean> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"/> </bean>
若是要在service中使用,在spring-shiro中便可緩存
httpsession和SecurityUtils.getSubject().getSession()能夠互相改,能夠在service調用sessioncookie
session也有會話監聽器用於監聽會話建立、過時及中止事件onStart,onStop,onexpirationsession
shiro登陸驗證碼mvc