Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FZU 登录流程 "应用没有权限" 错误 #18

Open
luckycat0426 opened this issue Nov 10, 2021 · 54 comments
Open

FZU 登录流程 "应用没有权限" 错误 #18

luckycat0426 opened this issue Nov 10, 2021 · 54 comments

Comments

@luckycat0426
Copy link
Contributor

luckycat0426 commented Nov 10, 2021

.....某些学校的边缘情况可能更加复杂,这几天我校好像更新了今日校园鉴权流程
image

不直接请求 今日校园的验证服务,

http://id.***.edu.cn/authserver/login?service=https%3A%2F%2F***.campusphere.net%2Fiap%2FloginSuccess%3FsessionToken%3D8cf1a0a7e01541f384d728d588329239"

也可能是手机端流程原本就不一样,不知道cea是基于什么登陆流程实现的?

@luckycat0426
Copy link
Contributor Author

image
post 主体也有所不同

@luckycat0426
Copy link
Contributor Author

luckycat0426 commented Nov 10, 2021

// 登录前校验
function checkForm() {
	var cllt = $("#cllt").val();
	if(cllt=='userNameLogin'){
		if(utils.requireInput($(LOGIN_USERNAME_ID),0,100,$("#showErrorTip"),inputUserNameTip,$(LOGIN_USERNAME_ID).parent())
			|| utils.requireInput($(LOGIN_PASSWORD_ID),0,32,$("#showErrorTip"),inputPasswordTip,$(LOGIN_PASSWORD_ID).parent())){
			return;
		}
	    if (needCaptcha && captchaSwitch == "1" && utils.requireInput($(LOGIN_CAPTCHA_ID),0,10,$("#showErrorTip"),inputCodeTip,$(LOGIN_CAPTCHA_ID).parent())) {
	    	return;
	    }
	    $("#saltPassword").val(encryptPassword($(LOGIN_PASSWORD_ID).val(),$("#pwdEncryptSalt").val()));
	    $(LOGIN_PASSWORD_ID).attr("disabled","disabled");
	}else if(cllt=='dynamicLogin'){
		if(utils.requireInput($(LOGIN_ACCOUNT_ID),0,100,$("#showErrorTip"),inputMobileTip,$(LOGIN_ACCOUNT_ID).parent())
			|| utils.requireInput($(LOGIN_DYNAMIC_ID),0,100,$("#showErrorTip"),inputDynamicTip,$(LOGIN_DYNAMIC_ID).parent())){
			return;
		}
	}
    return true;
}

加密函数

function encryptAES(data, aesKey) {
    if (!aesKey) {
        return data;
    }
    var encrypted = getAesString(randomString(64) + data, aesKey, randomString(16));
    return encrypted;
}
function encryptPassword(pwd0, key) {
    try {
        return encryptAES(pwd0, key);
    } catch (e) {}
    return pwd0;
}

密钥

$("#pwdEncryptSalt").val()
'RADJfz0oeCxzjnPI'

@beetcb
Copy link
Contributor

beetcb commented Nov 10, 2021

cea 用的是 PC 网页端的 userNamePasswordLogin(依稀记得是叫这个) 方法
Post 主体看起来没有大变化,应该(乐观情况下)是改变 edge-case.ts 里面的 formIdx 就可以了

@luckycat0426
Copy link
Contributor Author

根据网页抓的post请求构造了
image
post body ,最后返回结果是200,不是302重定向,
image

明天再看看往手机抓到的网址发包返回结果如何
遇到困难睡大觉:)

@beetcb
Copy link
Contributor

beetcb commented Nov 10, 2021

YES! 睡觉

@vic2ray
Copy link

vic2ray commented Nov 11, 2021

image post 主体也有所不同

