将Shiro整到SSM中(基于maven)
--------------------------------------------------------------------------------------------------------------------
Shiro整到Spring中后,我们自定义的realm啊、securityManager等都会交给spring去管理了,包括我们需要指定哪些url需要做什么样的验证,都是交给spring,也就是说,完全可以摆脱原来的那个.ini配置文件了,Shiro部分参考了它的官方文档:http://shiro.apache.org/spring.html
1.
2.配置文件
2.1 pom.xml
- <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>
- <groupId>com.demo</groupId>
- <artifactId>shiro</artifactId>
- <packaging>war</packaging>
- <version>1.0-SNAPSHOT</version>
- <name>shiro Maven Webapp</name>
- <url>http://maven.apache.org</url>
- <dependencies>
- <!-- shiro核心包 -->
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-core</artifactId>
- <version>1.2.5</version>
- </dependency>
- <!-- 添加shiro web支持 -->
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-web</artifactId>
- <version>1.2.5</version>
- </dependency>
- <!-- 添加shiro spring支持 -->
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-spring</artifactId>
- <version>1.2.5</version>
- </dependency>
- <!-- 添加sevlet支持 -->
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>javax.servlet-api</artifactId>
- <version>3.1.0</version>
- </dependency>
- <!-- 添加jsp支持 -->
- <dependency>
- <groupId>javax.servlet.jsp</groupId>
- <artifactId>javax.servlet.jsp-api</artifactId>
- <version>2.3.1</version>
- </dependency>
- <!-- 添加jstl支持 -->
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>jstl</artifactId>
- <version>1.2</version>
- </dependency>
- <!-- 添加log4j日志 -->
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>1.2.17</version>
- </dependency>
- <dependency>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- <version>1.2</version>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>1.7.21</version>
- </dependency>
- <!-- 添加spring支持 -->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-core</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-beans</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context-support</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-web</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-tx</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-aop</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-aspects</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <!-- 添加mybatis支持 -->
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis</artifactId>
- <version>3.4.0</version>
- </dependency>
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis-spring</artifactId>
- <version>1.3.0</version>
- </dependency>
- <dependency>
- <groupId>com.oracle</groupId>
- <artifactId>ojdbc14</artifactId>
- <version>11.1.0.6.0</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.12</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
- <build>
- <finalName>shiro</finalName>
- </build>
- </project>
- <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>
- <groupId>com.demo</groupId>
- <artifactId>shiro</artifactId>
- <packaging>war</packaging>
- <version>1.0-SNAPSHOT</version>
- <name>shiro Maven Webapp</name>
- <url>http://maven.apache.org</url>
- <dependencies>
- <!-- shiro核心包 -->
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-core</artifactId>
- <version>1.2.5</version>
- </dependency>
- <!-- 添加shiro web支持 -->
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-web</artifactId>
- <version>1.2.5</version>
- </dependency>
- <!-- 添加shiro spring支持 -->
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-spring</artifactId>
- <version>1.2.5</version>
- </dependency>
- <!-- 添加sevlet支持 -->
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>javax.servlet-api</artifactId>
- <version>3.1.0</version>
- </dependency>
- <!-- 添加jsp支持 -->
- <dependency>
- <groupId>javax.servlet.jsp</groupId>
- <artifactId>javax.servlet.jsp-api</artifactId>
- <version>2.3.1</version>
- </dependency>
- <!-- 添加jstl支持 -->
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>jstl</artifactId>
- <version>1.2</version>
- </dependency>
- <!-- 添加log4j日志 -->
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>1.2.17</version>
- </dependency>
- <dependency>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- <version>1.2</version>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>1.7.21</version>
- </dependency>
- <!-- 添加spring支持 -->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-core</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-beans</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context-support</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-web</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-tx</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-aop</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-aspects</artifactId>
- <version>4.3.0.RELEASE</version>
- </dependency>
- <!-- 添加mybatis支持 -->
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis</artifactId>
- <version>3.4.0</version>
- </dependency>
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis-spring</artifactId>
- <version>1.3.0</version>
- </dependency>
- <dependency>
- <groupId>com.oracle</groupId>
- <artifactId>ojdbc14</artifactId>
- <version>11.1.0.6.0</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.12</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
- <build>
- <finalName>shiro</finalName>
- </build>
- </project>
- log4j.rootLogger=DEBUG, Console
- #Console
- log4j.appender.Console=org.apache.log4j.ConsoleAppender
- log4j.appender.Console.layout=org.apache.log4j.PatternLayout
- log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
- log4j.logger.java.sql.ResultSet=INFO
- log4j.logger.org.apache=INFO
- log4j.logger.java.sql.Connection=DEBUG
- log4j.logger.java.sql.Statement=DEBUG
- log4j.logger.java.sql.PreparedStatement=DEBUG
2.3 web.xml(有待修改)
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
- <display-name>ShiroSpring</display-name>
- <welcome-file-list>
- <welcome-file>index.jsp</welcome-file>
- </welcome-file-list>
- <!-- spring监听器 -->
- <listener>
- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
- </listener>
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath:applicationContext.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:spring-mvc.xml</param-value>
- </init-param>
- </servlet>
- <servlet-mapping>
- <servlet-name>springMVC</servlet-name>
- <url-pattern>*.do</url-pattern>
- </servlet-mapping>
- <!-- 添加shiro过滤器 -->
- <filter>
- <filter-name>shiroFilter</filter-name>
- <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
- <init-param>
- <!-- 该值缺省为false,表示声明周期由SpringApplicationContext管理,设置为true表示ServletContainer管理 -->
- <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>encodingFilter</filter-name>
- <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
- <async-supported>true</async-supported>
- <init-param>
- <param-name>encoding</param-name>
- <param-value>UTF-8</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>encodingFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
- </web-app>
- <?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:p="http://www.springframework.org/schema/p"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:jee="http://www.springframework.org/schema/jee"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
- http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
- <!-- 自动扫描 -->
- <context:component-scan base-package="demo.service" />
- <!--配置数据源-->
- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
- <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
- <property name="url" value="jdbc:oracle:thin:@192.168.6.34:1521:orcl"/>
- <property name="username" value="scott"/>
- <property name="password" value="tiger"/>
- </bean>
- <!--配置mybatis的sqlSessionFactory-->
- <bean name="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
- <property name="dataSource" ref="dataSource"/>
- <!-- 自动扫描mappers.xml文件 -->
- <property name="mapperLocations" value="classpath:demo/mappers/*.xml "/>
- <!--mybatis配置文件-->
- <property name="configLocation" value="classpath:mybatis-config.xml"/>
- </bean>
- <!--DAO接口所在包名,spring 会自动查找其下的-->
- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
- <property name="basePackage" value="demo.dao"/>
- <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
- </bean>
- <!--自定义Realm-->
- <bean id="myRealm" class="demo.realm.MyRealm"/>
- <!--安全管理-->
- <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- <property name="realm" ref="myRealm"></property>
- </bean>
- <!--shiro 过滤器-->
- <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
- <!-- Shiro过滤器的核心安全接口,这个属性是必须的-->
- <property name="securityManager" ref="securityManager"/>
- <!--身份认证失败,则跳转到登录页面的配置-->
- <property name="loginUrl" value="/login.jsp"/>
- <!--权限认证失败,则跳转到指定页面-->
- <property name="unauthorizedUrl" value="/unauthorized.jsp"/>
- <!-- Shiro连接约束配置,即过滤链的定义-->
- <property name="filterChainDefinitions">
- <value>
- /login=anon
- /user/admin*=autho
- /user/student*/**=roles[teacher]
- /user/teacher*/**=perms["user:create"]
- </value>
- </property>
- </bean>
- </beans>
3.整合Mybatis
3.1全局配置文件
首先配置一个mybatis的全局配置文件mybatis-config.xml,因为数据源都交给spring管理了,所以全局配置文件就比较清晰了。
mybatis-config.xml
- <?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>
- <!-- 别名 -->
- <typeAliases>
- <package name="demo.entity"/>
- </typeAliases>
- </configuration>
UserMapper.xml
- <?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>
- <select id="getByUsername" parameterType="String" resultType="user">
- select * from tb_user where username=#{username}
- </select>
- <select id="getRoles" parameterType="String" resultType="String">
- select r.rolename from t_user u,t_role r where u.role_id=r.id and u.username=#{username}
- </select>
- <select id="getPermissions" parameterType="String" resultType="String">
- select p.permissionname from t_user u,t_role r,t_permission p where u.role_id=r.id and p.role_id=r.id
- and u.username=#{username}
- </select>
- </mapper>
- public interface UserDao {
- public User getByUsername(String username);
- public Set<String> getRoles(String username);
- public Set<String> getPermissions(String username);
- }
3.4 entity类
这里写个简单的User类
- public class User {
- private Integer id;
- private String username;
- private String password;
- //get set方法省略
- }
接口UserService.java
- public interface UserService {
- public User getByUsername(String username);
- public Set<String> getRoles(String username);
- public Set<String> getPermissions(String username);
- }
UserServiceImpl.java
- @Service("userService")
- public class UserServiceImpl implements UserService {
- @Resource
- private UserDao userDao;
- public User getByUsername(String username){
- return userDao.getByUsername(username);
- }
- public Set<String> getRoles(String username){
- return userDao.getRoles(username);
- }
- public Set<String> getPermissions(String username){
- return userDao.getPermissions(username);
- }
- }
4 整合SpringMVC
4.1配置文件
spring-mvc.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"
- xmlns:p="http://www.springframework.org/schema/p"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:jee="http://www.springframework.org/schema/jee"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
- http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
- <!-- 使用注解的包,包括子集-->
- <context:component-scan base-package="demo.controller"/>
- <!--视图解析器-->
- <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="prefix" value="/"></property>
- <property name="suffix" value=".jsp"></property>
- </bean>
- </beans>
4.2 Controller
UserController.java
- package demo.controller;
- import demo.entity.User;
- import org.apache.shiro.SecurityUtils;
- import org.apache.shiro.authc.UsernamePasswordToken;
- import org.apache.shiro.subject.Subject;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.stereotype.Controller;
- import javax.servlet.http.HttpServletRequest;
- @Controller
- @RequestMapping("/user")
- public class UserController {
- //用户登录
- @RequestMapping("/login")
- public String login(User user, HttpServletRequest request){
- Subject subject=SecurityUtils.getSubject();
- UsernamePasswordToken token=new UsernamePasswordToken(user.getUsername(),user.getPassword());
- try {
- //调用subject.login(token)进行登录,会自动委托给securityManager,调用之前
- subject.login(token);//会跳到我们自定义的realm中
- request.getSession().setAttribute("user",user);
- return "success";
- }catch (Exception e){
- e.printStackTrace();
- request.getSession().setAttribute("user",user);
- request.setAttribute("error","用户名或密码错误");
- return "login";
- }
- }
- @RequestMapping("/logout")
- public String logout(HttpServletRequest request){
- request.getSession().invalidate();
- return "index";
- }
- @RequestMapping("/admin")
- public String admin(HttpServletRequest request){
- return "success";
- }
- @RequestMapping("/student")
- public String student(HttpServletRequest request){
- return "success";
- }
- @RequestMapping("/teacher")
- public String teacher(HttpServletRequest request){
- return "success";
- }
- }
上面用户登录会执行一个subject.login(token);这里会跳转到我们自定义的realm中,接下来就定义一下我们自己的realm,由于这里是和mybatis整合了,所以不需要原来的那个Dbutil去连接数据库了,直接使用mybatis中的mapper接口,也就是上面写的dao。
- public class MyRealm extends AuthorizingRealm {
- @Resource
- private UserServiceImpl userServiceImpl;
- //为当前登录成功的用户授予权限和角色,已经登录成功了。
- protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
- String username=(String) principals.getPrimaryPrincipal();
- SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();
- authorizationInfo.setRoles(userServiceImpl.getRoles(username));
- authorizationInfo.setStringPermissions(userServiceImpl.getPermissions(username));
- return authorizationInfo;
- }
- //验证当前登录的用户,获取认证信息。
- protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
- String username=(String) token.getPrincipal();//获取用户名
- User user=userServiceImpl.getByUsername(username);
- if(user!=null){
- AuthenticationInfo authcInfo =new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(),"myRealm");
- return authcInfo;
- }else{
- return null;
- }
- }
- }
login.jsp
- <body>
- <form action="${pageContext.request.contextPath }/user/login.do" method="post">
- username:<input type="text" name="username"/><br>
- password:<input type="password" name="password"/><br>
- <input type="submit" value="登录">${error}
- </form>
- </body>
- <body>
- 欢迎你${user.username}
- <a href="/user/logout.do">退出</a>
- </body>
unauthorized.jsp
- <body>
- 认证未通过,或者权限不足
- <a href="${pageContext.request.contextPath}/user/login.do">退出</a>
- </body>
根据spring的配置文件中对shiro的url拦截配置,我们首先请求:http://localhost:8080/ShiroSpring/user/admin.do来测试身份认证,然后会跳转到登录页面让我们登录,登录成功后,再次请求这个url就会进入success.jsp页面了。
再测试角色和权限认证,可以先后输入http://localhost:8080/ShiroSpring/user/student.do来测试角色认证,输入http://localhost:8080/ShiroSpring/user/teacher.do来测试权限认证。通过登陆不同的用户去测试即可。