基于springside4 的app token登录鉴权

从零到一:如何用YOLOv8和PyQt5打造你的第一个花卉识别桌面应用 本文详细介绍了如何使用YOLOv8和PyQt5从零开始构建一个花卉识别桌面应用。涵盖环境搭建、数据准备、模型训练、界面设计、模型集成与性能优化等全流程,帮助开发者快速掌握深度学习目标识别技术的实际应用。 阅读详情

       很多公司app客户端和服务端通讯是基于socket自定义私有协议,但对于创业型公司和需要快速搭建app原型的公司,http通讯是比较好的选择,开发效率高,http协议会比socket协议通信慢,且容易被刷协议和截取数据包。那么基于http协议的通信,登录和鉴权是比较重要的环节。最近在研究springside4,shiro,基于这些框架搭建了一套app http登录和鉴权。

下图先介绍整个逻辑流程:



登录服务端代码:

@Controller

@RequestMapping(value = "/loginuser")

public classUserLogin {

 

   @Autowired

   protected AccountServiceaccountService;

 

   @Autowired

   private CacheManagerehcacheManager;

 

   /**

    * 设定安全的密码,生成随机的salt并经过1024次sha-1 hash

    */

   private StringentryptPassword(String salt,String plainPassWord) {

 

      byte[] decodeSalt=Encodes.decodeHex(salt);

      byte[] hashPassword =Digests.sha1(plainPassWord.getBytes(), decodeSalt, Constants.HASH_INTERATIONS);

      return Encodes.encodeHex(hashPassword);

   }

   //@RequestMapping(value = "/loginUser", method= RequestMethod.POST)

   @RequestMapping(value = "/{username}/{password}", method = RequestMethod.GET)

   @ResponseBody

   public String log(@PathVariable("username")String userName,@PathVariable("password") String passWord) {

 

      //根据用户名查找数据库

      Useruser = accountService.findUserByLoginName(userName);

      if (user !=null) {

         if(user.getStatus().equals("disabled")) {

            throw newDisabledAccountException();

         }

         //数据库存的密码为加密后的,需要把客户端传过来的密码明文进行加密

         StringdescPassWord=entryptPassword(user.getSalt(),passWord);

         if(user.getPassword().equals(descPassWord))

         {

            //根据KEY,用户ID,当前时间戳生成token

            StringclientToken=HmacSHA256Utils.digest(Constants.KEY, String.valueOf(user.getId()+System.currentTimeMillis()));

           

            //存放在ehcache,可以改为存放在redis

            Elementelement = newElement(user.getId(), clientToken);

            Cachecache=ehcacheManager.getCache(Constants.LOGIN_TOKEN_CACHE_NAME);

            cache.put(element);

            //返回token给客户端

            return clientToken;

         }

         else

            return null;

      } 

      else

         return null;

    

   }

}

 

 
public class Constants {
    public static final String PARAM_DIGEST = "digest";
    public static final String PARAM_USERNAME = "username";
    public static final String PARAM_ID = "id";

    public static final String LOGIN_TOKEN_CACHE_NAME = "logintoken";

    //摘要,用来加密生成token
    public static String KEY="qwertyasdfoimdfdk";

    public static final String HASH_ALGORITHM = "SHA-1";
    public static final int HASH_INTERATIONS = 1024;
}

 

服务端鉴权使用filter组装数据后委托shiro 的realm处理

 