刚好今天用golang写了下我们学校(NOTCLOUD)的模拟登录,看到你的这个错误(Status code 200, not 302)大概知道哪里漏了。我的登录流程如下:

  1. 请求金智教育portal首页:https://fzu.campusphere.net/portal/index.html

  2. 点击登录:https://fzu.campusphere.net/portal/login.html

  3. 以上请求会跳转到统一登录页面:http://id.fzu.edu.cn/authserver/login?service=https://fzu.campusphere.net/iap/loginSuccess?sessionToken=c6a12e5bf82b49f0afdb4ce8a1eb56d5

  4. 这个页面应该是全国统一的,post参数和加密固定,经测试有三个请求头必不可少

  • "Content-Type", "application/x-www-form-urlencoded"
  • "Referer", "我自己"
  • "Cookie", "route=跳转过来时Set-Cookie; JSESSIONID=跳转过来时Set-Cookie"
  1. 所以重点是获取到route和JSESSIONID,再post表单,否则就是响应200,就算密码对了也是登录错误

以上。因为破学校前两天登录页又抽风,导致cea自动登录时返回Unauthorized

之前的登录地址是:http://id.fzu.edu.cn/authserver/login?service=https://fzu.campusphere.net/portal/login

也就是不需要从portal页面点登录携带sessionToken跳转到统一登录页,但现在直接登录返回:

image

不知道其他学校是否存在一样的情况

@vic2ray
Copy link

vic2ray commented Nov 11, 2021

cea 用的是 PC 网页端的 userNamePasswordLogin(依稀记得是叫这个) 方法 Post 主体看起来没有大变化,应该(乐观情况下)是改变 edge-case.ts 里面的 formIdx 就可以了

顺便提一下,看到edge-case.ts里面有福州大学,现在验证码的路径已经变了:

http://id.fzu.edu.cn/authserver/**checkNeedCaptcha.htl**?username=xxx&_=1636638646618

这几天登不上很郁闷呐

@beetcb
Copy link
Contributor

beetcb commented Nov 11, 2021

// we will using proxy to get the default properties
const defaultProps = {
rememberMe: true,
getCaptchaPath: '/getCaptcha.htl',
checkCaptchaPath: '/checkNeedCaptcha.htl',
formIdx: 2,
pwdEncrypt: true,
}

哈哈,看起来变回默认的情形了

@beetcb
Copy link
Contributor

beetcb commented Nov 11, 2021

为什么它们的更新感觉回滚到之前的老版本了 😂

@beetcb
Copy link
Contributor

beetcb commented Nov 11, 2021

后期考虑把这个边缘情形维护成一个 API (在加载学校配置时抓取),这样方便改动,Cea 也不用以发布新版本的方式来更新了,这样可以缩短更新周期 @Juaran

@luckycat0426
Copy link
Contributor Author

image
@Juaran 我这里清除掉route信息后再登陆,获得的响应是302,重新跳转到登陆界面,而不是200

@vic2ray
Copy link

vic2ray commented Nov 12, 2021

image
@Juaran 我这里清除掉route信息后再登陆,获得的响应是302,重新跳转到登陆界面,而不是200

注意这里Location后缀是except.message=Error...跳转链接已经坏掉了

@luckycat0426
Copy link
Contributor Author

luckycat0426 commented Nov 12, 2021

现在遇到一个问题,在cea中发送POST请求到

https://fzu.campusphere.net/iap/loginSuccess?sessionToken=73de651dba294f7981f5ca99eb528290

不管账号密码是否正确,永远返回200,检查body为登录界面
用POSTMAN 发包,如果密码错误,将会返回401 状态码.

image

@luckycat0426
Copy link
Contributor Author

检查了一下,是header里面的cookie 中的JSESSIONID与请求url对不上的原因,不管请求什么,都会返回200

@beetcb
Copy link
Contributor

beetcb commented Nov 12, 2021

上面提到的 Error decoding flow execution响应码卡在200 问题在这个项目的前身 https://github.com/beetcb/cea 就遇到过,是解决了的。

我不觉得当前 Cea 在 https://github.com/ceajs/cea/blob/main/core/src/crawler/login.ts 文件内的 NOTCLOUD 学校登陆逻辑有问题。

十分感谢你们付出时间 DEBUG 并分享到这里

