下面我通過一個web的maven項目來講解如何將shiro整合ssm框架,具體結構如下圖

一、引入依賴的jar包
<?xml version="1.0" encoding="UTF-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <!-- $Id: pom.xml 642118 2008-03-28 08:04:16Z reinhard $ --> <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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <packaging>war</packaging> <name>shiro-web</name> <groupId>com.imooc</groupId> <artifactId>shiro-web</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</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-web</artifactId> <version>1.4.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.12</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>compile</scope> </dependency> </dependencies> </project>
二、配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <!--shiro攔截器--> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--spring配置監聽器--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--spring配置文件路徑,啟動時就加載--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring.xml</param-value> </context-param> <!--springmvc的控制器--> <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.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
三、spring整合mybatis的配置文件,springmvc配置文件,mybatis配置文件,mabatis映射文件
1、spring整合mybatis的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--掃描Service注解-->
<context:component-scan base-package="com.imooc.service"/>
<!--shiro的web過濾器-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="login.html"/>
<property name="unauthorizedUrl" value="403.html"/>
<property name="filterChainDefinitions">
<value>
<!--anon表示無需驗證,authc表示需要驗證-->
/login.html = anon
/sublogin = anon
/* = authc
</value>
</property>
</bean>
<!--安全管理器-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="realm"/>
</bean>
<!--自定義realm-->
<bean id="realm" class="com.imooc.realm.CustomRealm">
<property name="credentialsMatcher" ref="hashedCredentialsMatcher"/>
</bean>
<!--憑證匹配器-->
<bean id="hashedCredentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="md5"/>
<property name="hashIterations" value="1"/>
</bean>
<!--數據庫連接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="jdbc:mysql://localhost:3306/realm_test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<!--sqlSessionFactory的形成,可看作spring和mybatis整合的重要一步-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="typeAliasesPackage" value="com.imooc.entity"/>
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>
<!--自動掃描dao層,將對應的Mapper接口生成代理注入到Spring-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="com.imooc.dao"/>
</bean>
</beans>
2、springmvc配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--掃描Controller注解的控制器--> <context:component-scan base-package="com.imooc.controller"/> <!--設置配置方案--> <mvc:annotation-driven/> <!--找不到對應的Controller就掃描靜態資源--> <mvc:resources mapping="/*" location="/"/> </beans>
3、mybatis配置文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!--只是idea生成模板的默認配置,可忽略--> <settings> <!-- Globally enables or disables any caches configured in any mapper under this configuration --> <setting name="cacheEnabled" value="true"/> <!-- Sets the number of seconds the driver will wait for a response from the database --> <setting name="defaultStatementTimeout" value="3000"/> <!-- Enables automatic mapping from classic database column names A_COLUMN to camel case classic Java property names aColumn --> <setting name="mapUnderscoreToCamelCase" value="true"/> <!-- Allows JDBC support for generated keys. A compatible driver is required. This setting forces generated keys to be used if set to true, as some drivers deny compatibility but still work --> <setting name="useGeneratedKeys" value="true"/> </settings> <!-- Continue going here --> </configuration>
4、mabatis映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.imooc.dao.UserDao">
<select id="getPasswordByName" parameterType="String" resultType="String">
select password from users where username=#{username}
</select>
<select id="getRoles" parameterType="String" resultType="String">
select role_name from user_roles where username=#{username}
</select>
</mapper>
四、代碼
1、Controller層
package com.imooc.controller; import com.imooc.entity.User; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class UserController { @RequestMapping(value="/sublogin",method= RequestMethod.POST,produces = "application/json;charset=utf-8") @ResponseBody public String userLogin(User user){ UsernamePasswordToken token=new UsernamePasswordToken(user.getName(),user.getPassword()); Subject subject= SecurityUtils.getSubject(); try{ subject.login(token); }catch (Exception e){ return e.getMessage(); } if(subject.hasRole("admin")){ return "權限正確"; } return "權限失敗"; } }
2、Service層
package com.imooc.service; import com.imooc.dao.UserDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Set; @Service public class UserService { @Autowired private UserDao userDao; public Set<String> getRoles(String name) { Set<String> set=userDao.getRoles(name); return set; } public String getPasswordByName(String name) { String password=userDao.getPasswordByName(name); return password; } }
3、自定義的Realm
package com.imooc.realm; import com.imooc.dao.UserDao; import com.imooc.service.UserService; 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.credential.HashedCredentialsMatcher; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.crypto.hash.Md5Hash; 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 javax.annotation.Resource; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Set; public class CustomRealm extends AuthorizingRealm { @Autowired private UserService userService; //判斷是否有角色權限 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { String name = (String) principalCollection.getPrimaryPrincipal(); Set<String> roles = getRoleByName(name); SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); simpleAuthorizationInfo.setRoles(roles); return simpleAuthorizationInfo; } private Set<String> getRoleByName(String name) { Set<String> set = userService.getRoles(name); return set; } //判斷是否有登陸權限 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { String name = (String) authenticationToken.getPrincipal(); String password = getPassword(name); if (password == null) { return null; } SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, password, "abc"); simpleAuthenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(name)); return simpleAuthenticationInfo; } private String getPassword(String name) { String password=userService.getPasswordByName(name); return password; }
4、Dao層
package com.imooc.dao; import java.util.ArrayList; import java.util.Set; public interface UserDao { public String getPasswordByName(String name); public Set<String> getRoles(String name); }
5、界面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陸</title>
</head>
<body>
<form action="sublogin" method="post">
用戶名:<input type="text" name="name"/>
密碼: <input type="password" name="password"/>
<input type="submit" value="登陸">
</form>
</body>
</html>
啟動成功后如下:


該demo的地址:https://github.com/professorxin/Java_Demo/tree/master/shiro-web,里面有sql腳本了。
