Geoserver源码解读三 GeoServerBasePage

news2024/11/17 16:19:39

一、概述

        org.geoserver.web.GeoServerBasePage 类,在Geoserver中是所有页面类的基类,也是单独存在的一个主UI界面入口文件。拿到源码后可以在里面进行肆意的魔改,也可以单独创建一个工程写根据它扩展。下面以登录的代码作为切入点,做了个简单的分析。

二、页面内容分析

2.1 本质

import org.apache.wicket.markup.html.WebPage;

public class GeoServerBasePage extends WebPage implements IAjaxIndicatorAware{
}

从类上能看出来是它本质上是个wicket页面

2.2 顶部logo以及登录区

2.2.1 页面logo

<link href="#" rel="shortcut icon" wicket:id="faviconLink"/>
        if (faviconReference == null) {
            faviconReference = new PackageResourceReference(GeoServerBasePage.class, "favicon.ico");
        }
        String faviconUrl = RequestCycle.get().urlFor(faviconReference, null).toString();
        add(new ExternalLink("faviconLink", faviconUrl, null));

可以看出来logo使用的是同级的favicon.ico图片文件

2.2.2 登录区

在html页面中可以找到下面代码,是个wicket,不过主体就是个html

      <div class="button-group selfclear">
          <!--登录表单-->
	      <span wicket:id="loginforms">
	      	<form style="display: inline-block;" wicket:id="loginform" method="post" action="../j_spring_security_check">
	      		<span wicket:id="login.include"></span>
	      		<button class="positive icon" type="submit">
	      			<div><img src="#" wicket:id="link.icon"/><span wicket:id="link.label"></span></div>
	      		</button>
		        <script type="text/javascript">
		            $('input, textarea').placeholder();
		        </script>	      		
	      	</form>
	      </span>
          <!--注销表单-->
	      <span wicket:id="loggedinasform" class="username"><wicket:message key="loggedInAs">Logged in as</wicket:message> <span wicket:id="loggedInUsername">User von Testenheimer</span>.</span>
            <form style="display: inline-block;" wicket:id="logoutform" method="post" action="j_spring_security_logout">
                <button class="positive icon" type="submit">
                    <div><img src="#" wicket:id="link.icon"/><span wicket:id="link.label"></span></div>
                </button>
            </form>
        <span id="localeSwitcher"><wicket:link><img src="img/icons/globe.png"/></wicket:link> <select  wicket:id="localeSwitcher"></select></span>
      </div>

登录表单和注销表单显示的前提条件是用户是否登录,登录的话就显示注销的按钮,没登录的就显示登录表单

在GeoServerBasePage.java中可以看到如下代码,获取当前登录用户并判断当前用户是否是游客权限

        final Authentication user = GeoServerSession.get().getAuthentication();
        final boolean anonymous = user == null || user instanceof AnonymousAuthenticationToken;

最终根据用户控制登录表单的显隐

// 登录显隐
loggedInAsForm.setVisible(!anonymous);
// 注销显隐
logoutForm.setVisible(!anonymous);

2.2.3 登录逻辑

在登录区看到登录表单显隐是根据用户以及用户权限控制,那么登录的逻辑是怎么样的呢

<form style="display: inline-block;" wicket:id="loginform" method="post" action="../j_spring_security_check">      		
</form>

从上面代码可以看到,登录的操作是在j_spring_security_check 中完成的,但它不是个直接的类方法,是spring中默认的登录逻辑,具体来说是spring security 也就是这个东西

    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-web</artifactId>
    </dependency>

据说spring security是个比较落后的技术了,我也没有深入研究过,毕竟geoserver开源了那么久了,有可能在当时也是个比较火的技术。关于spring security我看了一篇(博客)感觉写的不错,感兴趣的可以看看,大致的逻辑是通过重写spring security的登录逻辑实现登录,在geoserver的源码中的org.geoserver.security包中可以看到其具体逻辑

2.2.3.1 过滤器

