shiro+springmvc+mybatis

来源:互联网 发布:java开发erp系统难不难 编辑:程序博客网 时间:2024/06/04 19:58


一直以来,从开发到现在,都还没自己研究过权限控制。问了老大,老大让我学习shiro。先讲一下shiro配置吧

需要jar包:

shiro-all-1.2.4.jar

ehcache-2.7.2.jar

slf4j-log4j12-1.6.1-javadoc.jar

slf4j.api-1.6.1.jar

log4j-1.2.15.jar

都是相互依赖的包。

配置文件: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"    xmlns:context="http://www.springframework.org/schema/context"    xmlns:aop="http://www.springframework.org/schema/aop"    xmlns:tx="http://www.springframework.org/schema/tx"    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/aop         http://www.springframework.org/schema/aop/spring-aop.xsd        http://www.springframework.org/schema/tx         http://www.springframework.org/schema/tx/spring-tx.xsd        http://www.springframework.org/schema/mvc         http://www.springframework.org/schema/mvc/spring-mvc.xsd">        <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="/login.jsp" /><property name="unauthorizedUrl" value="/error/noperms.jsp" /><property name="filterChainDefinitions"><value>/login.jsp* = anon/login.do* = anon/index.jsp*= anon/error/noperms.jsp*= anon/*.jsp* = authc/*.do* = authc</value></property></bean><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="realm" ref="monitorRealm" /></bean><bean id="monitorRealm" class="com.test.util.MonitorRealm"/><!-- securityManager --><bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"><property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager" /><property name="arguments" ref="securityManager" /></bean><!-- 保证实现了Shiro内部lifecycle函数的bean执行 --><bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /><!-- AOP式方法级权限检查  --><beanclass="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"depends-on="lifecycleBeanPostProcessor" /><beanclass="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"><property name="securityManager" ref="securityManager" /></bean>    </beans>

web.xml

  <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>*.do</url-pattern>        </filter-mapping>        <filter-mapping>            <filter-name>shiroFilter</filter-name>            <url-pattern>*.jsp</url-pattern>        </filter-mapping>  

从<bean id="monitorRealm" class="com.test.util.MonitorRealm"/>可以看出 我们需要一个java类 来控制验证,认证

package com.test.util;import java.util.ArrayList;import java.util.List;import javax.annotation.Resource;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.UsernamePasswordToken;import org.apache.shiro.authz.AuthorizationException;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import com.test.dao.PermissionDao;import com.test.dao.RoleDao;import com.test.dao.UserDao;import com.test.model.Permission;import com.test.model.RoleBean;import com.test.model.UserBean;public class MonitorRealm extends AuthorizingRealm{@Resource(name="userDao")private UserDao userDao;@Resource(name="roleDao")private RoleDao roleDao;@Resource(name="permissionDao")private PermissionDao permissionDao;protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {String currentUsername = (String)super.getAvailablePrincipal(principals);UserBean user = userDao.findUserByName(currentUsername);List<String> roles = new ArrayList<String>();List<String> permissions = new ArrayList<String>();if(null != user){  List<RoleBean> list1 = roleDao.findLikeEntity(user.getId());if(null != list1 && !list1.isEmpty()){for(RoleBean role:list1){roles.add(role.getName());List<Permission> list = permissionDao.findEntity(role.getId());if(null != list && !list.isEmpty()){for(Permission permission:list){permissions.add(permission.getUrl());}}}}}else{  throw new AuthorizationException();  }SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();          simpleAuthorInfo.addRoles(roles);        simpleAuthorInfo.addStringPermissions(permissions);          //实际中可能会像上面注释的那样从数据库取得          if(null!=currentUsername && "admin".equals(currentUsername)){              //添加一个角色,不是配置意义上的添加,而是证明该用户拥有admin角色                simpleAuthorInfo.addRole("admin");              //添加权限              simpleAuthorInfo.addStringPermission("admin:manage");              System.out.println("已为用户[mike]赋予了[admin]角色和[admin:manage]权限");              return simpleAuthorInfo;          }        //若该方法什么都不做直接返回null的话,就会导致任何用户访问/admin/listUser.jsp时都会自动跳转到unauthorizedUrl指定的地址          //详见applicationContext.xml中的<bean id="shiroFilter">的配置          return null;  }protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {UsernamePasswordToken token = (UsernamePasswordToken) authcToken;UserBean user = new UserBean();user.setLoginName(token.getUsername());user.setPasswd(new String(token.getPassword()));List<UserBean> list = userDao.login(user);if(!list.isEmpty()){return  new SimpleAuthenticationInfo(user,                  user.getPasswd().toCharArray(), getName());}return null;}}

当你在login时

@RequestMapping(value="login.do",method=RequestMethod.POST)public String login(UserBean user,HttpSession session,Model model){        Subject currentUser = SecurityUtils.getSubject();          UsernamePasswordToken token = new UsernamePasswordToken(                  user.getLoginName(), user.getPasswd());          token.setRememberMe(true);          try {              currentUser.login(token);          } catch (AuthenticationException e) {        model.addAttribute("status", 1);         return "error";        }          if(currentUser.isAuthenticated()){              session.setAttribute("userinfo", user);              return "page/index";        }else{          return "login";        }  }

currentUser.login(token);  就会调用 monitorRealm里的doGetAuthenticationInfo方法

并将用户名密码传递过去。

数据库查找,当用户密码正确时 

return new SimpleAuthenticationInfo(user, user.getPasswd().toCharArray(), getName());

否则 return null

return null 就会被catch到AuthenticationException

也有一种情况,就是 如果你没有使用加密,然后你配置文件使用了加密配置了。

则会报一个Caused by: java.lang.IllegalArgumentException: Odd number of characters.的错误。


0 0