美文网首页
SpringMVC 整合 Shiro 登录验证的简单实现

SpringMVC 整合 Shiro 登录验证的简单实现

作者: 年少懵懂丶流年梦 | 来源:发表于2017-06-23 15:15 被阅读149次
    添加依赖
        <!-- apache共公包 -->
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.2</version>
            </dependency>
            <dependency>
                <groupId>commons-beanutils</groupId>
                <artifactId>commons-beanutils</artifactId>
                <version>1.9.2</version>
            </dependency>
            
            <!-- Shiro -->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.2.1</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-core</artifactId>
                <version>1.2.1</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-web</artifactId>
                <version>1.2.1</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-ehcache</artifactId>
                <version>1.2.1</version>
            </dependency>
    

    commons-beanutils 要注意,没有引入这玩意儿,报错,搞了半天。

    排错时 要注意 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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd">
        
        <description>Shiro Configuration</description>
        
        <!-- 用户授权信息 -->
        <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager"></bean>
    
        <!-- 必须的 -->
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <property name="realm" ref="myShiroRealm"></property>
            <property name="cacheManager" ref="cacheManager"></property>
        </bean>
        
        <!-- 自定义的 Realm -->
        <bean id="myShiroRealm" class="com.meng.realm.MyShiroRealm">
            <property name="cacheManager" ref="cacheManager"></property>
        </bean>
        
        <!-- Shiro Filter -->
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager"></property>
            <property name="loginUrl" value="/test/login"></property>
            <property name="successUrl" value="/test/show"></property>
            <!-- 没有权限跳转的页面 -->
            <property name="unauthorizedUrl" value="/error"></property>
            <property name="filterChainDefinitions">
                <value>
                    /index.jsp = anon
                    /test/match = anon
                    /test/login = authc
                    /test/show = authc
                    /test/error = anon
                    /test/captcha-image = anon
                    /test/code = anon
                    /test/codeCheck = anon
                    /test/loginCheck = anon
                    /test/logout = authc
                    /** = authc
                    / = authc
                </value>
            </property>
        </bean>
        
        
        <!--  -->
        <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean>
        
        <!-- AOP 式方法级权限检查 -->
        <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
            depends-on="lifecycleBeanPostProcessor">
            <property name="proxyTargetClass" value="true"></property>
        </bean>
        
        <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
            <property name="securityManager" ref="securityManager"></property>
        </bean>
    </beans>
    
    

    anon:匿名访问,不进行 shiro 的校验
    authc:需要获得权限才可以访问

    自定义的 Realm
    public class MyShiroRealm extends AuthorizingRealm {
        
        // 假定一个校验数据
        private static final String USER_NAME = "xiaoli";
        private static final String PASS_WORD = "123456";
        /**
         * 授权
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
            
            Set<String> roleNames = new HashSet<>();
            Set<String> permissions = new HashSet<>();
            
            // 添加角色
            roleNames.add("administrator");
            // 添加权限
            permissions.add("test/newPage");
            
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);
            
            info.setStringPermissions(permissions);
            
            return info;
        }
        
        /**
         * 登录验证
         */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
            
            UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
            if (token.getUsername().equals(USER_NAME)) {
                return new SimpleAuthenticationInfo(USER_NAME, PASS_WORD, getName());
            } else {
                throw new AuthenticationException();
            }
        }
    
    }
    
    在 web.xml 中添加
        <!-- shiro 配置文件引入 -->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-shiro.xml</param-value>
        </context-param>
    
        <!-- shiro 过滤器 -->
        <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>/*</url-pattern>
            <dispatcher>REQUEST</dispatcher> 
            <dispatcher>FORWARD</dispatcher> 
            <dispatcher>INCLUDE</dispatcher> 
            <dispatcher>ERROR</dispatcher> 
        </filter-mapping>
    
    Controller
    @Controller
    @RequestMapping("/test")
    public class MainController {
    
        @RequestMapping("/login")
        public String loginPage() {
            return "index";
        }
        
        @RequestMapping("/newPage")
        public ModelAndView newPage() {
            ModelAndView nav = new ModelAndView("newPage");
            return nav;
        }
    
        /**
         * 登录校验
         * @param request
         * @param userName
         * @param password
         * @return
         */
        @RequestMapping("/loginCheck")
        public ModelAndView loginCheck(HttpServletRequest request, @RequestParam("userName")String userName, 
                @RequestParam("password")String password) {
            
            ModelAndView nav = new ModelAndView();
            Map<String, Object> result = new HashMap<>();
            try {
                UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
                Subject subject = SecurityUtils.getSubject();
                System.out.println(subject.isAuthenticated());
                if (!subject.isAuthenticated()) {
                    token.setRememberMe(true);
                    subject.login(token);
                    nav.setViewName("json");
                    return nav;
                } else {
                    nav.setViewName("error");
                    return nav;
                }
                
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
        
        /**
         * 退出登录状态
         * @return
         */
        @RequestMapping("/logout")
        @ResponseBody
        public String logout() {
            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            Subject subject = SecurityUtils.getSubject();
            subject.logout();
            return JSONUtils.toJSONString(result);
        }
    }
    

    相关文章

      网友评论

          本文标题:SpringMVC 整合 Shiro 登录验证的简单实现

          本文链接:https://www.haomeiwen.com/subject/peeccxtx.html