但是我还是没看出错误的地方,方便的话,能给个测试账号吗,邮箱 [email protected]

@beetcb
Copy link
Contributor

beetcb commented Nov 12, 2021

或者说一下完整的登录流程和 Cookie 的特点,也行

@beetcb beetcb self-assigned this Nov 12, 2021
@beetcb
Copy link
Contributor

beetcb commented Nov 13, 2021

后期考虑把这个边缘情形维护成一个 API (在加载学校配置时抓取),这样方便改动,Cea 也不用以发布新版本的方式来更新了,这样可以缩短更新周期 @Juaran

已实现,准备检查一下你们学校适配性后发布新版本,可以参考 #20 提交适配

@luckycat0426
Copy link
Contributor Author

刚刚看到,我等下回去发个账号

@luckycat0426
Copy link
Contributor Author

.....URLSearchParams 这个对象是不是限制了长度,发现execution被截断了.

@luckycat0426
Copy link
Contributor Author

luckycat0426 commented Nov 13, 2021

.....把截断的补全就正常302跳转了,应该是以前的exection 太短了,没有遇到url 字符限制.

@beetcb
Copy link
Contributor

beetcb commented Nov 13, 2021

好,明天再研究研究 @luckycat0426

@luckycat0426
Copy link
Contributor Author

那个form index字段是为了定位general login 位置吧,为何不做成循环不同form表单,直到定位到general login为止,这样能少一个边缘情况,是因为出现了不兼容的情况吗?

@beetcb
Copy link
Contributor

beetcb commented Nov 14, 2021

因为四种登录方式都有 general login,并且不同学校这个正确的表单中没有统一的可以区别其它几种登录方式的字段
@luckycat0426 你可以看看这个结构,尝试检索一下 generalLogin<form 两个关键字

https://transfer.sh/HQQ1EQ/i.html

@beetcb
Copy link
Contributor

beetcb commented Nov 14, 2021

.....把截断的补全就正常302跳转了,应该是以前的exection 太短了,没有遇到url 字符限制.

这个限制应该只存在于把它真正用于 URL 请求时,Cea 是把字符放在 body 中请求的,没有限制

URLSearchParams 类并不会截断,node 源码中也没有相关证据,我写了一个小 demo,1000000 长度字符串也是通过测试了的:

async function urlParamsLimit(len) {
  const origalStr = 'a'.repeat(len)
  const string = new URLSearchParams({ a: origalStr }).toString()
  const urlStr = string.split('a=')?.[1]
  if (urlStr) {
    assertEq(origalStr, urlStr)
  }
}

function assertEq(arg1, arg2) {
  if (arg1 === arg2) {
    console.log(`Test Passed!`)
  } else {
    throw new Error(`Failed with ${arg1} = ${arg2}`)
  }
}

urlParamsLimit(1000000)

@luckycat0426

@luckycat0426
Copy link
Contributor Author

更新到最新的cea库好像用vscode 调试不了,
使用配置好的vscode 调试 提示
image

通过 vscode Javascript debug terminal 使用

node internal/lib/src/cli.js sign

调试
调用的是internal/node_modules/cea-core/lib/src/crawler/login.js
node modules 下载的cea core
而不是工作区文件夹下的cea core

@luckycat0426
Copy link
Contributor Author

截断问题没再复现了......可能是我哪里配置出错了.

@beetcb
Copy link
Contributor

beetcb commented Nov 18, 2021

fzu 有个问题,我用浏览器登录想看下请求,你给的账号密码都是对的,登录后出现这个报错界面:

https://transfer.sh/2Qr57B/fzu.txt

@luckycat0426

@luckycat0426
Copy link
Contributor Author

txt乱码了,如果显示是

应用没有权限
您的身份验证尝试不受信任,并且未经当前工作站的授权。

手机抓包也出现了该返回页面,但是能正常完成今日校园登陆.

@beetcb
Copy link
Contributor

beetcb commented Nov 18, 2021

确实是这样提示的,能登录的话,行吧,现在就是要把 cea 的处理给适配好

