利用shiro实现权限的动态控制

来源:互联网 发布:java技能专业培训 编辑:程序博客网 时间:2024/04/30 10:29

使用shiro对登陆进行权限验证,以及实现权限的动态管理。

数据库表



shiro配置文件

<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:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans    
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd    
                        http://www.springframework.org/schema/context    
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd    
                        http://www.springframework.org/schema/mvc    
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
                        http://www.springframework.org/schema/util    
                        http://www.springframework.org/schema/util/spring-util-3.2.xsd">

    <!-- 登陆及权限认证 -->
    <bean id="bosRealm" class="com.cn.hnust.utils.BOSRealm" />
    <!--配置shiro的sessionManager-->  
    <!-- <bean id="webSessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">  
         <property name="sessionDAO" ref="redisSessionDAO" />
    </bean>  -->

    <!-- 安全管理器 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="bosRealm" />
        <!-- <property name="sessionManager" ref="webSessionManager" /> -->
    </bean>

    <!-- 开启shiro权限注解 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
    <bean id="controllerAdvisorAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor" />
    <bean id="controllerAuthorizationAttributeSourceAdvisor" class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager" />
    </bean>

    <!-- Shiro的Web过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager" />
        <!-- 登陆页面 -->
        <property name="loginUrl" value="/index.jsp" />
        <!-- 没权限时页面 -->
        <property name="unauthorizedUrl" value="/" />
        <!-- 成功页面 -->
        <property name="successUrl" value="/" />
        <!-- URL拦截规则 -->
        <!-- <property name="filterChainDefinitions" value="#{shiroManager.loadFilterChainDefinitions()}"/> -->
        <property name="filterChainDefinitions" >
            <value>
                /index.jsp=anon
                /user/update!initAuth=anon
                /baseUtils/update!changePermissions=anon
                /**=authc
            </value>
        </property>
    </bean>
    

</beans>


jdbc配置文件

mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://127.0.0.1:3306/test
mysql.username=root
mysql.password=123456
#\u5B9A\u4E49\u521D\u59CB\u8FDE\u63A5\u6570  
mysql.initialSize=0
#\u5B9A\u4E49\u6700\u5927\u8FDE\u63A5\u6570  
mysql.maxActive=20
#\u5B9A\u4E49\u6700\u5927\u7A7A\u95F2  
mysql.maxIdle=20
#\u5B9A\u4E49\u6700\u5C0F\u7A7A\u95F2  
mysql.minIdle=1
#\u5B9A\u4E49\u6700\u957F\u7B49\u5F85\u65F6\u95F4  
mysql.maxWait=60000



redis.pool.maxActive=8
redis.pool.maxIdle=8
redis.pool.maxWaitTime=3000
redis.pool.testOnBorrow=false
redis.host.ip=localhost
redis.host.port=6379
shiro.session.timeout=10000
redis.pass=admin


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:p="http://www.springframework.org/schema/p"
    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-3.1.xsd    
                            http://www.springframework.org/schema/context    
                            http://www.springframework.org/schema/context/spring-context-3.1.xsd    
                            http://www.springframework.org/schema/mvc    
                            http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
    <!-- 自动扫描(自动注入) -->
    <context:component-scan base-package="com.cn.hnust" use-default-filters="false">
         <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
    </context:component-scan>
    
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="${mysql.driver}" />
        <property name="url" value="${mysql.url}" />
        <property name="username" value="${mysql.username}" />
        <property name="password" value="${mysql.password}" />
        <!-- 初始化连接大小 -->
        <property name="initialSize" value="${mysql.initialSize}"></property>
        <!-- 连接池最大数量 -->
        <property name="maxActive" value="${mysql.maxActive}"></property>
        <!-- 连接池最大空闲 -->
        <property name="maxIdle" value="${mysql.maxIdle}"></property>
        <!-- 连接池最小空闲 -->
        <property name="minIdle" value="${mysql.minIdle}"></property>
        <!-- 获取连接最大等待时间 -->
        <property name="maxWait" value="${mysql.maxWait}"></property>
    </bean>

    <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- 自动扫描mapping.xml文件 -->
        <property name="mapperLocations" value="classpath:com/cn/hnust/dao/*.xml"></property>
    </bean>

    <!-- DAO接口所在包名,Spring会自动查找其下的类 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.cn.hnust.dao" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
    </bean>

    <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!-- 配置事物的注解方式注入 -->  
    <!-- <tx:annotation-driven transaction-manager="transactionManager"/>  -->
    
</beans> 


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:p="http://www.springframework.org/schema/p"
    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-3.1.xsd    
                        http://www.springframework.org/schema/context    
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd    
                        http://www.springframework.org/schema/mvc    
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">          
                        
    <!-- 启用SpringMVC的注解功能,它会自动注册HandlerMapping、HandlerAdapter、ExceptionResolver的相关实例 -->  
    <mvc:annotation-driven/>                 
                        
    <!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 -->
    <context:component-scan base-package="com.cn.hnust.controller" use-default-filters="false">
        <context:include-filter type="annotation"
            expression="org.springframework.stereotype.Controller" />
        <context:exclude-filter type="annotation"
            expression="org.springframework.stereotype.Service" />
    </context:component-scan>
    
    
    <!--避免IE执行AJAX时,返回JSON出现下载文件 -->
    <bean id="mappingJacksonHttpMessageConverter"
        class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>text/html;charset=UTF-8</value>
            </list>
        </property>
    </bean>
    <!-- 启动SpringMVC的注解功能,完成请求和注解POJO的映射 -->
    <bean
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="mappingJacksonHttpMessageConverter" /> <!-- JSON转换器 -->
            </list>
        </property>
    </bean>
    <!-- 定义跳转的文件的前后缀 ,视图模式配置 -->
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 这里的配置我的理解是自动给后面action的方法return的字符串加上前缀和后缀,变成一个 可用的url地址 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <!-- 配置文件上传,如果没有使用文件上传可以不用配置,当然如果不配,那么配置文件中也不必引入上传组件包 -->
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 默认编码 -->
        <property name="defaultEncoding" value="utf-8" />
        <!-- 文件大小最大值 -->
        <property name="maxUploadSize" value="10485760000" />
        <!-- 内存中的最大值 -->
        <property name="maxInMemorySize" value="40960" />
    </bean>

</beans>

spring配置文件

<?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: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-3.1.xsd    
                        http://www.springframework.org/schema/context    
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd    
                        http://www.springframework.org/schema/mvc    
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
    <!-- 引入配置文件 -->
    <context:property-placeholder location="classpath:jdbc.properties" />
    <import resource="spring-mybatis.xml"/>  
    <import resource="spring-mvc.xml"/>  
    <import resource="spring-redis.xml"/>  
    <import resource="spring-shiro.xml"/>  
</beans>


dao层

package com.cn.hnust.dao;

import java.util.List;

import com.cn.hnust.pojo.UrlFilter;

public interface UrlFilterMapper {

    List<UrlFilter> selectAll();
    
    void insertPermissions(UrlFilter urlFilter);
}


<?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.cn.hnust.dao.UrlFilterMapper">  
    <resultMap id="BaseResultMap" type="com.cn.hnust.pojo.UrlFilter">  
        <result column="id" property="id" jdbcType="BIGINT"/>
        <result column="url" property="url" jdbcType="VARCHAR"/>  
        <result column="name" property="name" jdbcType="VARCHAR"/>  
        <result column="roles" property="roles" jdbcType="VARCHAR"/>  
        <result column="permissions" property="permissions" jdbcType="VARCHAR"/>
        <result column="sort" property="sort" jdbcType="INTEGER"/>  
    </resultMap>  
  <sql id="Base_Column_List" >  
    id,url,name,roles,permissions,sort,available
  </sql>  
  <select id="selectAll" resultMap="BaseResultMap">  
    select   
    <include refid="Base_Column_List" />  
    from t_url_permissions  
    ORDER BY sort DESC
  </select>  
  <insert id="insertPermissions" parameterType="com.cn.hnust.pojo.UrlFilter">
      INSERT INTO t_url_permissions(url,name,roles,permissions,sort,available)
      VALUES(#{url,jdbcType=VARCHAR},#{name,jdbcType=VARCHAR},#{roles,jdbcType=VARCHAR},
              #{permissions,jdbcType=VARCHAR},
              #{sort,jdbcType=INTEGER},#{available,jdbcType=VARCHAR})
  </insert>
</mapper>

package com.cn.hnust.dao;

import com.cn.hnust.pojo.User;

public interface IUserDao {
    
    User selectByPrimaryKey(Integer userId);
    
    User selectByUsername(String name);
}
<?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.cn.hnust.dao.IUserDao">  
    <resultMap id="BaseResultMap" type="com.cn.hnust.pojo.User">  
        <result column="id" property="id" jdbcType="INTEGER"/>
        <result column="user_name" property="userName" jdbcType="VARCHAR"/>  
        <result column="password" property="password" jdbcType="VARCHAR"/>
        <result column="age" property="age" jdbcType="INTEGER"/>  
    </resultMap>  
  <sql id="Base_Column_List" >  
    id,user_name, password  ,age
  </sql>  
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >  
    select   
    <include refid="Base_Column_List" />  
    from user_t  
    where id = #{id,jdbcType=INTEGER}  
  </select>  
  <select id="selectByUsername" resultMap="BaseResultMap" parameterType="java.lang.String">
      select   
    <include refid="Base_Column_List" />  
    from user_t  
    where user_name = #{userName,jdbcType=VARCHAR}  
  </select>
</mapper>

POJO实体类

package com.cn.hnust.pojo;

import java.io.Serializable;

public class UrlFilter implements Serializable{
    
    /**
     *
     */
    private static final long serialVersionUID = 2725744448169512486L;
    
    private Long id;
    //地址描述
    private String name;
    //地址
    private String url;
    //所需角色
    private String roles;
    //所需权限
    private String permissions;
    //是否启用
    private String available;
    //排序
    private String sort;
    
    
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getRoles() {
        return roles;
    }
    public void setRoles(String roles) {
        this.roles = roles;
    }
    public String getPermissions() {
        return permissions;
    }
    public void setPermissions(String permissions) {
        this.permissions = permissions;
    }
    public String getAvailable() {
        return available;
    }
    public void setAvailable(String available) {
        this.available = available;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public String getSort() {
        return sort;
    }
    public void setSort(String sort) {
        this.sort = sort;
    }
}