public classStatelessAuthcFilterextendsAccessControlFilter {

 

      @Autowired

      private CacheManagerehcacheManager;

  

      @Override

       protected boolean isAccessAllowed(ServletRequestrequest, ServletResponse response, Object mappedValue)throws Exception {

           return false;

       }

 

       @Override

       protected boolean onAccessDenied(ServletRequestrequest, ServletResponse response)throws Exception {

           //客户端的url的数字签名

           String clientDigest =request.getParameter(Constants.PARAM_DIGEST);

           //2、客户端传入的用户身份

           String username =request.getParameter(Constants.PARAM_USERNAME);

           String id =request.getParameter(Constants.PARAM_ID);         

          

           HttpServletRequesthttpRequest=(HttpServletRequest) request;        

           //删除掉URL的数字签名

           String digestParm="digest="+clientDigest;

           String url=httpRequest.getRequestURL()+"?"+httpRequest.getQueryString().replace("&"+digestParm,"").replace(digestParm,"");

              

           //4、生成无状态Token

           StatelessToken token = new StatelessToken(Long.parseLong(id),username,url, clientDigest);

 

           try {

               //5、委托给Realm进行登录

               getSubject(request,response).login(token);

           } catch (Exception e) {

               e.printStackTrace();

               onLoginFail(response); //6、登录失败

               return false;

           }

           return true;

       }

 

       //登录失败时默认返回401状态码

       private void onLoginFail(ServletResponse response) throws IOException {

           HttpServletResponse httpResponse =(HttpServletResponse) response;

          httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);

           httpResponse.getWriter().write("login error");

       }

}

 

 

 

public classStatelessRealm extends AuthorizingRealm {

   protected AccountServiceaccountService;

 

   @Autowired

   private CacheManagerehcacheManager;

   @Override

   publicbooleansupports(AuthenticationToken token) {

        //仅支持StatelessToken类型的Token

        return tokeninstanceof StatelessToken;

   }

   @Override

   protectedAuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        //根据用户名查找角色,请根据需求实现

        SimpleAuthorizationInfoauthorizationInfo =  newSimpleAuthorizationInfo();

        authorizationInfo.addRole("admin");

        return authorizationInfo;

   }

   @Override

   protectedAuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)throws AuthenticationException{

        StatelessToken statelessToken =(StatelessToken) token;

        String username =statelessToken.getUsername();//用户名

        long id=statelessToken.getId();//用户ID

        Cache cache=ehcacheManager.getCache(Constants.LOGIN_TOKEN_CACHE_NAME);

        Element tokenElement=cache.get(id);

        String strtoken=(String)tokenElement.getObjectValue();

       

        //在服务器端生成客户端参数消息摘要

        String url=statelessToken.getUrl();

        

        String serverDigest = HmacSHA256Utils.digest(strtoken,url);

        System.out.println("ClientDigest:"+statelessToken.getClientDigest());

        System.out.println("serverDigest"+serverDigest);

        //然后进行客户端消息摘要和服务器端消息摘要的匹配

        return new SimpleAuthenticationInfo(

                username,

                serverDigest,

                getName());

         

   }

}

 

 

 

客户端测试代码如下

 

/**

 * Hello world!

 *

 */

public classApp

{

   static RestTemplaterestTemplate =new RestTemplate();

   publicstaticfinalStringPARAM_DIGEST="digest";

   publicstaticfinalStringPARAM_USERNAME="username";   

   public static String userName="admin";

   public static String passWord="admin";

   public static String userId="1";

   publicstaticvoidmain( String[] args )

   {

     

      //登录获取token

        String token =login(); 

       

        MultiValueMap<String, String>params = newLinkedMultiValueMap<String, String>(); 

        params.add(PARAM_USERNAME,userName);

        params.add("id", userId); 

 

        //构造请求URL

        String url = UriComponentsBuilder 

                .fromHttpUrl("http://localhost:8080/showcase/api/v1/user/1.json") 

               .queryParams(params).build().toUriString();

        //对URL进行签名

        String digest=HmacSHA256Utils.digest(token,url);

       

        //在URL上带上签名

        params.add(PARAM_DIGEST, digest);

        url= UriComponentsBuilder 

                .fromHttpUrl("http://localhost:8080/showcase/api/v1/user/1.json") 

               .queryParams(params).build().toUriString(); 

       

        System.out.println("url:"+url);

        ResponseEntity<String>responseEntity = restTemplate.getForEntity(url, String.class);

        System.out.println("responseEntity:"+responseEntity.getBody());

  

   }

   

   /**

     * 登录返回token

     * @return

     */

   publicstaticString login()

   {

 

      String loginUrl="http://localhost:8080/showcase/loginuser/"+userName+"/"+passWord;  

        ResponseEntity<String>responseEntity = restTemplate.getForEntity(loginUrl, String.class);

        return (String)responseEntity.getBody();       

   }

}

