• 007 整合spring


    一 .概述

      在这里我们不去说shiro的web支持,我们直接进入spring的整合.然后再依次讲解shiro的一些特性.


    二 .环境的配置  

        <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.9.0</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>4.2.5.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>4.2.5.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-orm</artifactId>
                <version>4.2.5.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>4.2.5.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.0.18</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.30</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.4.0</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>1.3.0</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-core</artifactId>
                <version>1.3.0</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-api</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-web</artifactId>
                <version>1.3.0</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.3.0</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-ehcache</artifactId>
                <version>1.3.2</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>javax.servlet.jsp-api</artifactId>
                <version>2.3.1</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.1.3</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.25</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>1.7.25</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>

    web.xml文件

    <servlet>
            <servlet-name>springDispatcherServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:springmvc.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>springDispatcherServlet</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
        <!-- spring -->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring.xml</param-value>
        </context-param>
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <!-- 编码过滤器 -->
        <filter>
            <filter-name>encode</filter-name>
            <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
            <init-param>
                <param-name>encoding</param-name>
                <param-value>utf-8</param-value>
            </init-param>
            <init-param>
                <param-name>forceEncoding</param-name>
                <param-value>true</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>encode</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        <!-- shiro的代理过滤器对象 -->
        <filter>
            <filter-name>shiroFilter</filter-name>
            <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
            <!-- Filter的生命周期由web容器进行管理 -->
            <init-param>
                <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>

    我们重点配置了一个shiro的过滤器.

        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager"></property>
            <!-- 配置登录页面 -->
            <property name="loginUrl" value="/login"></property>
            <!-- 配置未授权页面的路径 -->
            <property name="unauthorizedUrl" value="/unan.jsp"></property>
            <!-- 配置登录成功的页面 -->
            <property name="successUrl" value="/WEB-INF/success.jsp"></property>
            <!-- 配置过滤器链
                这是shiro的web配置的核心
             -->
             <property name="filterChainDefinitions">
                 <value>
                     /login=anon
                     /js/**=anon
                     /**=authc
                 </value>
             </property>
        </bean>
        
        <!-- 配置安全管理器 -->
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <property name="realm" ref="realm"></property>
            <property name="cacheManager" ref="cacheManager"></property>
        </bean>
        <!-- 配置自定义的realm -->
        <bean id="realm" class="com.trek.realm.ShiroRealm">
        </bean>

    上面是shiro的核心配置.

    我们可以看到我们重点配置了一个Filter.

    然后shiro就是按照这个核心的过滤器完成整个权限的认证过程.

    然后我们将之前的Shiro的SecurityManager设置到Shiro之中.


    三 .核心代码

    @ResponseBody
        @RequestMapping(value="/login",method=RequestMethod.POST)
        public Map<String,Object> checkUsernameAndPassword(String username ,String password) {
            //init
            Subject subject = SecurityUtils.getSubject();
            UsernamePasswordToken token = new UsernamePasswordToken(username,password);
            //json
            Map<String,Object> json = new HashMap<String,Object>();
            try {
                subject.login(token); //login
                json.put("status", Boolean.TRUE);
            } catch (AuthenticationException e) {
                logger.error("{}账号,密码为{}验证出现错误",username,password);
                json.put("status", Boolean.FALSE);
                json.put("msg", e.getMessage());
            }
            return json ;
        }
    public class ShiroRealm extends AuthorizingRealm{
        private static final Logger logger = LoggerFactory.getLogger(ShiroRealm.class);
        @Autowired
        private UserDAO userdao;
        
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            UsernamePasswordToken utoken = (UsernamePasswordToken) token;
            String username = utoken.getUsername();
            String password = new String(utoken.getPassword());
            User user = userdao.selectUserByUsername(username);
            if(user == null) {
                throw new UnknownAccountException("账号不正确!");
            }
            if(user.getLocked() == Boolean.TRUE) {
                throw new LockedAccountException("账号被锁定!");
            }
            //密码校验
            SimpleHash hash = new SimpleHash("MD5",username , user.getSalt(),1);
            if(!user.getPassword().equals(hash.toString())) {
                throw new IncorrectCredentialsException("密码不正确");
            }
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user ,password ,getName() );
            return info;
        }
        
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            logger.info("开始授权.....");
            //从PrincipalCollection 中获取主体信息
            //这个主体信息是认证时创建出来的.
            User user = (User) principals.getPrimaryPrincipal();
            Integer userid = user.getId();
            Set<Role> roles = userdao.selectAllRoleByUserId(userid);
            Set<Permission> pers = userdao.selectAllPermissionByUserId(userid);
            
            //创建返回信息
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            //设置角色信息
            if(roles != null && roles.size()>0) {
                Set<String> roleStrings = new HashSet<String>();
                for(Role role : roles) {
                    roleStrings.add(role.getRolename());
                }
                info.setRoles(roleStrings);
            }
            
            //设置权限信息
            if(pers != null && pers.size()>0) {
                Set<String> perStrings = new HashSet<String>();
                for(Permission per : pers) {
                    perStrings.add(per.getPername());
                }
                info.setStringPermissions(perStrings);
            }
            
            return info;
        }

    至于表结构就是基本的RBAC表.

  • 相关阅读:
    登录验证servlet实现
    IOS开发(68)之捕获点击划屏手势
    jquery实现漂浮在网页右侧的qq在线客服插件
    深切缅怀“5.12”特大地震遇难同胞
    PHP实现微信申请退款流程实例源码
    empty和isset的区别
    ThinkPHP中实现微信支付(jsapi支付)流程
    php中正则表达式详解
    PHP与RBAC设计思路讲解与源码
    一起谈.NET技术,VS2010实践RUP4+1架构模型 狼人:
  • 原文地址:https://www.cnblogs.com/trekxu/p/9057731.html
Copyright © 2020-2023  润新知