@luckycat0426
Copy link
Contributor Author

luckycat0426 commented Nov 19, 2021

imageimage
手机网页登陆和今日校园登陆抓包有所不同,手机网页登陆的请求和电脑认证入口类似,这个请求网址应该是无法登录到今日校园

@vic2ray
Copy link

vic2ray commented Nov 19, 2021

现在还不能登上吗 @luckycat0426

@vic2ray
Copy link

vic2ray commented Nov 19, 2021

我刚调试了下login.js,发现还是formIdx的问题

虽然文件vercel/data/school-edge-cases.json里的NOTCLOUD学校formIdx=2(这是正确的登录方式)

a9c5fb082fe9e8f18f705d6000a9702

但调试运行时发现login.js引用的compatibility/edge-case.js内容依旧为2.2.1版本之前的那三个学校:

  • 宁波大学
  • 武汉大学
  • 福州大学-->formIdx: 0

也就是说虽然版本更新后文件去除了福州大学的旧的登录方式,但是打包之后的node_modules里面的文件还是旧的

(缓存还是什么鬼原因不知道)

手动改了下idx=2就能登录了

@beetcb @luckycat0426

@beetcb
Copy link
Contributor

beetcb commented Nov 19, 2021

因为我还在等你们确认再发布布新版本的😂
@Juaran

@beetcb
Copy link
Contributor

beetcb commented Nov 19, 2021

忘记提醒 @luckycat0426 了,因为新版是远程加载学校边缘信息的,所以要调试时需要先编译好,再手动运行

node internal/lib/src/cli.js load

再用 vscode 断点调试

@vic2ray
Copy link

vic2ray commented Nov 19, 2021

因为我还在等你们确认再发布布新版本的😂
@Juaran

没啥问题,赶快发布吧😄

@luckycat0426
Copy link
Contributor Author

image

const form = $('form[method=post]').get(schoolEdgeCases.formIdx);
        console.log(schoolEdgeCases.formIdx);

@Juaran @beetcb formindex我之前遇到截断的问题的时候就检查过,发现表单位置变换后,已经改成2测试过,之前询问能否自动匹配formindex也是于此相关,最后还是登陆不上去,所以推测是请求网址变动.
现在测试一下好像还是登陆不了

@beetcb
Copy link
Contributor

beetcb commented Nov 19, 2021

嗯,我等下拿你的号试试

@luckycat0426
Copy link
Contributor Author

忘记提醒 @luckycat0426 了,因为新版是远程加载学校边缘信息的,所以要调试时需要先编译好,再手动运行

node internal/lib/src/cli.js load

再用 vscode 断点调试

image
调试还是调用的internal目录下node_modules的cea-core,无法调试到根目录的cea-core 进行login代码的debug.

@beetcb
Copy link
Contributor

beetcb commented Nov 19, 2021

这种行为是符合预期的,因为 monorepo 的管理工具 lerna 会将那个文件夹软链接成 core/

@beetcb
Copy link
Contributor

beetcb commented Nov 19, 2021

还有是在 ts 文件里打断点,你这个界面我感觉不太对,似乎是 js 文件里打的

@luckycat0426
Copy link
Contributor Author

是我lerna配置出问题了吗,
image
是在ts文件打的断点,在js打断点是为了演示调试会进入node_modules文件.
image
internal ts文件打的断点是可以正常触发的,在cea-core处的断点不生效

@vic2ray
Copy link

vic2ray commented Nov 19, 2021

image

const form = $('form[method=post]').get(schoolEdgeCases.formIdx);
        console.log(schoolEdgeCases.formIdx);

@Juaran @beetcb formindex我之前遇到截断的问题的时候就检查过,发现表单位置变换后,已经改成2测试过,之前询问能否自动匹配formindex也是于此相关,最后还是登陆不上去,所以推测是请求网址变动. 现在测试一下好像还是登陆不了

我在Linux系统下安装v2.2.1之后,直接修改:

/usr/lib/node_modules/cea/node_modules/cea-core/lib/src/compatibility/edge-case.js