Android15车载系统开机冷启动流程源码解析 本文主要介绍Android15车机系统开机冷启动的流程,暂不包含bootloader,仅从kernel开始直至Launcher首页展示。 阅读详情

相关推荐

ffmpeg中av_read_frame阻塞的原因与解决方案

最近用到ffmpeg,想要av_read_frame立即返回,但是看网上的博客,都没有详细的解说,那就自己看源码。 两种方法: 设置回调打断函数和设置超时 超时,但是如果只设置该参数,依然会在av_read_frame中阻塞, av_dict_set(&inputDic, "stimeout", "2*1000*1000", 0); // milliseconds //打断回调 m_avformatCtx->interrupt_callback.callback = interru

weixin_43360707的博客 1万+

安卓鉴权方式的总结

利用服务器端的session(会话)和浏览器端的cookie来实现前后端的认证,由于http请求时是无状态的,服务器正常情况下是不知道当前请求之前有没有来过, 这个时候我们如果要记录状态,就需要在服务器端创建一个会话(session),将同一个客户端的请求都维护在各自的会话中,每当请求到达服务器端的时候, 先去查一下该客户端有没有在服务器端创建session,如果有则已经认证成功了,否则就没有认证。收集生物识别数据:在进行生物识别鉴权之前,需要先收集用户的生物识别数据,例如指纹、面部、虹膜等。

leidashuaige的专栏 1465

从SPI协议到文件系统:手把手教你用HAL库给W25Q16移植FATFS(附扇区管理优化方案)

本文详细介绍了如何在STM32平台上,通过HAL库的SPI接口为W25Q16 Flash芯片移植FATFS文件系统。文章从SPI通信基础讲起,深入解析了FATFS底层驱动(diskio.c)的移植要点,并重点探讨了针对W25Q16的4KB物理扇区特性进行扇区管理优化的两种方案,旨在帮助开发者构建稳定高效的文件存储方案。

happy2的博客 1044

认证和鉴权

认证鉴权是应用系统的基础需求,在微服务结构中服务分散,通常在 API 网关中进行身份验证和鉴权。当用户身份认证授权后,每次外部 API 的请求集中在网关中进行验证鉴权,不仅性能好,维护方便,还能让其余服务更加专注自己的业务。微服务中常用的认证鉴权解决方案为 jwt 、共享 session、 网关 oauth2 这三种。

gzl_1984的博客 2372

【20230415】Ubuntu22.04双屏显示触屏设置,解决触摸点和响应位置不一致的问题

双屏显示时,如果存在一个触摸屏,有可能会出现触摸点和响应位置不一致的问题。我的显示器配置如下:一个34寸,3440*1440;一个22英寸触摸屏,1920*1080。

Creationyang的博客 3216

yersinia -G打不开图形化界面解决方案(曲线救国,实操可行)

附Kali 2021 VMware懒人版,已完成汉化,更新源,并已经安装yersinia。ping 114.114.114.114也不通,接着ifconfig发现 IP地址有的,然后手动配置了IP地址,发现还是Ping不通114.11.4.114.114,然后输入。更新源后,报错源无法解析,同时ping www.baidu.com也不通,那可能是DNS存在问题,更新一下DNS服务器。百度找了很久,有个回答比较接近,但一一尝试了几遍,还是无解,解决不了呀!•(2)Yersinia编译的时候,要选择gtk。

weilandeyongheng的专栏 4170

Hybrid App 中 Token 鉴权到底怎么做?

本文提出Hybrid开发的安全分级策略:公共接口由H5直接请求,需登录的普通业务通过原生网络层代发(H5不接触Token),高风险操作必须原生处理并添加额外安全措施。核心原则是不让H5获取Token,通过JSBridge让原生应用处理敏感请求,从而避免XSS等安全风险。这种架构既保证安全性又简化前端开发,明确划分H5负责UI、原生负责安全层的职责边界,是企业级混合开发的最佳实践方案。

Mark Wu 的博客 806

F5高可用HA配置详情