当请求到达j_spring_security_check时,它首先通过Spring Security的过滤器链,过滤器链中包含了一个或多个认证过滤器,如UsernamePasswordAuthenticationFilter,它负责处理基于表单的认证,在spring 的配置文件中看到登录组件用的过滤器是GeoServerUserNamePasswordAuthenticationFilter

<bean id="geoserverFormLoginButton" class="org.geoserver.web.LoginFormInfo">
		<property name="id" value="geoserverFormLoginButton" />
        <!-- 组件需要的过滤器即登录过滤 -->
		<property name="filterClass" value="org.geoserver.security.filter.GeoServerUserNamePasswordAuthenticationFilter" />
	</bean>
2.2.3.2 认证管理器

过滤器设置了认证管理器AuthenticationManager(下面代码最后一行)

        // add login filter
        UsernamePasswordAuthenticationFilter filter =
                new UsernamePasswordAuthenticationFilter() {
                    @Override
                    protected boolean requiresAuthentication(
                            HttpServletRequest request, HttpServletResponse response) {

                        for (String pathInfo : pathInfos) {
                            if (getRequestPath(request).startsWith(pathInfo)) return true;
                        }
                        return false;
                    }
                };

        filter.setPasswordParameter(upConfig.getPasswordParameterName());
        filter.setUsernameParameter(upConfig.getUsernameParameterName());
        filter.setAuthenticationManager(getSecurityManager().authenticationManager());
2.2.3.3 用户名密码认证

当用户通过登录表单提交用户名和密码时,这些信息会被UsernamePasswordAuthenticationFilter捕获然后创建一个UsernamePasswordAuthenticationToken对象,并将其传递给认证管理器AuthenticationManager。然后会调用配置的AuthenticationProvider

    private AuthenticationManager authMgrProxy =
            new AuthenticationManager() {
                @Override
                public Authentication authenticate(Authentication authentication)
                        throws AuthenticationException {
                    return providerMgr.authenticate(authentication);
                }
            };

其中上述providerMgr就包括UsernamePasswordAuthenticationProviderUsernamePasswordAuthenticationProviderauthenticate方法被调用,以验证用户身份

src/main/java/org/geoserver/security/auth/UsernamePasswordAuthenticationProvider.java

public class UsernamePasswordAuthenticationProvider extends GeoServerAuthenticationProvider{
}

UsernamePasswordAuthenticationProvider中有两个重点

  • 设置UserDetailsService(获取文件、或者数据库中用户数据)
  • 设置加密方式(设计密码的加密方式)

在初始化方法initializeFromConfig中找到下面代码

authProvider = new DaoAuthenticationProvider();
// 设置用户详情Service层
authProvider.setUserDetailsService(userDetailsService)
// 设置加密方式
authProvider.setPasswordEncoder(
                new GeoServerMultiplexingPasswordEncoder(getSecurityManager(), ugService));
2.2.3.3.1 加密方式

关于密码的加密方式,其实geoserver的密码加密方式支持的类型很多(如MD5、SHA-1、BCrypt等),此处默认是混合类型,也就是同时支持多种加密,按理来说加密只能是一种,但geoserver怎么能同时支持多种呢,再往下查源码时就能看到

public String encodePassword(String rawPass, Object salt) throws UnsupportedOperationException {
        for (GeoServerPasswordEncoder enc : encoders) {
            try {
                return enc.encodePassword(rawPass, salt);
            } catch (Exception e) {
                LOG.fine("Password encode failed with " + enc.getName());
            }
        }
        throw new UnsupportedOperationException();
    }

它会循环遍历支持的所有加密方法,会去假设每一种加密方式,直到匹配成功。

2.2.3.3.2 用户信息校验

那么继续看UsernamePasswordAuthenticationProviderauthenticate方法

    @Override
    public Authentication authenticate(Authentication authentication, HttpServletRequest request)
            throws AuthenticationException {
        UsernamePasswordAuthenticationToken auth = null;
        try {
            auth = (UsernamePasswordAuthenticationToken) authProvider.authenticate(authentication);
        }
        return auth;
    }

里面的逻辑很少,主要还是调用了spring security 内置的DaoAuthenticationProvider的authenticate方法,反编译源码后看到图片中的代码