package com.cn.hnust.pojo;

public class User {

    private Integer id;
    private String userName;
    private String password;
    private Integer age;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    
    
}

service层

package com.cn.hnust.service.impl;

import java.util.List;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cn.hnust.dao.UrlFilterMapper;
import com.cn.hnust.pojo.UrlFilter;
import com.cn.hnust.service.UrlFilterService;


@Service
public class UrlFilterServiceImpl implements UrlFilterService {
    private static final String CRLF = "\r\n";
    @Autowired
    private UrlFilterMapper urlFilterMapper;

    @Override
    public String selectAllPermissions() {
        StringBuilder sb = new StringBuilder();
        List<UrlFilter> urls = urlFilterMapper.selectAll();
        for (UrlFilter urlFilter : urls) {
            sb.append(urlFilter.getUrl()).append(" == ").append(urlFilter.getPermissions()).append(CRLF);
        }
        return sb.toString();
    }

    @Override
    public void insertPermissions(UrlFilter urlFilter) {
        urlFilterMapper.insertPermissions(urlFilter);
    }

}

package com.cn.hnust.service.impl;  
 
import javax.annotation.Resource;  
 
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.UrlFilenameViewController;

import com.cn.hnust.dao.IUserDao;  
import com.cn.hnust.pojo.User;  
import com.cn.hnust.service.IUserService;  
 
