zoukankan      html  css  js  c++  java
  • spring下配置shiro

    1.web.xml中加入shiro的过滤器:

    <!-- Spring -->
        <!-- 配置Spring配置文件路径 -->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
          classpath*:spring/applicationContext.xml
          classpath*:spring/spring-shiro.xml
        </param-value>
        </context-param>
        <!-- 配置Spring上下文监听器 -->
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <!-- Spring -->
    
    <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>
        </filter-mapping>
    View Code

    2.创建shiro的配置文件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-3.1.xsd">
        
        <!-- 配置进行授权和认证的 Realm -->
        <bean id="myRealm" class="com.wdcloud.wdMaptail.entity.myRealm"/>
        
        <!-- 配置 Shiro 的 SecurityManager Bean. -->
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <property name="cacheManager" ref="cacheManager" />
            <property name="realm" ref="myRealm" />
            <!-- <property name="sessionMode" value="native"/> -->
        </bean>    
        
        <!-- 启用shrio授权注解拦截方式 -->
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <!-- 装配 securityManager -->
            <property name="securityManager" ref="securityManager" />
            <!-- 配置登陆页面 -->
            <property name="loginUrl" value="/index.jsp" />
            <!-- 登陆成功后的一面 -->
            <property name="successUrl" value="/jsp/success.jsp" />
            <!-- 授权失败页面 -->
            <property name="unauthorizedUrl" value="/jsp/unauthorized.jsp" />
            <!-- 具体配置需要拦截哪些 URL, 以及访问对应的 URL 时使用 Shiro 的什么 Filter 进行拦截. -->
            <property name="filterChainDefinitions">
                <value> 
                    /test/dologin.do = anon
                    <!-- /test/save.do请求之允许有save权限的用户访问 -->
                    /test/save.do = perms[save]
                    /index.jsp=anon
                    /jsp/success.jsp=anon
                    /jsp/fail.jsp=anon
                    /jsp/user.jsp = roles[user]
                    /jsp/admin.jsp = roles[admin]
                    /logout = logout                
                    <!--拦截非静态资源的所有请求-->    
                    /** = authc
                </value>
            </property>
        </bean>
    
        <!-- 配置缓存管理器 -->
        <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
            <!-- 指定 ehcache 的配置文件 -->
            <property name="cacheManagerConfigFile" value="classpath:spring/ehcache-shiro.xml" />
        </bean>        
        
        <!-- 配置 Bean 后置处理器: 会自动的调用和 Spring 整合后各个组件的生命周期方法. -->
        <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
    </beans>
    View Code

     shiro权限管理过滤器解释:

    默认过滤器(10个)   
    anon -- org.apache.shiro.web.filter.authc.AnonymousFilter  
    authc -- org.apache.shiro.web.filter.authc.FormAuthenticationFilter  
    authcBasic -- org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter  
    perms -- org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter  
    port -- org.apache.shiro.web.filter.authz.PortFilter  
    rest -- org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter  
    roles -- org.apache.shiro.web.filter.authz.RolesAuthorizationFilter  
    ssl -- org.apache.shiro.web.filter.authz.SslFilter  
    user -- org.apache.shiro.web.filter.authc.UserFilter  
    logout -- org.apache.shiro.web.filter.authc.LogoutFilter  
      
      
    anon:例子/admins/**=anon 没有参数,表示可以匿名使用。   
    authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,没有参数   
    roles:例子/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。   
    perms:例子/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。   
    rest:例子/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。   
    port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString是你访问的url里的?后面的参数。   
    authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证   
    ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https   
    user:例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查 
    View Code

     

    3.创建shiro的缓存配置文件ehcache-shiro.xml

    <ehcache updateCheck="false" name="shiroCache">
    
        <defaultCache
                maxElementsInMemory="10000"
                eternal="false"
                timeToIdleSeconds="120"
                timeToLiveSeconds="120"
                overflowToDisk="false"
                diskPersistent="false"
                diskExpiryThreadIntervalSeconds="120"
                />
    </ehcache>
    View Code

    4.创建shiro的realm类

    public class myRealm extends AuthorizingRealm {
        @Autowired
        private UserServiceImpl userService;
    
        /**
         * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用,负责在应用程序中决定用户的访问控制的方法
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    
            String username = (String) principals.getPrimaryPrincipal();
            SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
            // 根据用户名查询当前用户拥有的角色
            Set<String> roleNames = userService.findRolesByUsername(username);
            // 将角色名称提供给info
            authorizationInfo.setRoles(roleNames);
    
            // 根据用户名查询当前用户权限
            Set<String> permissionNames = userService.findPermissionsByUsername(username);
            // 将权限名称提供给info
            authorizationInfo.setStringPermissions(permissionNames);
    
            return authorizationInfo;
        }
    
        /**
         * 认证回调函数,登录信息和用户验证信息验证
         */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            String username = (String) token.getPrincipal();
            User user = userService.findUserByUsername(username);
            if (user == null) {
                // 用户名不存在抛出异常
                throw new UnknownAccountException();
            }
    
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(),
                    user.getPassword(), getName());
            return authenticationInfo;
    
        }
    
    }
    View Code

    5.创建登陆controller

    @Controller
    @RequestMapping("/test")
    public class LoginAction {
        @Autowired
        private UserServiceImpl userService;
    
        @RequestMapping("/dologin.do")
        public String dologin(@Validated User user, Model model) {
            String info = loginUser(user);
            if (!"SUCC".equals(info)) {
                model.addAttribute("failMsg", "用户不存在或密码错误!");
                return "/jsp/fail";
            } else {
                model.addAttribute("successMsg", "登陆成功!");// 返回到页面说夹带的参数
                model.addAttribute("name", user.getUsername());
                return "/jsp/success";// 返回的页面
            }
        }
    
        @RequestMapping("/logout.do")
        public void logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
            Subject subject = SecurityUtils.getSubject();
            if (subject != null) {
                try {
                    subject.logout();
                } catch (Exception ex) {
                }
            }
            response.sendRedirect("/wdMaptail/index.jsp");
        }
    
        // 用于方法权限测试
        @RequestMapping(value = "/save.do", method = RequestMethod.GET)
        public void save(HttpServletRequest request, HttpServletResponse response) {
            System.out.println("拥有save权限的用户才能访问");
        }
    
        private String loginUser(User user) {
            if (isRelogin(user)) { // 判断是否已登录
                return "SUCC";
            }
    
            return shiroLogin(user); // 调用shiro的登陆验证
        }
    
        private boolean isRelogin(User user) {
            Subject us = SecurityUtils.getSubject();
            if (us.isAuthenticated()) {
                return true; // 参数未改变,无需重新登录,默认为已经登录成功
            }
            return false; // 需要重新登陆
        }
    
        private String shiroLogin(User user) {
            // 组装token,包括客户公司名称、简称、客户编号、用户名称;密码
            UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
            token.setRememberMe(true);
    
            // shiro登陆验证
            try {
                SecurityUtils.getSubject().login(token);
            } catch (UnknownAccountException ex) {
                return "用户不存在或者密码错误!";
            } catch (IncorrectCredentialsException ex) {
                return "用户不存在或者密码错误!";
            } catch (AuthenticationException ex) {
                return ex.getMessage(); // 自定义报错信息
            } catch (Exception ex) {
                ex.printStackTrace();
                return "内部错误,请重试!";
            }
            return "SUCC";
        }
    
    }
    View Code

    6.再贴一个登陆成功后的页面代码,以为里面有Shiro的标签来控制页面的显示,其他页面和dao层代码这里就不写了。

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        ${successMsg } Welcome!
        <shiro:principal />
        <br>
        <br>
    
        <shiro:hasAnyRoles name="user">
            <a href="/WEB-INF/jsp/user.jsp">User Page</a>
        </shiro:hasAnyRoles>
    
        <br>
        <br>
    
        <shiro:hasAnyRoles name="admin">
            <a href="/WEB-INF/jsp/admin.jsp">Admin Page</a>
        </shiro:hasAnyRoles>
    
        <br>
        <br>
        <a href="../test/logout.do">Logout</a>
    </body>
    </html>
    View Code

    shiro标签解释:

    <shiro:authenticated> 登录之后  
    <shiro:notAuthenticated> 不在登录状态时  
    <shiro:guest> 用户在没有RememberMe时  
    <shiro:user> 用户在RememberMe时  
    <shiro:hasAnyRoles name="abc,123" > 在有abc或者123角色时  
    <shiro:hasRole name="abc"> 拥有角色abc  
    <shiro:lacksRole name="abc"> 没有角色abc  
    <shiro:hasPermission name="abc"> 拥有权限abc  
    <shiro:lacksPermission name="abc"> 没有权限abc  
    <shiro:principal> 显示用户登录名 
    View Code

    7.如果在数据库中对密码使用md5加密,想要使用shiro验证的话,需要在realm中添加属性credentialsMatcher,shiro中使用md5加密:

    <bean id="jdbcRealm" class="com.java.shiro.realms.ShiroRealm">
            <property name="credentialsMatcher">
                <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                    <property name="hashAlgorithmName" value="MD5"></property> <!-- 加密算法的名称 -->
                    <property name="hashIterations" value="1024"></property> <!-- 配置加密的次数 -->
                </bean>
            </property>
        </bean>
    View Code

    springboot中添加credentialsMatcher:

    /**
         * 密码匹配凭证管理器
         * @return
         */
        @Bean(name = "hashedCredentialsMatcher")
        public HashedCredentialsMatcher hashedCredentialsMatcher() {
            HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
            hashedCredentialsMatcher.setHashAlgorithmName("MD5");// 散列算法:这里使用MD5算法;
            hashedCredentialsMatcher.setHashIterations(1024);// 散列的次数,比如散列两次,相当于md5(md5(""));
            return hashedCredentialsMatcher;
        }
    
    @Bean(name="myRealm")
        public MyRealm myRealm(HashedCredentialsMatcher hashedCredentialsMatcher,EhCacheManager ehCacheManager) {
            MyRealm myRealm = new MyRealm();
            myRealm.setCacheManager(ehCacheManager);
            myRealm.setCredentialsMatcher(hashedCredentialsMatcher);
            return myRealm;
        }
    View Code

    参考:

    基于spring的shiro配置

    SpringMVC整合Shiro权限框架

    30分钟学会如何使用Shiro

    Spring整合Shiro做权限控制模块详细案例分析

    Shiro-密码的MD5加密

    Springboot+shiro配置笔记+错误小结

  • 相关阅读:
    2017.2.16 开涛shiro教程-第十七章-OAuth2集成(二)客户端
    7.编写Java应用程序。首先,定义一个Print类,它有一个方法void output(int x),如果x的值是1,在控制台打印出大写的英文字母表;如果x的值是2,在 控制台打印出小写的英文字母表。其次,再定义一个主类——TestClass,在主类 的main方法中创建Print类的对象,使用这个对象调用方法output ()来打印出大 小写英文字母表。
    6.编写一个Java应用程序,该应用程序包括2个类:Print类和主类E。Print 类里有一个方法output()功能是输出100 ~ 999之间的所有水仙花数(各位数字的 立方和等于这个三位数本身,如: 371 = 33 + 73 + 13。)在主类E的main方法中来 测试类Print。
    5.编写Java应用程序。首先,定义描述学生的类——Student,包括学号(int)、 姓名(String)、年龄(int)等属性;二个方法:Student(int stuNo,String name,int age) 用于对对象的初始化,outPut()用于输出学生信息。其次,再定义一个主类—— TestClass,在主类的main方法中创建多个Student类的对象,使用这些对象来测 试St
    17.从键盘上输入一个正整数n,请按照以下五行杨辉三角形的显示方式, 输出杨辉三角形的前n行。请采用循环控制语句来实现。 (三角形腰上的数为1,其他位置的数为其上一行相邻两个数之和。) 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1
    16.按要求编写Java应用程序。 编写一个名为Test的主类,类中只有一个主方法; 在主方法中定义一个大小为50的一维整型数组,数组名为x,数组中存放着{1, 3,5,…,99}输出这个数组中的所有元素,每输出十个换一行;在主方法中定义一 个大小为10*10的二维字符型数组,数组名为y,正反对角线上存的是‘*’,其余 位置存的是‘#’;输出这个数组中的所有元素。
    15.找出如下数组中最大的元素和最小的元素, a[][]={{3,2,6},{6,8,2,10},{5},{12,3,23}}
    已知2个一维数组:a[]={3,4,5,6,7},b[]={1,2,3,4,5,6,7};把数组a与数组b 对应的元素乘积再赋值给数组b,如:b[2]=a[2]*b[2];最后输出数组b的元素。
    2.采用字符的移位方式实现字符文本加密解密。
    1. 用自己的算法实现startsWith和endsWith功能。
  • 原文地址:https://www.cnblogs.com/Jason-Xiang/p/6649956.html
Copyright © 2011-2022 走看看