retrieveUser查用户详情的关键就是刚刚在UsernamePasswordAuthenticationProvider设置的UserDetailsService
protected final UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        try {
            UserDetails loadedUser = this.getUserDetailsService().loadUserByUsername(username);
             return loadedUser;
        }
    }

下面那个验证用户名密码的就不说了,就是比较下数据库或者文件中查出来账号密码和用户传过来的是否匹配

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1838887.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CarService的构成和初始化分析

以下分析&#xff0c;基于安卓13的AAOS。 代码构成 packages/services/Car CarService相关代码&#xff0c;主要是在这个目录下 frameworks/opt/car/services 主要是carservice启动相关。 其它目录&#xff1a;audio_policy_configuration.xml和car_audio_configuration.xm…

<Rust><iced>基于rust使用iced构建GUI实例:如何将svg格式转为ico格式图片?

前言 本专栏是Rust实例应用。 环境配置 平台:windows 软件:vscode 语言:rust 库:iced、iced_aw 概述 本文是专栏第4篇实例,依旧是一个图像格式转换程序,基于rust的svg库resvg、图像处理库image以及文件处理库rfd。 流程是先用resvg获取svg图片的数据并将其转为png数据…

llama-factory微调chatglm3

一、定义 案例/多卡 二、实现 案例 1. 下载chatglm3-6b-32k模型 2. 配置数据集微调指令 CUDA_VISIBLE_DEVICES0,1 llamafactory-cli train \--stage sft \--do_train True \--model_name_or_path /home/chatglm3-6b-32k \--finetuning_type lora \--template chatglm3 \--d…

零基础入门学用Arduino 第四部分(三)

重要的内容写在前面&#xff1a; 该系列是以up主太极创客的零基础入门学用Arduino教程为基础制作的学习笔记。个人把这个教程学完之后&#xff0c;整体感觉是很好的&#xff0c;如果有条件的可以先学习一些相关课程&#xff0c;学起来会更加轻松&#xff0c;相关课程有数字电路…

nodejs爬取小红书图片

昨天的文章已经描述了可以抓取评论区内容&#xff0c; 抓取图片内容和抓取评论区的内容基本一致 我们可以看到接口信息中含有图片链接&#xff0c;我们要做的就是爬取图片链接然后下载 这边要用到的模块为const downloadrequire(download) 将爬到的图片链接存放到images数组…

STM8单片机的GPIO口介绍

本篇文章依托于stm8单片机和lora模块 目录 一、GPIO口测试相关硬件电路图 &#xff08;a&#xff09;USB转串口底板PA3控制LED6 (b)Lora模块底板PA3接口 &#xff08;c&#xff09;LED灯电路 二、参考官方例程实现GPIO口的输出 三、GPIO相关函数的了解 &#xff08;1&a…

docker安装使用

文章目录 docker产生的原因传统虚拟机容器化技术 docker组成安装docker镜像加速docker安装过程中遇到的问题以及解决办法Errors during downloading metadata for repository root_:Failed to set locale, defaulting to C.UTF-8 docker产生的原因 传统虚拟机 在不使用docker…

从“野人饭”走红,探索品牌户外化营销趋势丨小红书内容分析

wildeat&#xff0c;户外是人的天性的回归 近来&#xff0c;“wildeat&#xff08;户外野吃&#xff09;”的风潮在小红书逐渐兴起。越来越多的人选择到户外吃一顿&#xff0c;做一次“野人”&#xff0c;主打一个只要氛围到了&#xff0c;就地开饭&#xff0c;不愁吃什么&…

AI智能写作工具, 免费在线智能创作内容网站

对于需要创作内容的同学&#xff0c;选择一款适合自己的AI写作工具可以极大的提高创作效率。下面小编就来和大家分享几款可以生成高质量原创内容的AI写作工具。 1. Kimi智能助手 Kimi智能助手是一款集成了先进算法的AI工具&#xff0c;它能够理解复杂的语言模式&#xff0c;生…