@Service("userService")  
public class UserServiceImpl implements IUserService {  
    @Resource  
    private IUserDao userDao;

    public User getUserById(Integer userId) {
        // TODO Auto-generated method stub
        return this.userDao.selectByPrimaryKey(userId);
    }

    @Override
    public User getUserByName(User user) {
        if(null == user || null == user.getUserName())
            return null;
            
        return userDao.selectByUsername(user.getUserName());
    }  
    
 
}
controller层

package com.cn.hnust.controller;  

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.mgt.RealmSecurityManager;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import com.cn.hnust.pojo.User;
import com.cn.hnust.service.IUserService;
import com.cn.hnust.utils.BOSRealm;
import com.cn.hnust.utils.ShiroManager;  

@Controller  
@RequestMapping("/user")  
public class UserController {  
    @Resource  
    private IUserService userService;  
    @Autowired
    private ShiroManager shiroManager;
      
    //@RequiresPermissions("sys")
    @RequestMapping("/showUser")  
    public String toIndex(HttpServletRequest request,Model model){  
        Integer userId = Integer.parseInt(request.getParameter("id"));  
        User user = this.userService.getUserById(userId);  
        model.addAttribute("user", user);  
        return "showUser";  
    }
    
    @RequestMapping("/login")  
    public String toLogin(HttpServletRequest request,Model model){  
        Subject subject = SecurityUtils.getSubject();
        String password = request.getParameter("password");
        String username = request.getParameter("username");
        
        System.out.println(username+"<----->"+password);
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);
        try{
            subject.login(token);
        }catch(UnknownAccountException ue){
            System.out.println("Exception 用户不存在");
        }catch(IncorrectCredentialsException ie){
            System.out.println("Exception 密码错误");
        }
        User user = (User) subject.getPrincipal();
        