F5 HA详细配置

weixin_45843944的博客 3026

【有料】一口气说出前后端 10 种鉴权方案~

最经典的莫过于 APP 内嵌 H5 的使用场景,当用户从 APP 进入内嵌的 H5 时,我们希望 APP 内已登录的用户能够访问到 H5 内受限的资源,而未登录的用户则需要登录后访问。短信验证码的作用就是证明当前操作页面的用户与输入手机号的用户为相同的人,那么实际上只要我们能够获取到当前手机使用的手机卡号,直接使用这个号码进行登录,不需要额外的操作,这就是。对于两个网站 A 和 B,在登录 A 网站的时候用 B 网站的帐号密码,就是联合登录,或者登录 B 网站的时候使用 A 网站的帐号密码,也是联合登录。

daobuxinzi的博客 1684

C#上位机+YOLO入门:工业视觉检测最小demo(复制就能跑,附完整代码)

新手入门C#上位机+YOLO,最忌讳的是上来就追求“大而全”,结果卡在某个外围功能上,连核心逻辑都没搞懂。这个最小demo的目的就是让大家先掌握“图像预处理→模型推理→结果解析”的核心链路,后续再逐步添加工业场景的功能,这样学习效率会高很多。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 728

W5500以太网&PoE扩展模块原理图设计,已量产

本文将以 W5500 以太网 & PoE 扩展板为对象,从嵌入式硬件设计的视角,深度拆解其电路架构、核心器件选型、关键功能实现,以及这款板子解决行业痛点的设计思路。

不脱发的程序猿 951

微信小程序一键登录功能,使用uni-app和springboot(JWT鉴权)

使用uni-app开发微信小程序,实现微信一键登录功能,后端使用springboot进行登录的处理,使用JWT进行身份验证。

maohe的博客 1万+

【法如faro】三维激光软件Scene2023数据处理(自动配准并转换坐标)流程

法如faro Scene2023数据处理(自动配准并转换坐标)的主要流程为:新建项目、导入数据、处理、自动注册、坐标系转换、模型导出立和面模型导出等。

智慧空间实验室 2385

SpringSide实战(三)----使用SpringSide4自动构建一个项目

SpringSide4为我们提供了一个自动生成WEB项目的骨架,它使用的是Maven的Archetype插件,基于Quickstart项目,创建自己的项目。 一、安装模块 首先确保support/maven-archetype中的内容已被install,进入 双击根目录中的generate-project.bat 或手工输入 二、自动生成 三、

fendo 8472

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

SpringSide开发实战(五):兵马未动,粮草先行

本篇讨论的问题是对项目中遇到的难题进行技术穿刺。做过项目的人都知道,在构思完一个项目的功能之后,紧接着的事情就是考虑这些构思的功能如何实现,对于自己不熟悉的领域,要进行技术穿刺。我的穿刺方法为先查找有无比较好的开源组件可用,如果没有,就查找相关的文档,自己编写和测试代码。在这一篇,我主要解决三个问题。1、解决字符串加密的问题,在前面一篇中,我们设计用户模块的时候,准备将用户的密码字

Gerry的专栏 1558

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

springside-core-4.2.3-GA.jar 我这里有

jar包下载: https://download.youkuaiyun.com/download/qq_41169544/85111031https://download.youkuaiyun.com/download/qq_41169544/85111031 git 网址: SpringSide 春天的旁边http://springside.github.io/ 生成jar包步骤: 一,下载springside 源码 下面是地址https://github.com/spri...

阿涩的博客 1339

SpringSide实战(二)----运行SpringSide项目并导入到Eclipse中

一、下载源码 去以下地址下载SpringSide4的源码: https://github.com/springside/springside4/releases 或者去下载我上传到优快云的: 下载下来之后,解压,因为SpringSide是基于Maven构建的所以必须要先安装Maven,具体安装方式可参考我这篇文章: 解压下载包后,会看到

fendo 8980

【华为云会议开发指南】App ID鉴权介绍