执行签到成功:

image

本地调试也是修改node_modules下cea-core内edge-case.js,签到成功

你试一下 @luckycat0426

@beetcb
Copy link
Contributor

beetcb commented Nov 19, 2021

我用你给的账号测试不能登录,Cea 的逻辑没错,跟用浏览器访问 https://fzu.campusphere.net/portal/login 的每一步行为都是一致的 @luckycat0426

问题是用最后 POST 账号密码阶段 fzu 返回的状态码是 200,并不会跳转到 campusphere 地址,所以也就拿不到今日校园 COOKIE,Cea 会根据返回码来确认登录结果的,所以会输出登陆失败

image

我感觉这无解啊,浏览器都登录不了,如果 @Juaran 同学能登陆,难道是你给的账号有问题?

@luckycat0426
Copy link
Contributor Author

@Juaran 你应该是研究生吧,登陆验证和本科生可能不一样.

@luckycat0426
Copy link
Contributor Author

@beetcb http://id.fzu.edu.cn/authserver/login?service=http%3A%2F%2Fid.fzu.edu.cn%2Fauthserver%2Fmobile%2Fcallback%3FappId%3D673223559
用这个网址试一下,这个是今日校园手机端抓包抓到的

@beetcb
Copy link
Contributor

beetcb commented Nov 19, 2021

返回了 Mobile,重定向跳转了一次 http://id.fzu.edu.cn/authserver/mobile/default.html#mobile_token=*********************** ,接下来是什么步骤呢,今日校园是如何拿到 Cookie 的呢?

@beetcb
Copy link
Contributor

beetcb commented Nov 19, 2021

我用我手机也试一下

@vic2ray
Copy link

vic2ray commented Nov 19, 2021

我刚找小学弟shilexi试了下,他们学院登上去直接没有权限,肯定拿不到MOD_AUTH_CAS

image

@luckycat0426 你的是这样吗

@luckycat0426
Copy link
Contributor Author

luckycat0426 commented Nov 19, 2021

返回了 Mobile,重定向跳转了一次 http://id.fzu.edu.cn/authserver/mobile/default.html#mobile_token=*********************** ,接下来是什么步骤呢,今日校园是如何拿到 Cookie 的呢?

http://id.fzu.edu.cn/authserver/login?service=http%3A%2F%2Fehall.fzu.edu.cn%2Fnewmobile%2Fclient%2FuserStoreAppList

访问这个网址的时候headers 带着今日校园认证信息,之前的包没有看到set cookies,应该js生成的.

@luckycat0426
Copy link
Contributor Author

@Juaran 也是这样

@vic2ray
Copy link

vic2ray commented Nov 20, 2021

今早APP端登录抓包情况如下:

  1. 请求今日校园appId认证登录
GET http://id.fzu.edu.cn/authserver/mobile/auth?appId=673223559
Header: 
	Host : id.fzu.edu.cn
	CpdailyAuthType : Login

Set-Cookie : route=0e3da18bb42e38dad8cb429bb3f505d0; Path=/authserver
Location: http://id.fzu.edu.cn/authserver/login?service=http://id.fzu.edu.cn/authserver/mobile/callback?appId=673223559&login_type=mobileLogin
  1. 取得callback形式登录地址,页面中两个form: 手机动态码登录;用户名密码登录
GET http://id.fzu.edu.cn/authserver/login?service=http://id.fzu.edu.cn/authserver/mobile/callback?appId=673223559&login_type=mobileLogin
Header:
	Host : id.fzu.edu.cn
	Cookie : route=0e3da18bb42e38dad8cb429bb3f505d0
	CpdailyAuthType : Login

Set-Cookie : JSESSIONID=7E3705A3FED182022C6C83B02A780E43
  1. 输入学号,请求验证码检查
GET http://id.fzu.edu.cn/authserver/checkNeedCaptcha.htl?username=学号&_=1637367974836
  1. 用步骤2的表单formIdx=1进行登录