        model.addAttribute("user", user);
        return "showUser";  
    }
    
    /**
     * 用户登出
     */  
    @RequestMapping("/logout")  
    public String logout(HttpServletRequest request){  
         SecurityUtils.getSubject().logout();  
         return InternalResourceViewResolver.REDIRECT_URL_PREFIX + "/";  
    }
    
    
    /**
     * 清除权限
     */
    public void clearAuthz(){
        RealmSecurityManager rsm = (RealmSecurityManager) SecurityUtils.getSecurityManager();
        BOSRealm realm  = (BOSRealm) rsm.getRealms().iterator().next();
        realm.clearAuthz();
    }
    
    @RequestMapping("/update!initAuth")  
    public String initAuth(){
        shiroManager.reCreateFilterChains();
        return InternalResourceViewResolver.REDIRECT_URL_PREFIX + "/";  
    }

package com.cn.hnust.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import com.cn.hnust.pojo.UrlFilter;
import com.cn.hnust.service.impl.UrlFilterServiceImpl;
import com.cn.hnust.utils.ShiroManager;

@Controller
@RequestMapping("/baseUtils")
public class BaseUtilController {
    @Autowired
    private UrlFilterServiceImpl urlFilterServiceImpl;
    @Autowired
    private ShiroManager shiroManager;

    @RequestMapping("/update!changePermissions")
    public String toChangeFilterChain(){
        String filterChains = urlFilterServiceImpl.selectAllPermissions();
        shiroManager.sqlCreateFilterChains(filterChains);
        return InternalResourceViewResolver.REDIRECT_URL_PREFIX + "/";  
    }
    
    
    @RequestMapping("/insert!addPermissions")
    public String addFilterChain(UrlFilter urlFilter){
        urlFilterServiceImpl.insertPermissions(urlFilter);
        String filterChains = urlFilterServiceImpl.selectAllPermissions();
        System.out.println("重新加载权限:\n"+filterChains);
        shiroManager.sqlCreateFilterChains(filterChains);
        return "addPermissions";  
    }
    
    
    @RequestMapping("/select!showPage")
    public String showPage(String pageName){
        return pageName;  
    }
}

utils工具类

package com.cn.hnust.utils;

import java.util.HashSet;
import java.util.Set;

import org.apache.shiro.SecurityUtils;
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.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.springframework.beans.factory.annotation.Autowired;

import com.cn.hnust.pojo.User;
import com.cn.hnust.service.IUserService;