如何用Vue3和ApexCharts打造引人注目的3D径向条形图

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 使用 ApexCharts 构建美观的 Vue.js 径向条形图 应用场景 径向条形图是一种用于可视化单一数据点及其与目标或理想值的关系的图表类型。它在显示进度、完成率或其他类似度量时非常有用。 基本功能 这段代码…

划分子网和构造超网的学习

子网掩码长度&#xff1d;32位 某位&#xff1d;1&#xff1a;IP地址中的对应位为网络号和子网号 某位&#xff1d;0&#xff1a;IP地址中的对应位为主机号 从一个 IP 数据报的首部并无法判断源主机或目的主机所连接的网络是否进行了子网划分。 使用子网掩码(subnet mask)可…

EasyCVR/EasyDSS无人机直播技术助力野生动物监测

近日有新闻报道&#xff0c;一名挖掘机师傅在清理河道时&#xff0c;意外挖出一只稀有的扬子鳄&#xff0c;挖机师傅小心翼翼地将其放在一边&#xff0c;扬子鳄也顺势游回一旁的河道中。 随着人类对自然环境的不断探索和开发&#xff0c;野生动物及其栖息地的保护显得愈发重要。…

AI产品组件——TTS产品

语音合成TTS 序列猴子TTS&#xff0c;每个发音人付费标准不同&#xff0c;通过序列猴子开放平台使用。 微软TTS&#xff0c;采用信用卡后付费模式。Speech Studio&#xff0c;付费模式采用统一付费的形式&#xff0c;音效有一款女声效果逼真。 女声&#xff1a;晓晓&#xff…

三天带你快速入门Transformer,真的太牛了

前言 听说Transformer很火&#xff1f;但感觉它好复杂&#xff1f;别担心&#xff0c;三天时间&#xff0c;你也可以轻松入门Transformer&#xff01; 第一天&#xff0c;我们先来了解Transformer的“骨架”。简单来说&#xff0c;它就像是一个双层机器&#xff0c;上面一层…

mysql5.7windows安装修改密码

mysql5.7windows安装修改密码 1.首先下载Windows 64位安装包2.安装服务3.my.ini4.初始化4.做成Windows服务5.重置密码 1.首先下载Windows 64位安装包 2.安装服务 双击运行安装服务&#xff0c;一直next&#xff1b; 在Choose Setup Type界面中 选择Custom选项&#xff0c;意思…

万界星空科技QMS质量管理介绍

产品的生产质量是企业发展之根本&#xff0c;对所有企业来说&#xff0c;建立完善质量控制体系&#xff0c;对企业生产经营以及发展竞争具有至关重要的影响&#xff0c;可以说是企业质量保证的防火墙。QMS质量管理系统对任何一家企业都具有重要意义&#xff0c;可帮助企业提高生…

nextjs(持续学习中)

return ( <p className{${lusitana.className} text-xl text-gray-800 md:text-3xl md:leading-normal}> Welcome to Acme. This is the example for the{’ } Next.js Learn Course , brought to you by Vercel. ); } 在顶级 /public 文件夹下提供静态资产 **默认 /…

Linux磁盘格式化与重新分区

1.df -BG查看磁盘挂载情况 2.fdisk -l查看磁盘详细信息 3.sudo mkfs.ext4 /path 格式化磁盘 4.挂载格式化后磁盘 挂载成功

《化工设计通讯》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答 问&#xff1a;《化工设计通讯》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的正规学术期刊 问&#xff1a;《化工设计通讯》级别&#xff1f; 答&#xff1a;省级。主办单位&#xff1a;湖南化工设计院有限公司 主管单位&#xff1…

jeecg spring数据源用户名和密码加密 避免明文安全漏洞

1.目的 由于系统部署在互联网&#xff0c;配置文件中的数据库账号密码使用明文&#xff0c;存在安全隐患&#xff0c;做等保测试时要求对其加密。 2.实现方法 Jeecg框架本身有PasswordUtil可以使用PBEWITHMD5andDES进行加密&#xff0c;这里为方便改造&#xff0c;且安全性较…