为了降低第三方应用集成华为云会议难度,并且提升开放接口的安全性,华为云会议开放能力中支持基于App ID的鉴权方式。App ID是一个应用的标识,同一个App ID可以同时在第三方的桌面终端、移动终端、Web应用上使用。 App ID鉴权原理 图1 第三方客户端App ID鉴权流程 鉴权前提: 开发者在华为云会议控制台上为自己的应用申请AppID,并获取App ID和App Key。 开发者在自己的服务端集成Signature生成算法,请参考“第三方服务集成Signature生成算法”。 SDK初始化时传

HWCloudDeveloper的博客 3968

[推荐]一口气说出前后端 10 种鉴权方案~

在介绍鉴权方法之前,我们先要了解的是:什么是认证、授权、鉴权、权限控制以及他们之间的关系,有了他们做铺垫,那么我们才能做到从始至终的了解透彻 ~

李小文的博客 2236

Token鉴权

需要注意的是,在实际应用中,为了增强安全性,Token通常会设置过期时间,并采用加密算法对Token进行签名和验证。常见的Token类型有两种:基于Session的Token和基于JSON Web Token (JWT)的Token。5. 服务端接收到请求后,根据携带的Session ID进行验证,如果验证通过,则允许客户端访问相应资源。5. 服务端接收到请求后,对Token进行解析和验证,如果验证通过,则允许客户端访问相应资源。6. 服务端对Token进行验证,验证通过后允许客户端访问相应资源。

maoyudashen的博客 1405

接口测试中的Token鉴权(Postman中Token的获取和引用)

Token的获取和引用

weixin_44901808的博客 2万+

token鉴权

前言 上一篇博客介绍了什么是cookie、session,以及cookie和session之间的区别,运行机制等。那么这篇博客一起来看看另外一种鉴权方式,也就是token鉴权,token就是接口层面的一种校验而已。 一、什么是token? 其实token就是一个令牌,通俗一点可以称为‘暗号’,在一些数据传递之前,要先进行暗号的核对,不同的暗号(令牌)之前被授权不同的数据操作。 二、token的运行机制。 #mermaid-svg-uUOHpzCQGpWVw5Nd .label{font-family:'

m0_47127594的博客 8731

声网 Token 鉴权机制,以及常见的问题

可以看到,在用户加入频道前,客户端需要先向服务器申请Token,并在 服务器 生成 Token,且 Token 必须与 需要加入频道的用户所对应的 AppID、频道名、用户 ID(UID)信息、用户权限(是否能发流或收流) 一一对应,并且确保生成的 Token 在有效期内。Token 过期时,SDK 会触发 Token 过期回调。一般来说,我们建议在Token 过期前,及时更新 Token,即从服务器获取新的 Token 并调用 renewToken 将新生成的Token 传给 SDK。

声网的博客 2136

使用Token方式实现用户身份鉴权认证

Token,也称为“令牌”,是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。比如如下形式: 39faf62271944fe48c4f1d69be71bc9a

软件自动化测试技术交流、资源分享 1110

基于 Token 的身份验证方法

使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的: 客户端使用用户名跟密码请求登录 服务端收到请求,去验证用户名与密码 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里 客户端每次向服务端请求资源的时候需要...

weixin_34367257的博客 1204

学习笔记(二):Token鉴权实现

上次总结了有关Token鉴权的理论知识,本次内容学习了将jwt、shiro、redis整合,实现token的自动刷新和可控性。

qq_49111986的博客 2254

【鉴权】深入解析 Token:身份认证的核心技术

Token(令牌)是一个用于身份认证的凭证,通常是由服务器生成并返回给客户端。客户端在后续请求中携带该 Token,服务器通过解析 Token 验证用户身份,从而决定是否授权访问资源。Token 的一个显著特点是其无状态性,这意味着服务器不需要存储关于用户会话的数据,而是通过解析客户端携带的 Token 来获取所有的身份信息。Token 认证是现代 Web 和移动应用中最常见的身份验证方式之一。

人生苦短,睡觉要紧,睡醒再说 1万+
上一篇: websocket之旅
下一篇: 通过redis选主进程
ChainCode
ChainCode 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄11年 115粉丝 51原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值