认证中心(单点登陆)之SpringSecurity+OAuth2

认证和授权的概念
认证解决“我是谁”问题
在这里插入图片描述
授权解决“我能作什么”的问题在这里插入图片描述
Filter和FilterChain
任何Spring Web应用本质上只是一个Servlet,Security Filter在HTTP请求到达你的Controller之前过滤每一个传入的
Http请求。pring Security 实现认证和授权的地层机制
浏览器->Security Filter ->Tomcat ->检查用户是否认证->没有认证401/403 认证到DispatcherServlet->RestController、Controller
在这里插入图片描述
FilterChain

在这里插入图片描述

在这里插入图片描述
常见的内建过滤器
在这里插入图片描述

Http
熟悉Http的请求/响应结构
Filter和客户端交互(获取数据/返回数据)是通过请求/响应中的字段完成的
在这里插入图片描述

 */
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        http
//                .formLogin(Customizer.withDefaults())
//                .authorizeRequests(req -> req.antMatchers("/api/greeting")
//                        .authenticated());
        http.authorizeRequests()
                .anyRequest().authenticated() //任何请求都会进行认证
                .and()
                .formLogin() //启用内建的登陆界面
                .and()
                .httpBasic(); //使用Http Basic Auth认证
    }
}

密码进化史
明文-》哈希-》加盐-》自适应

SpringSecurity核心组件
SecurityContext :是用来存储当前认证的用户的详细信息
SecurityContextHolder : 是一个工具类,它提供了对安全上下文的访问。默认情况下,它使用一个ThreadLocal对象来存储安全上下文,这意味着它是线程安全的。
Authentication:存储了当前用户(与应用程序交互的主体)的详细信息,它是Spring认证体系的核心元素
Principal可以理解为用户的信息(比较简单的情况下,有可能是用户名)
Credentials 可以理解为密码
Authorites 可以理解为权限

UserDetailService和UserDetails
通常的场景下用户是具备一系列属性约束
在这里插入图片描述

JWT是什么

JWT是Json Web Token的缩写,基于RFC 7159标准定义,可以安全传输的小巧和包含的JSON对象,
使用数字签名的所以是可信任的和安全的,使用HMAC 算法进行加密火灾RSA算法加密

JWT的工作流程
在这里插入图片描述
访问令牌和刷新令牌
访问令牌:生命周期要短,一般在几分钟到几小时
刷新令牌:生命周期会长,应该在几到不超过一年
令牌i如何存放:理论上说,直接存放在store中最安全,但刷新浏览器会有重新登陆的行为,如果可以由服务器端直接设置在Cookie中也是比较安全的,都不适合的场景下建议加密后存在SessionStorage中

多因子验证

TOTP-基于时间的一次性密码
在这里插入图片描述授权Authorization

在这里插入图片描述
安全表达式
在这里插入图片描述

