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表.

猜你喜欢

转载自www.cnblogs.com/trekxu/p/9057731.html
007
今日推荐