简介
1.shiro是用于权限控制还有对密码加密的框架,同时可以控制尝试登入次数,超出将对用户锁定
2.shiro的运行轨迹是用户登入以后,shiro会自动查询用户的角色以及权限,并将用户信息保存到session里,当用户在进行访问资源时候,会根据之前对资源权限的定义,检查用户是否具有这个权限,比如访问/allUser,访问需要admin的角色,shiro会根据登入用户的信息,检查用户是否具有admin的角色
3.shiro1.2提供了passwordService,对密码加密更加方便
4.shiro的shiroFilter配置,如果是访问其他已存在的页面被拦截到登录页面,登录后就会跳转到之前的页面;如果是直接访问登录页面或者是通过退出登录到登录页面,再次登录就会跳转到“/”
5.Spring MVC的json传输,可以自动的根据属性名称,将json和对象自动转换
6.实例环境的搭建 http://blog.csdn.net/zzhao114/article/details/54958339
7.实例用到的mybatis多表联立 http://blog.csdn.net/zzhao114/article/details/55106270
8.实例 http://download.csdn.net/download/zzhao114/9757441
(http://download.csdn.net/download/zzhao114/9936992 这个加入了数据库还有简单的文档)
将Shiro整到SSM中(基于maven)
--------------------------------------------------------------------------------------------------------------------
Shiro整到Spring中后,我们自定义的realm啊、securityManager等都会交给spring去管理了,包括我们需要指定哪些url需要做什么样的验证,都是交给spring,也就是说,完全可以摆脱原来的那个.ini配置文件了,Shiro部分参考了它的官方文档:http://shiro.apache.org/spring.html
1.
2.配置文件
2.1 pom.xml
2.2 log4j.properties
- 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>ShiroSpringdisplay-name>
- <welcome-file-list>
- <welcome-file>index.jspwelcome-file>
- welcome-file-list>
-
-
- <listener>
- <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
- listener>
- <context-param>
- <param-name>contextConfigLocationparam-name>
- <param-value>classpath:applicationContext.xmlparam-value>
- context-param>
-
-
- <servlet>
- <servlet-name>springMVCservlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
- <init-param>
- <param-name>contextConfigLocationparam-name>
- <param-value>classpath:spring-mvc.xmlparam-value>
- init-param>
- servlet>
- <servlet-mapping>
- <servlet-name>springMVCservlet-name>
- <url-pattern>*.dourl-pattern>
- servlet-mapping>
-
-
- <filter>
- <filter-name>shiroFilterfilter-name>
- <filter-class>org.springframework.web.filter.DelegatingFilterProxyfilter-class>
- <init-param>
-
- <param-name>targetFilterLifecycleparam-name>
- <param-value>trueparam-value>
- init-param>
- filter>
- <filter-mapping>
- <filter-name>shiroFilterfilter-name>
- <url-pattern>/*url-pattern>
- filter-mapping>
-
-
- <filter>
- <filter-name>encodingFilterfilter-name>
- <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
- <async-supported>trueasync-supported>
- <init-param>
- <param-name>encodingparam-name>
- <param-value>UTF-8param-value>
- init-param>
- filter>
- <filter-mapping>
- <filter-name>encodingFilterfilter-name>
- <url-pattern>/*url-pattern>
- filter-mapping>
- web-app>
2.4 applicationContext.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.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>
-
-
- <bean name="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
- <property name="dataSource" ref="dataSource"/>
-
- <property name="mapperLocations" value="classpath:demo/mappers/*.xml "/>
-
- <property name="configLocation" value="classpath:mybatis-config.xml"/>
- bean>
-
-
- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
- <property name="basePackage" value="demo.dao"/>
- <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
- bean>
-
-
- <bean id="myRealm" class="demo.realm.MyRealm"/>
-
-
- <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- <property name="realm" ref="myRealm">property>
- bean>
-
-
- <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
-
- <property name="securityManager" ref="securityManager"/>
-
- <property name="loginUrl" value="/login.jsp"/>
-
- <property name="unauthorizedUrl" value="/unauthorized.jsp"/>
-
- <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" ?>
-
- PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-config.dtd">
- <configuration>
-
- <typeAliases>
- <package name="demo.entity"/>
- typeAliases>
- configuration>
3.2配置mapper映射文件
UserMapper.xml
- xml version="1.0" encoding="UTF-8" ?>
-
- 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>
3.3mapper接口(UserDao)
- public interface UserDao {
- public User getByUsername(String username);
-
- public Set getRoles(String username);
-
- public Set getPermissions(String username);
-
- }
只需要写接口,不需要写实现,spring的配置文件中会去扫描mapper,会自动创建一个代理对象来执行相应的方法,要注意的是这个接口的方法名要和上面mapper映射文件的id号一样的,否则是无法映射到具体的statement上面的,会报错。
3.4 entity类
这里写个简单的User类
- public class User {
- private Integer id;
- private String username;
- private String password;
-
-
- }
3.5 Service
接口UserService.java
- public interface UserService {
- public User getByUsername(String username);
-
- public Set getRoles(String username);
-
- public Set 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 getRoles(String username){
- return userDao.getRoles(username);
- }
- public Set getPermissions(String username){
- return userDao.getPermissions(username);
- }
- }
在service的实现类中,注入刚刚写好的dao接口即可调用其中的方法了,使用的是spring自动创建的代理对象去执行的。
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);
- 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";
- }
- }
4.3完成自定义的realm
上面用户登录会执行一个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;
- }
- }
- }
5.几个jsp页面
login.jsp
success.jsp
unauthorized.jsp
6.测试
根据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来测试权限认证。通过登陆不同的用户去测试即可。