# MCloud - OAuth2 认证中心 [![Build Status](https://www.travis-ci.org/heyuxian/mcloud-oauth2-server.svg?branch=master)](https://www.travis-ci.org/heyuxian/mcloud-oauth2-server) [![Coverage Status](https://coveralls.io/repos/github/heyuxian/mcloud-oauth2-server/badge.svg?branch=master)](https://coveralls.io/github/heyuxian/mcloud-oauth2-server?branch=master) [![License](https://img.shields.io/badge/License-Apache 2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) ## 简介 `mcloud-oauth-server` 基于**Spring OAuth2**,实现了**OAuth2**认证服务器以及资源服务器,并以 **Restful API** 的方式提供了**OAuth** 客户端以及用户的管理功能。 项目中主要使用了以下技术: - **Java8** - **Spring 相关** Spring, Spring Mvc, Spring Cloud, Spring data jpa, Spring Boot,Hibernate - **mapstruct** 主要用于DTO 与 Entity 之间的转换 - **flywaydb** 以版本化的方式管理数据库脚本 - **thymeleaf** 模板框架,用于实现后台管理界面 - **Redis** 主要用作缓存实现 (暂未实现) - **lombok** ## 认证流程 **OAuth2**认证流程可参考博客 [理解OAuth 2.0](http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html) ,此处不再赘述。 ## Features - **认证服务器** 使用Spring Security 结合 JWT Token 实现认证服务,提供了功能完整的 OAuth2 认证服务器。 - **资源服务器** 实现了以下两种方式进行OAuth2 相关资源的管理 - 以 RestAPI 形式提供服务来管理资源:`http://localhost:8043/uaa/swagger-ui.html` - 以 Thymeleaf + [AdminBSBMaterialDesign](https://github.com/gurayyarar/AdminBSBMaterialDesign) 实现的管理端: ​ **用户端** ![image](https://user-images.githubusercontent.com/30259465/33719089-a021befc-db9a-11e7-9a59-179f531dcfe4.png) **管理员** ![image](https://user-images.githubusercontent.com/30259465/33719145-c7c0af54-db9a-11e7-8c52-f92df2cdd7a1.png) ## 快速使用 **创建数据库** 请使用 mysql 客户端或是其他你喜欢的工具创建数据库,默认的数据库名称为 `db_oauth` **使用flywaydb初始化数据库** 修改 `pom.xml`中 **flywaydb** 插件的数据库名,用户名以及密码: **pom.xml** ```xml <plugin> <groupId>org.flywaydb</groupId> <artifactId>flyway-maven-plugin</artifactId> <version>4.2.0</version> <configuration> <user>root</user> <password>你的数据库密码</password> <driver>com.mysql.jdbc.Driver</driver> <url>jdbc:mysql://localhost:3306/数据库名称</url> </configuration> </plugin> ``` 修改相关配置之后,请在项目根目录下执行maven命令: ``` mvn flyway:clean flyway:migrate ``` 修改项目的数据库配置: **application.yml** ```yaml spring: datasource: url: jdbc:mysql://localhost/数据库名称 username: 用户 password: 密码 driver-class-name: com.mysql.jdbc.Driver ``` **启动OAuth2认证服务** 所有准备工作已经完成,现在,让我们启动服务,在项目根目录下运行maven命令: ``` mvn clean install mvn spring-boot:run ``` 如果你使用的是 Idea 或 eclipse 开发,请直接运行 **OAuthServerApplication** 这个方法即可启动服务。 **访问地址** ``` http://localhost:8043/uaa/swagger-ui.html ``` ![uaa](https://user-images.githubusercontent.com/30259465/31441550-16f2053e-aec6-11e7-9568-93cd35dbc1dd.png) ## 使用 Postman 调试API **前提:** 了解Postman并且安装了 **Chrome** 的 **Postman** 插件 首先自然是启动服务,然后我们在Postman中请求 `http://localhost:8043/uaa/api/v1/users/` ,此时因为还未进行认证,所以服务器返回的是 `401` 的状态码: ![OAuth fail](https://user-images.githubusercontent.com/30259465/31854106-e2270cf6-b6c6-11e7-91e3-f66ec6fef9fd.png) 现在我们通过Postman 自带的OAuth认证功能进行认证: ![qq 20171022011928](https://user-images.githubusercontent.com/30259465/31854237-11da1e38-b6c8-11e7-90b0-40dc54325b67.png) ![qq 20171022012054](https://user-images.githubusercontent.com/30259465/31854178-c1ad282e-b6c7-11e7-95a8-e2b5b006fcab.png) 相关项: - **Token Name** access_token - **Auth URL**: http://localhost:8043/uaa/oauth/authorize - **Access Token URL**: http://localhost:8043/uaa/oauth/token - **Client ID**: mcloud-blog - **Client Secret**: 123456 - **Scope**: 可以为空,此处不填 - **Grant Type**: Authorization code ![qq 20171126221612](https://user-images.githubusercontent.com/30259465/33240822-6c0d75ee-d2f7-11e7-810c-5dd523714c86.jpg) 默认用户: - **用户名** user - **密码** 123456 ![qq 20171022012701](https://user-images.githubusercontent.com/30259465/31854253-51b0a55e-b6c8-11e7-8415-d0ff4a242a85.png) 当我们授权之后,就可以得到 **access_token**,此时选中并点击 Use Token,然后我们再次访问之前无权限的 API ![qq 20171022013209](https://user-images.githubusercontent.com/30259465/31854294-d78b8fae-b6c8-11e7-8c77-46878e9159ef.png) 服务器已成功返回 `200` 的状态码,并返回了用户列表。 ## 其他 1. 因本项目使用了 **lombok** 进行开发,在开发之前需要安装插件,若使用的是 **IDEA** 进行开发,请自行搜索并安装 **lombok** 插件,否则会导致编译错误 2. 若是进行二次开发,请替换 `keystore.jks` **(非常重要)** ,否则会导致安全风险,`keystore.jks` 可使用jdk 工具生成,也可自行使用其他工具生成非对称密钥对。 ## 问题及建议 如果你有任何好的意见以及建议,请提 [Issue](https://github.com/heyuxian/mcloud-oauth2-server/issues/new)。 如果你觉得此项目对你有所帮助,欢迎点赞支持。
<think>我们面对的问题:在JSON地图数据中找不到指定的经纬度中心点信息,如何解决? 根据引用内容,我们可以获取到一些思路: 1. 引用[1]提到,我们可以从JSON中获取四个点(最西、最东、最南、最北)来组成一个矩形区域(东北和西南两个点)。那么,如果我们需要中心点,可以通过计算这两个点的中心来得到。 2. 引用[5]提到了关于经纬度过滤数据的规则节点配置,其中涉及到了圆形和多边形区域的处理,以及如何从元数据中获取范围信息。这启发我们,如果数据中存储了范围(比如矩形边界),我们可以计算出中心点。 因此,解决思路如下: 如果JSON数据中提供了矩形区域的边界点(如西南角和东北角),我们可以通过计算这两个点的中间点来得到中心点坐标。 具体计算方法: 中心点经度 = (西南角经度 + 东北角经度) / 2 中心点纬度 = (西南角纬度 + 东北角纬度) / 2 但是注意:这种方法适用于矩形区域,如果是其他形状(如不规则多边形),则可能需要计算多边形的几何中心(质心)。 步骤: 1. 从JSON数据中解析出矩形区域的西南角和东北角坐标(即minLng, minLat, maxLng, maxLat)。 2. 计算中心点: 中心经度 = (minLng + maxLng) / 2 中心纬度 = (minLat + maxLat) / 2 如果JSON数据中不是矩形区域,而是多边形区域(由多个点组成),那么计算中心点的方法如下: 中心经度 = 所有顶点经度的平均值 中心纬度 = 所有顶点纬度的平均值 但是,引用[1]中只提供了矩形区域的两个点,所以我们先按照矩形区域处理。 如果JSON数据中连矩形区域的两个点也没有,那么可能需要从其他途径获取,或者根据实际需求采用其他方法(如引用[3]提到的坐标纠偏,但这里我们不需要纠偏,只需要中心点)。 根据引用[2],我们了解到获取地理边界数据可能比较困难,所以如果JSON数据中确实没有中心点信息,我们只能通过计算边界点来得到中心点。 因此,解决方案如下: 1. 检查JSON数据中是否直接提供了中心点坐标。如果有,直接使用。 2. 如果没有,检查是否有矩形边界(西南角和东北角): 如果有,则按照上述矩形中心计算方法计算。 3. 如果只有多边形边界(多个点): 则计算所有点的经度平均值作为中心经度,纬度平均值作为中心纬度。 4. 如果都没有,则可能需要从其他数据源获取中心点,或者根据实际情况(如引用[3]提到的坐标偏移)进行转换,但这里我们只需要计算几何中心,所以不考虑偏移。 注意:由于地球是球面,这种方法在区域较大时(比如跨越多个经度带)可能不精确,但对于小区域(如一个城市内的区域)可以接受。 代码示例(JavaScript): 假设我们有一个JSON对象,包含一个矩形区域的边界: ```json { "southwest": { "lat": 35.950, "lng": 120.000 }, "northeast": { "lat": 36.200, "lng": 120.300 } } ``` 计算中心点: ```javascript function calculateCenter(bounds) { const center = { lng: (bounds.southwest.lng + bounds.northeast.lng) / 2, lat: (bounds.southwest.lat + bounds.northeast.lat) / 2 }; return center; } ``` 如果是多边形(由多个点组成的数组): ```javascript function calculatePolygonCenter(points) { let sumLng = 0; let sumLat = 0; for (let i = 0; i < points.length; i++) { sumLng += points[i].lng; sumLat += points[i].lat; } return { lng: sumLng / points.length, lat: sumLat / points.length }; } ``` 注意:多边形中心点计算(简单平均)只适用于凸多边形,对于凹多边形可能不准确。更准确的方法是计算多边形的质心,但上述方法在大多数情况下可以接受。 另外,引用[4]中提到,地图应用中可能需要获取用户绘制的图形的坐标信息,这包括矩形、多边形、圆形等。如果我们的JSON数据是用户绘制的图形,那么我们可以按照上述方法计算中心点。 总结:当JSON地图数据缺少经纬度中心点信息时,我们可以通过计算边界点(矩形或多边形)来得到中心点。 如果问题中的JSON数据是类似于引用[1]中的矩形边界,那么我们可以直接计算矩形中心。如果是其他形状,则采用对应的计算方法。 如果问题中的JSON数据是引用[5]中提到的规则节点配置中的多边形定义(格式为:[[lat1, lon1],[lat2, lon2],...]),那么我们可以用多边形中心计算方法。 因此,解决方案的核心是:根据可用的边界信息计算中心点。</think>### 解决JSON地图数据缺少经纬度中心点问题 当JSON地图数据缺少经纬度中心点信息时,可以通过以下方法解决: #### 1. **计算矩形区域的几何中心** 如果JSON数据包含矩形区域的边界坐标(如西南角和东北角),可直接计算中心点: $$ \text{中心经度} = \frac{\text{西南经度} + \text{东北经度}}{2}, \quad \text{中心纬度} = \frac{\text{西南纬度} + \text{东北纬度}}{2} $$ ```json // 输入示例 { "southwest": {"lat": 35.950, "lng": 120.000}, "northeast": {"lat": 36.200, "lng": 120.300} } // 计算结果 "center": { "lat": (35.950 + 36.200) / 2, // 36.075 "lng": (120.000 + 120.300) / 2 // 120.150 } ``` [^1] #### 2. **计算多边形区域的质心** 对于不规则多边形(如镇街边界),通过顶点坐标计算质心: $$ \text{质心经度} = \frac{\sum \text{经度}_i}{n}, \quad \text{质心纬度} = \frac{\sum \text{纬度}_i}{n} $$ ```python # Python计算示例 points = [[lat1, lng1], [lat2, lng2], ...] # 多边形顶点 centroid = { "lat": sum(p[0] for p in points) / len(points), "lng": sum(p[1] for p in points) / len(points) } ``` [^2] #### 3. **使用第三方地理工具生成** - **GIS软件**:用QGIS、ArcGIS导入GeoJSON边界数据,自动计算质心坐标 - **在线工具**:如geojson.io上传数据后获取中心点 - **API服务**:调用地图API(如百度/高德)的`getBounds().getCenter()`方法[^4] #### 4. **坐标纠偏处理** 若数据源使用加密坐标系(如GCJ-02),需转换为标准WGS-84坐标: ```c++ // C++示例(参考Qt地图应用) QPointF convertCoord(QPointF point) { // GCJ02转WGS84纠偏算法实现 return corrected_point; } ``` [^3] #### 5. **动态计算覆盖物中心** 在地图应用中,可通过遍历覆盖物实时计算中心点: ```javascript // JavaScript示例(百度地图API) const overlays = map.getOverlays(); let points = []; overlays.forEach(overlay => { if (overlay instanceof BMap.Polygon) { points = points.concat(overlay.getPath()); } }); const center = calculateCentroid(points); // 调用质心计算函数 ``` [^4] #### 6. **规则引擎辅助计算** 在IoT系统中(如ThingsBoard),配置规则节点自动计算: ```json { "type": "geofencing_filter", "latitudeKey": "deviceLat", "longitudeKey": "deviceLng", "outputCenterKey": "areaCenter" // 输出中心点 } ``` [^5] --- ### 实施建议 1. **优先检查原始数据**:确认是否遗漏了中心点字段 2. **小区域**:直接采用几何中心计算(方法1) 3. **复杂多边形**:使用质心算法(方法2)或GIS工具 4. **实时应用**:结合地图API动态计算(方法5) 5. **坐标系统一**:确保所有坐标使用同一标准(WGS-84)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值