POST http://id.fzu.edu.cn/authserver/login?service=http://id.fzu.edu.cn/authserver/mobile/callback?appId=673223559
Header:
	Host :id.fzu.edu.cn
	Content-Type :application/x-www-form-urlencoded
	Referer : http://id.fzu.edu.cn/authserver/login?service=http%3A%2F%2Fid.fzu.edu.cn%2Fauthserver%2Fmobile%2Fcallback%3FappId%3D673223559&login_type=mobileLogin
	Cookie : JSESSIONID=F85CFE4581DA4431277BCE0F286C6909; route=0e3da18bb42e38dad8cb429bb3f505d0
Body: 学号, password, captcha, _eventId, ...

Set-Cookie: HttpOnlyCASTGC=TGT-52894-cc2RCZF2tS4opxgA-CSA4WLRRmbTd-NMsUe2qHT-sA4n25nnfyQzCUFRMfV0DVInSFUids7
Location: http://id.fzu.edu.cn/authserver/mobile/callback?appId=673223559&ticket=ST-1981080-XZRMBMfRPp7dz0-PjTtjGUTOYbQids7
  1. 请求上一步带ticket跳转。注意此时的Cookie信息中,CASTGC是上一请求Set的HttpOnlyCASTGC,JSESSIONID和route是前面请求的
GET http://id.fzu.edu.cn/authserver/mobile/callback?appId=673223559&ticket=ST-1981080-XZRMBMfRPp7dz0-PjTtjGUTOYbQids7
Header:
	Host : id.fzu.edu.cn
	Cookie : CASTGC=TGT-52894-cc2RCZF2tS4opxgA-CSA4WLRRmbTd-NMsUe2qHT-sA4n25nnfyQzCUFRMfV0DVInSFUids7; JSESSIONID=7E3705A3FED182022C6C83B02A780E43; route=0e3da18bb42e38dad8cb429bb3f505d0;
	Referer: http://id.fzu.edu.cn/authserver/login?service=http%3A%2F%2Fid.fzu.edu.cn%2Fauthserver%2Fmobile%2Fcallback%3FappId%3D673223559&login_type=mobileLogin
	
Location: http://id.fzu.edu.cn/authserver/mobile/default.html#mobile_token=N53EV8Ng3CrbR2mXCyofDtyledC1CAsRfM+TQRUC7WVGg+hM/ow9jwDrZl+YkcxiPGlME05p/xr4iSZwMzJdszwt4ZfqjvojI5DnqFeFaDE=

这里没有返回Set-Cookie,Location链接也没有跳转

  1. notcloud/login
POST https://mobile.campushoy.com/app/auth/authentication/notcloud/login/v-8222
Header:
	Host : mobile.campushoy.com
	deviceType : 2
	CpdailyClientType : CPDAILY
	Content-Type : application/json
	tenantId : fzu
	User-Agent : CampusNext/9.0.12 (iPhone; iOS 14.4.2; Scale/3.00)
	CpdailyStandAlone : 0
	CpdailyInfo: xxxxx
	Cookie : tenantId=fzu; acw_tc=2f624a6816373706640745168e5ca06f5e0b1550a0b02c8561fefe85e1531c
Body: { "a": "xx", "b": "first_v2" }

到这里已经是今日校园的API了(登录成功),但是没有找到MOD_AUTH_CAS,猜测上一步的#mobile_token中应该隐藏了MOD信息

在后续API: http://ehall.fzu.edu.cn/newmobile/client/userStoreAppList 发现携带了MOD_AUTH_CAS信息

在进入主界面之后,又自动去请求了portal/login服务,然后被告知没有应用权限(手动滑稽):

image

@beetcb beetcb changed the title 边缘情况无法登陆 FZU 登录流程 "应用没有权限" 错误 Jan 2, 2022
@fzusb
Copy link

fzusb commented Jul 29, 2022

So can this problem be solved?

@fzusb
Copy link

fzusb commented Jul 29, 2022

Uploading Screenshot from 2022-07-29 08-13-54.png…

@he1215894612
Copy link

fzu现在已经可以云端登录了好像

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants