• springmvc集成shiro例子


    仅供参考

    仅供参考

    登录部分

    代码:

        @RequestMapping(value = "/login", method = RequestMethod.GET)
        @ResponseBody
        public Map<String, Object> login(HttpServletRequest request)
        {
            Map<String, Object> resultMap = new LinkedHashMap<String, Object>();
            try
            {
                ShiroToken token = new ShiroToken("admin", "21232f297a57a5a743894a0e4a801fc3");
                token.setRememberMe(false);
                SecurityUtils.getSubject().login(token);
                ShiroToken token2 = (ShiroToken) SecurityUtils.getSubject().getPrincipal();
    
                logger.info(token2.getUsername() + "," + token2.getPswd());
    
                resultMap.put("status", 200);
                resultMap.put("message", "登录成功");
    
                /**
                 * 获取登录之前的地址
                 */
                SavedRequest savedRequest = WebUtils.getSavedRequest(request);
                String url = null;
                if (null != savedRequest)
                {
                    url = savedRequest.getRequestUrl();
                }
                // 跳转地址
                resultMap.put("back_url", url);
            }
            catch (DisabledAccountException e)
            {
                resultMap.put("status", 500);
                resultMap.put("message", "帐号已经禁用。");
            }
            catch (Exception e)
            {
                resultMap.put("status", 500);
                resultMap.put("message", "帐号或密码错误");
            }
            return resultMap;
        }

    注意几点:

    1、登录密码记得加密,一般存在数据库中的密码是加密过的。

    2、真正开始执行登录操作的是SecurityUtils.getSubject().login(token),这个方法会调用org.apache.shiro.realm.AuthorizingRealm的doGetAuthenticationInfo方法进行登录认证:

    3、出错异常记得捕获

    登录验证部分

    代码如下:

       @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0)
        {
            ShiroToken token = (ShiroToken) arg0;
            String username = token.getUsername();
    
            // 根据username从数据库查找用户,得到密码
            // 假设找到的用户如下
            // User user = userService.findByUsername(username)
            User user = new User();
            user.setName(username);
            user.setPassword("21232f297a57a5a743894a0e4a801fc3"); // 数据库中的密码md5加密的
    
            if (null == user)
            {
                throw new AccountException("username is not exist");
            }
            else if (!user.getPassword().equals(token.getPswd()))
            {
                throw new AccountException("password is not right");
            }
            else
            {
                // 登陆成功
                logger.info("{} login success.", username);
            }
            return new SimpleAuthenticationInfo(arg0, user.getPassword(), username);
        }

    注意几点:

    1、一般会根据username从数据库中查找该用户,得到密码

    2、进行密码校验,判断一致性

    3、根据获取到的用户信息,也可以进行其它判断,如用户是否激活,是否被禁用等

    授权部分

    代码如下:

        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0)
        {
            ShiroToken token = (ShiroToken) SecurityUtils.getSubject().getPrincipal();
            String username = token.getUsername();
            logger.info(username + "授权...");
    
            // 从数据库中查找该用户的角色和权限
            SimpleAuthorizationInfo sainfo = new SimpleAuthorizationInfo();
    
            Set<String> roles = new HashSet<String>();
            roles.add("admin");
            //roles.add("role1");
            Set<String> permissions = new HashSet<String>();
            permissions.add("add");
            permissions.add("delete");
            sainfo.setRoles(roles);
            sainfo.setStringPermissions(permissions);
            return sainfo;
        }

    注意,一般是根据用户名从数据库中查找该用户的角色和权限,进行授权;当然其它途径也是可以的,如webservice接口,配置文件等获取用户权限。

    权限拦截配置

    如下:

        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager"></property>
            <property name="loginUrl" value="/security/view/login"></property>
            <property name="successUrl" value="/successUrl"></property>
            <!-- 用户访问未对其授权的资源时,所显示的连接 -->
            <property name="unauthorizedUrl" value="/unauthorizedUrl"></property>
            <property name="filters">
                <map>
                    <entry key="anyRoles">
                        <bean class="cn.edu.hdu.ssd.core.shiro.AnyRolesAuthorizationFilter" />
                    </entry>
                </map>
            </property>
            <property name="filterChainDefinitions">
                <value>
                    /security/**=anon
                    /test/**=roles[role1]
                    /users/**=anyRoles[admin,role1]
                    /**=authc
                </value>
            </property>
        </bean>

    根据用户的角色或权限来配置对应匹配的访问路径;

    访问路径匹配任意角色

    默认情况下,配置权限控制的时候,如

    /test/**=roles[role1,admin]

    结果是需要用户同时拥有role1和admin权限才能访问/test/**路径,这往往不符合我们的需求,

    大部分情况,我们希望的是用户拥有role1和admin任一角色即可。

    那么可以这样修改,编写一个过滤器:

    public class AnyRolesAuthorizationFilter extends AuthorizationFilter
    {
    
        // private Logger logger =  LoggerFactory.getLogger(ShiroCasAuthFilter.class);
        @Override
        protected boolean isAccessAllowed(ServletRequest req, ServletResponse resp, Object mappedValue)
            throws Exception
        {
            Subject subject = getSubject(req, resp);
            String[] rolesArray = (String[]) mappedValue;
    
            if (rolesArray == null || rolesArray.length == 0)
            {
                return true;
            }
            for (int i = 0; i < rolesArray.length; i++)
            {
                if (subject.hasRole(rolesArray[i]))
                {
                    return true;
                }
            }
            return false;
        }
    }

    配置shiroFilter bean的filters属性,如下,

            <property name="filters">
                <map>
                    <entry key="anyRoles">
                        <bean class="cn.edu.hdu.ssd.core.shiro.AnyRolesAuthorizationFilter" />
                    </entry>
                </map>
            </property>

    最后,权限拦截配置可以这样配:

    /test/**=anyRoles[admin,role1]

    示例源码参考

    https://github.com/peterchenhdu/spring-shiro-demo

    测试

    登录:http://localhost:8080/ssd/security/login ----->角色:admin,用户名:admin,密码:21232f297a57a5a743894a0e4a801fc3
    权限测试:http://localhost:8080/ssd/users ----->访问成功
    权限测试:http://localhost:8080/ssd/test/access ----->访问失败,无访问权限
    换个角色登录,修改UserRealm.java里的角色为roler1,重新登录http://localhost:8080/ssd/security/login
    权限测试:http://localhost:8080/ssd/users ----->访问成功
    权限测试:http://localhost:8080/ssd/test/access ----->访问成功
  • 相关阅读:
    Northwind数据库下载地址
    MSSQL跨服务访问数据库
    MSSQL基于一致性的I/O错误,解决方法之一
    DataGridView单元格ComboBox控件添加事件
    线程安全类 跨线程修改窗体UI
    数据库字段名
    SELECT INTO 和 INSERT INTO SELECT
    链表
    因为数据库正在使用,所以无法获得对数据库的独占访问权
    代替游标的循环
  • 原文地址:https://www.cnblogs.com/chenpi/p/6247956.html
Copyright © 2020-2023  润新知