public class BOSRealm extends AuthorizingRealm{
    @Autowired
    private IUserService userService;  
    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principla) {
        //获取当前登陆的用户名
        SimpleAuthorizationInfo inf = new SimpleAuthorizationInfo();
        User principlaUser = (User)super.getAvailablePrincipal(principla);  
        
        if(null != principlaUser){
            System.out.println("当前登陆的用户--->"+principlaUser.getUserName());
            User user = userService.getUserByName(principlaUser);
            
            Set<String> roles = new HashSet<>();
            roles.add(user.getUserName());
            Set<String> perms = new HashSet<>();
            perms.add("sys");
            perms.add("userAdd");
            
            inf.setRoles(roles);
            inf.setStringPermissions(perms);
        }
        
        
        return inf;
    }

    /**
     * 认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
        
        UsernamePasswordToken token = (UsernamePasswordToken) auth;
        System.out.println("进行登陆校验的用户="+token.getUsername());
        User user = new User();
        user.setUserName(token.getUsername());
        
        user = userService.getUserByName(user);
        if(null == user)
            return null;
        
        return new SimpleAuthenticationInfo(user,(user == null? null :user.getPassword()),this.getClass().getSimpleName());
    }
    
    
    public void clearAuthz(){
        this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
    }

}

package com.cn.hnust.utils;

import java.io.IOException;
import java.util.Map;
import java.util.Set;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import com.cn.hnust.service.impl.UrlFilterServiceImpl;

/**
 * 动态加载权限 Service
 */
@Service
public class ShiroManager{
    
    // 注意/r/n前不能有空格
    private static final String CRLF = "\r\n";
    @Autowired
    private ShiroFilterFactoryBean shiroFilterFactoryBean;
    
    public String loadFilterChainDefinitions() {
        
        StringBuffer sb = new StringBuffer();
        sb.append(getFixedAuthRule());//固定权限,采用读取配置文件
        System.out.println(sb.toString());
        return sb.toString();
    }
    
    /**
     * 从配置文件获取固定权限验证规则串
     */
    private String getFixedAuthRule(){
        String fileName = "shiro_base_auth.ini";
        ClassPathResource cp = new ClassPathResource(fileName);
        INI4j ini = null;
        try {
            ini = new INI4j(cp.getFile());
        } catch (IOException e) {
            e.printStackTrace();
        }
        String section = "base_auth";
        Set<String> keys = ini.get(section).keySet();
        StringBuffer sb = new StringBuffer();
        for (String key : keys) {
            String value = ini.get(section, key);
            sb.append(key).append(" = ").append(value).append(CRLF);
        }
        
        return sb.toString();
    }
    
    // 此方法加同步锁
    public synchronized void reCreateFilterChains() {
        AbstractShiroFilter shiroFilter = null;
        try {
            shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean.getObject();
        } catch (Exception e) {
            throw new RuntimeException("get ShiroFilter from shiroFilterFactoryBean error!");
        }
        PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter.getFilterChainResolver();
        DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver.getFilterChainManager();
        // 清空老的权限控制
        manager.getFilterChains().clear();
        shiroFilterFactoryBean.getFilterChainDefinitionMap().clear();
        shiroFilterFactoryBean.setFilterChainDefinitions(loadFilterChainDefinitions());
        // 重新构建生成
        Map<String, String> chains = shiroFilterFactoryBean.getFilterChainDefinitionMap();
        
        for (Map.Entry<String, String> entry : chains.entrySet()) {
            String url = entry.getKey();
            String chainDefinition = entry.getValue().trim().replace(" ", "");
            
            manager.createChain(url, chainDefinition);
        }
    }
    
    
    public synchronized void sqlCreateFilterChains(String filterChains) {
        AbstractShiroFilter shiroFilter = null;
        try {
            shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean.getObject();
        } catch (Exception e) {
            throw new RuntimeException("get ShiroFilter from shiroFilterFactoryBean error!");
        }
        PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter.getFilterChainResolver();
        DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver.getFilterChainManager();
        // 清空老的权限控制
        manager.getFilterChains().clear();
        shiroFilterFactoryBean.getFilterChainDefinitionMap().clear();
        //String filterChains = urlFilterService.selectAllPermissions();
        shiroFilterFactoryBean.setFilterChainDefinitions(filterChains);
        // 重新构建生成
        Map<String, String> chains = shiroFilterFactoryBean.getFilterChainDefinitionMap();
        
        for (Map.Entry<String, String> entry : chains.entrySet()) {
            String url = entry.getKey();
            String chainDefinition = entry.getValue().trim().replace(" ", "");
            
            manager.createChain(url, chainDefinition);
        }
    }
    
    
    public void setShiroFilterFactoryBean(ShiroFilterFactoryBean shiroFilterFactoryBean) {
        this.shiroFilterFactoryBean = shiroFilterFactoryBean;
    }
}

