ParseCallback 验证并解析 Discourse 回调的 sso/sig 参数,返回 Discourse 用户名。
(rawSSO, sig string)
| 69 | |
| 70 | // ParseCallback 验证并解析 Discourse 回调的 sso/sig 参数,返回 Discourse 用户名。 |
| 71 | func (d *DiscourseConfig) ParseCallback(rawSSO, sig string) (string, error) { |
| 72 | // 验证 HMAC 签名 |
| 73 | expected := d.sign(rawSSO) |
| 74 | if !hmac.Equal([]byte(expected), []byte(sig)) { |
| 75 | return "", errors.New("invalid signature") |
| 76 | } |
| 77 | // 解码 payload |
| 78 | decoded, err := base64.StdEncoding.DecodeString(rawSSO) |
| 79 | if err != nil { |
| 80 | return "", fmt.Errorf("decode payload: %w", err) |
| 81 | } |
| 82 | params, err := url.ParseQuery(string(decoded)) |
| 83 | if err != nil { |
| 84 | return "", fmt.Errorf("parse payload: %w", err) |
| 85 | } |
| 86 | // 验证 nonce(防重放攻击) |
| 87 | if !d.consumeNonce(params.Get("nonce")) { |
| 88 | return "", errors.New("invalid or expired nonce") |
| 89 | } |
| 90 | username := params.Get("username") |
| 91 | if username == "" { |
| 92 | return "", errors.New("missing username in payload") |
| 93 | } |
| 94 | return username, nil |
| 95 | } |
| 96 | |
| 97 | // IsAllowed 检查 Discourse 用户名是否有权限登录。 |
| 98 | // 白名单为空时信任所有 Discourse 用户。 |
no test coverage detected