- <span style="background-color: rgb(255, 255, 255); font-family: Arial, Helvetica, sans-serif;">
- </span>
- 一直以来,从开发到现在,都还没自己研究过权限控制。问了老大,老大让我学习shiro。
- <span style="background-color: rgb(255, 255, 255); font-family: Arial, Helvetica, sans-serif;">先讲一下shiro配置吧。</span>
需要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式方法级权限检查 -->
- <bean
- class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
- depends-on="lifecycleBeanPostProcessor" />
- <bean
- class="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.的错误。
框架/平台构成:
Maven+Springmvc + Mybatis + Shiro(权限)+ Tiles(模板) +ActiveMQ(消息队列) + Rest(服务) + WebService(服务)+ EHcache(缓存) + Quartz(定时调度)+ Html5(支持PC、IOS、Android)
用户权限系统:
组织结构:角色、用户、用户组、组织机构;权限点:页面、方法、按钮、数据权限、分级授权
项目管理新体验:
快速出原型系统、组件树、版本控制、模块移植、协同开发、实时监控、发布管理
可持续集成:
所有组件可移植、可定制、可扩充,开发成果不断积累,形成可持续发展的良性循环
支持平台平台:
Windows XP、Windows 7 、Windows 10 、 Linux 、 Unix
服务器容器:
Tomcat 5/6/7 、Jetty、JBoss、WebSphere 8.5