package com.cn.hnust.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

import org.springframework.core.io.ClassPathResource;
/**
 * 有序读取 ini配置文件
 *
 */
public class INI4j {
    
    /**
     * 用linked hash map 来保持有序的读取
     *
     */
    final LinkedHashMap<String,LinkedHashMap<String, String>>  coreMap = new LinkedHashMap<String, LinkedHashMap<String,String>>();
    /**
     * 当前Section的引用
     */
    String currentSection = null;
     
    /**
     * 读取
     * @param file 文件
     * @throws FileNotFoundException
     */
    public INI4j(File file) throws FileNotFoundException {
        this.init(new BufferedReader(new FileReader(file)));
    }
    /***
     * 重载读取
     * @param path 给文件路径
     * @throws FileNotFoundException
     */
    public INI4j(String path) throws FileNotFoundException {
        this.init(new BufferedReader(new FileReader(path)));
    }
    /***
     * 重载读取
     * @param source ClassPathResource 文件,如果文件在resource 里,那么直接 new ClassPathResource("file name");
     * @throws IOException
     */
    public INI4j(ClassPathResource source) throws IOException {
        this(source.getFile());
    }

    void init(BufferedReader bufferedReader){
        try {
            read(bufferedReader);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("IO Exception:" + e);
        }
    }
    /**
     * 读取文件
     * @param reader
     * @throws IOException
     */
    void read(BufferedReader reader) throws IOException {
        String line = null;
        while((line=reader.readLine())!=null) {
            parseLine(line);
        }
    }
     
    /**
     * 转换
     * @param line
     */
    void parseLine(String line) {
        line = line.trim();
        // 此部分为注释
        if(line.matches("^\\#.*$")) {
            return;
        }else if (line.matches("^\\[\\S+\\]$")) {
            // section
            String section = line.replaceFirst("^\\[(\\S+)\\]$","$1");
            addSection(section);
        }else if (line.matches("^\\S+=.*$")) {
            // key ,value
            int i = line.indexOf("=");
            String key = line.substring(0, i).trim();
            String value =line.substring(i + 1).trim();
            addKeyValue(currentSection,key,value);
        }
    }


    /**
     * 增加新的Key和Value
     * @param currentSection
     * @param key
     * @param value
     */
    void addKeyValue(String currentSection,String key, String value) {
        if(!coreMap.containsKey(currentSection)) {
            return;
        }
        Map<String, String> childMap = coreMap.get(currentSection);
        childMap.put(key, value);
    }


    /**
     * 增加Section
     * @param section
     */
    void addSection(String section) {
        if (!coreMap.containsKey(section)) {
            currentSection = section;
            LinkedHashMap<String,String> childMap = new LinkedHashMap<String,String>();
            coreMap.put(section, childMap);
        }
    }
     
    /**
     * 获取配置文件指定Section和指定子键的值
     * @param section
     * @param key
     * @return
     */
    public String get(String section,String key){
        if(coreMap.containsKey(section)) {
            return  get(section).containsKey(key) ?  get(section).get(key): null;
        }
        return null;
    }
     
     
     
    /**
     * 获取配置文件指定Section的子键和值
     * @param section
     * @return
     */
    public Map<String, String> get(String section){
        return  coreMap.containsKey(section) ? coreMap.get(section) : null;
    }
     
    /**
     * 获取这个配置文件的节点和值
     * @return
     */
    public LinkedHashMap<String, LinkedHashMap<String, String>> get(){
        return coreMap;
    }
     
}

工程文件位置


阅读全文
0 0
原创粉丝点击