zoukankan      html  css  js  c++  java
  • shiro实现权限注解配置拦截-cjq

    1.shiro.inil初始化自定义的realm(很多都可以初始化。。。)

    [main]
    #自定义 realm
    customRealm=cn.cjq.util.shiro.UserRealm
    #将realm设置到securityManager
    securityManager.realms=$customRealm

    2.web.xml开启shiro拦截

    <!-- 添加 Shiro 相关配置 -->
    <listener>
    <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
    </listener>
    <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>

    3.springmvc配置开启aop代理,初始化自定义异常类:获取用户无权限异常

    <aop:aspectj-autoproxy/>
    <!-- 自定义异常处理-->
    <bean id="exceptionResolver" class="cn.cjq.util.MyExceptionResolver"></bean>

    4.shiro的xml配置:启用aop代理,启用shiro注解

    <?xml version="1.0" encoding="GB2312"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
    <description>== Shiro Components ==</description>
    <!-- 缓存管理器 使用Ehcache实现 -->
    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
    <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
    </bean>
    <!-- 凭证匹配器 未使用-->
    <bean id="credentialsMatcher" class="cn.cjq.util.shiro.RetryLimitHashedCredentialsMatcher">
    <constructor-arg ref="cacheManager"/>
    <property name="hashAlgorithmName" value="md5"/>
    <property name="hashIterations" value="2"/>
    <property name="storedCredentialsHexEncoded" value="true"/>
    </bean>

    <!-- rememberMeManager管理器,写cookie,取出cookie生成用户信息 -->
    <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
    <property name="cookie" ref="rememberMeCookie" />
    </bean>
    <!-- 记住我cookie -->
    <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
    <!-- rememberMe是cookie的名字 -->
    <constructor-arg value="rememberMe" />
    <!-- 记住我cookie生效时间30天 -->
    <property name="maxAge" value="2592000" />
    </bean>


    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager"/>
    <property name="loginUrl" value="/login/toLogin.do"/>
    <property name="unauthorizedUrl" value="/login/toLogin.do"/> //无验证权限跳转
    <property name="filters">
    <map>
    <entry key="authc" value-ref="formAuthenticationFilter"/>
    </map>
    </property>
    <property name="filterChainDefinitions">
    <value>
    /login/**=anon
    /api/** = authc
    /person/** = authc
    </value>
    </property>
    </bean>

    <!-- 会话ID生成器 -->
    <bean id="sessionIdGenerator"
    class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/>
    <!-- 会话Cookie模板 -->
    <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
    <constructor-arg value="sid"/>
    <property name="httpOnly" value="true"/>
    <property name="maxAge" value="1800000"/>
    </bean>
    <!-- 会话DAO -->
    <bean id="sessionDAO"
    class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
    <property name="activeSessionsCacheName" value="shiro-activeSessionCache"/>
    <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
    </bean>
    <bean id="sessionValidationScheduler"
    class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler">
    <property name="sessionValidationInterval" value="1800000"/>
    <property name="sessionManager" ref="sessionManager"/>
    </bean>
    <!-- 会话管理器 -->
    <bean id="sessionManager"
    class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
    <property name="globalSessionTimeout" value="1800000"/>
    <property name="deleteInvalidSessions" value="true"/>
    <property name="sessionValidationSchedulerEnabled" value="true"/>
    <property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
    <property name="sessionDAO" ref="sessionDAO"/>
    <property name="sessionIdCookieEnabled" value="true"/>
    <property name="sessionIdCookie" ref="sessionIdCookie"/>
    </bean>

    <bean id="formAuthenticationFilter" class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">
    <property name="usernameParam" value="username"/>
    <property name="passwordParam" value="password"/>
    <property name="rememberMeParam" value="rememberMe"/>
    </bean>


    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <!-- Single realm app. If you have multiple realms, use the 'realms' property instead. -->
    <property name="realm" ref="myShiroRealm"/>
    <property name="sessionManager" ref="sessionManager"/>
    <property name="cacheManager" ref="cacheManager"/>
    <!-- 记住我 -->
    <property name="rememberMeManager" ref="rememberMeManager"/>
    </bean>
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
     <!-- 自定义的realm -->
       <bean id="myShiroRealm" class="cn.cjq.util.shiro.UserRealm">
    <!-- <property name="userservice" ref="userservice"/>-->
    <property name="cachingEnabled" value="true"/>
    <property name="authenticationCachingEnabled" value="true"/>
    <property name="authenticationCacheName" value="authenticationCache"/>
    <property name="authorizationCachingEnabled" value="true"/>
    <property name="authorizationCacheName" value="authorizationCache"/>
    </bean>
    <!-- 开启Shiro注解 -->
    <bean
    class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    <property name="securityManager" ref="securityManager" />
    </bean>
    </beans>
    5.自定义realm
    package cn.cjq.util.shiro;


    import cn.cjq.entity.User;
    import cn.cjq.mapper.UserMapper;
    import cn.cjq.service.user.UserService;
    import cn.cjq.util.SpringContextUtil;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.AuthenticationInfo;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.SimpleAuthenticationInfo;
    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 org.springframework.beans.factory.annotation.Autowired;

    import java.util.List;
    import java.util.Set;


    public class UserRealm extends AuthorizingRealm {

    @Autowired
    private UserMapper userMapper;

    /**
    * 认证信息
    */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
    AuthenticationToken token) throws AuthenticationException {
    String username = (String)token.getPrincipal();
    UserService userService = (UserService) SpringContextUtil.getBean("userServiceImpl");
    User user = null;
    try {
    user = userService.findByUserName(username);
    } catch (Exception e) {
    e.printStackTrace();
    }
    if(user == null) {
    throw new IncorrectCredentialsException();//没找到帐号
    }

    //交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配,如果觉得人家的不好可以自定义实现
    SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
    user.getUsername(), //用户名
    user.getPassword(), //密码
    getName() //realm name
    );

    return authenticationInfo;
    }
    /**
    * 授权信息
    */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    String username = (String)principals.getPrimaryPrincipal();
    SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
    // UserService userService = (UserService) SpringContextUtil.getBean("userServiceImpl");
    try {
    authorizationInfo.setRoles(userMapper.findUserRoles(username));
    authorizationInfo.setStringPermissions(userMapper.findUserPermissions(username));
    } catch (Exception e) {

    e.printStackTrace();
    }
    return authorizationInfo;
    }

    @Override
    public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
    super.clearCachedAuthorizationInfo(principals);
    }

    @Override
    public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
    super.clearCachedAuthenticationInfo(principals);
    }

    @Override
    public void clearCache(PrincipalCollection principals) {
    super.clearCache(principals);
    }

    public void clearAllCachedAuthorizationInfo() {
    getAuthorizationCache().clear();
    }

    public void clearAllCachedAuthenticationInfo() {
    getAuthenticationCache().clear();
    }

    public void clearAllCache() {
    clearAllCachedAuthenticationInfo();
    clearAllCachedAuthorizationInfo();
    }

    }
    6.自定义异常处理类,在springmvc中的bean定义authorizationInfo中存入的值有关
    package cn.cjq.util;

    import org.apache.shiro.authz.UnauthorizedException;
    import org.springframework.web.servlet.HandlerExceptionResolver;
    import org.springframework.web.servlet.ModelAndView;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    /**
    *
    * 类名称:MyExceptionResolver.java
    * 类描述:
    * @author cjq
    * @version 1.0
    */
    public class MyExceptionResolver implements HandlerExceptionResolver {

    public ModelAndView resolveException(HttpServletRequest request,
    HttpServletResponse response, Object handler, Exception ex) {
    // TODO Auto-generated method stub
    System.out.println("==============shiro权限异常开始=============");
    //如果是shiro无权操作,因为shiro 在操作auno等一部分不进行转发至无权限url
    if(ex instanceof UnauthorizedException){
    ModelAndView mv = new ModelAndView("/403");
    return mv;
    }
    ex.printStackTrace();
    System.out.println("==============shiro权限异常结束=============");
    ModelAndView mv = new ModelAndView("error");
    mv.addObject("exception", ex.toString().replaceAll(" ", "<br/>"));
    return mv;
    }

    }
    7.实例,注解一个url方法,跟自定义realm授权
    package cn.cjq.controller;
    import cn.cjq.entity.Menu;
    import cn.cjq.entity.User;
    import cn.cjq.service.user.UserService;
    import org.apache.shiro.authz.annotation.RequiresPermissions;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;

    import javax.annotation.Resource;
    import javax.servlet.http.HttpServletRequest;
    import java.util.List;
    @Controller
    @RequestMapping("/person")
    public class PersonalController {
    @Resource
    private UserService userServiceImpl;
    /**
    * 个人中心
    * @return
    */
    @RequestMapping(value = {"/main"}, method = RequestMethod.GET)
    @RequiresPermissions("1dd44f6f850944898d0220314eb955a1")
    public String index(HttpServletRequest request) throws Exception{
    //用户信息
    User user=(User) request.getSession().getAttribute("user");
    request.setAttribute("user",user);
    //菜单列表
    List<Menu> Menulist=userServiceImpl.ListMenuByUserId(user.getUerid());
    request.setAttribute("Menulist",Menulist);
    return "personalmain";
    }
    }

    ---------------------------------------------------------------------------------------------------------------------

    附录

      anon,authc,authcBasic,user是第一组认证过滤器

      perms,port,rest,roles,ssl是第二组授权过滤器

    相关url:http://www.cppblog.com/guojingjia2006/archive/2014/05/14/206956.html






  • 相关阅读:
    declare handler 声明异常处理的语法
    mysql存储过程获取sqlstate message_text
    mongoTemplate操作内嵌文档
    mysql索引之七:组合索引中选择合适的索引列顺序
    mongoDB的操作总结
    explain之三:MYSQL EXPLAIN语句的extended 选项学习体会,分析诊断工具之二
    状态模式
    代码重构----使用java有限状态机来消除太多的if else判断
    断路器(CircuitBreaker)设计模式
    断路器之一:Hystrix 使用与分析
  • 原文地址:https://www.cnblogs.com/1234cjq/p/8072892.html
Copyright © 2011-2022 走看看