Skip to content

组织授权与审计平台对接FAQ

常见问题解答

1. 系统是新建的没有用户,怎么对接?

问题描述: 我的系统是全新的,还没有用户数据,如何进行OAuth对接?

解决方案:

  1. 创建固定用户方案: 可以先在您的系统中创建一个固定的用户(如管理员用户)
  2. 统一平台关联: 在统一身份平台中,将所有用户都关联到这个固定用户
  3. 动态创建用户: 在回调处理逻辑中,通过平台的用户身份信息动态创建您系统的用户
  4. 重新关联用户: 建议在用户创建完成后,将创建过的用户重新进行关联,与固定用户解耦,保证安全性

示例代码:

java
@Override
public boolean convert(HttpSession session, User userInfo) {
    if (null == userInfo) {
        // 用户未成功转换,根据OAuth用户信息动态创建用户
        String oauthUserId = getOAuthUserId(); // 从OAuth信息中获取用户ID
        User newUser = createUserFromOAuth(oauthUserId); // 动态创建用户
        session.setAttribute("user", newUser);
        return true;
    }
    session.setAttribute("user", userInfo);
    return true;
}

2. 回调时报错400,排查不到原因怎么办?

问题描述: OAuth回调时收到HTTP 400错误,无法定位具体原因。

解决方案:

  1. 检查回调地址: 确认回调地址是否以 /oauth/callback 开头
    • 我们的回调地址固定为 /oauth/callback
    • 这也是拦截器默认拦截的地址
  2. 检查context-path配置: 如果您的系统有context-path,请在统一认证平台中的URL处正确配置
    • 例如:如果您的应用context-path是 /myapp,则回调地址应配置为 http://yourdomain.com/myapp/oauth/callback
  3. 检查鉴权排除: 确保已排除 /oauth/* 路径下的鉴权判定
  4. 日志检查: 查看服务器日志,确认是否有其他拦截器或过滤器影响

配置示例:

yaml
oauth:
  client:
    redirect-uri: http://your-domain.com/your-context-path/oauth/callback

3. 从平台携带 ?oauth=1的url参数到系统,系统不识别?

问题描述: 从统一认证平台跳转到我的系统时,URL带有 ?oauth=1 参数,但系统无法识别。

解决方案:

对于一般项目:

  • SDK默认提供了针对 oauth=1 参数的拦截
  • 有该参数会自动跳转到平台登录

对于前后端分离项目:

需要在nginx或前端配置中对该参数进行拦截,然后将请求转发到后端。

Nginx配置示例:

nginx
server {
    location / {
        if ( $query_string ~* "oauth=1" ) {
            # 当且仅当包含鉴权标记,才跳转
            proxy_pass      http://localhost:8089;
        }
        root   /your/frontend/path;
        try_files  $uri $uri/ /index.html;
        index  index.html index.htm;
    }
    
    location /oauth {
        proxy_pass http://localhost:8089/;
        proxy_set_header Host $host;
    }
}

Webpack代理配置示例:

javascript
const devServer = {
  index: '',
  proxy: {
    '/': {
      target: 'http://localhost:8089',
      changeOrigin: true,
      bypass: function(req, res, proxyOptions) {
        if (!req.query.oauth) {
          return '/index.html';
        }
      },
    },
    '/oauth': {
        target: 'http://localhost:8089',
        changeOrigin: true,
    },
  }
};

不使用SDK的情况:

  • 在主页处填写您希望触发登录的具体URL
  • 自行判断登录状态,跳转到您自己的主页

4. Maven依赖下载失败怎么办?

问题描述: 无法从Maven中央仓库下载OAuth SDK依赖。

解决方案:

  1. 检查网络连接: 确保能够访问Maven中央仓库
  2. 清理本地缓存: 删除 ~/.m2/repository 中的相关缓存文件
  3. 更新Maven版本: 使用较新版本的Maven
  4. 使用镜像仓库: 配置国内Maven镜像,如阿里云镜像

settings.xml配置示例:

xml
<mirrors>
  <mirror>
    <id>alimaven</id>
    <name>aliyun maven</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    <mirrorOf>central</mirrorOf>
  </mirror>
</mirrors>

5. 配置文件加载失败怎么办?

问题描述: OAuth配置文件无法正确加载。

解决方案:

  1. 检查文件路径: 确认配置文件路径正确
    • SpringBoot默认检测 oauth.yml
    • 也可在 application.propertiesapplication.yml 中配置
  2. 检查配置格式: 确保YAML或Properties格式正确
  3. 检查必需配置项: 确保包含以下必需配置:
    • client-id
    • client-secret
    • local-url
    • server-url

最小配置示例:

yaml
oauth:
  client:
    client-id: your-app-id
    client-secret: your-client-secret
    local-url: http://your-domain.com
    server-url: http://oauth-server-url

6. 用户同步失败怎么办?

问题描述: 用户数据同步到统一认证平台失败。

解决方案:

  1. 检查SyncUserProvider实现: 确保正确实现了 transformgetLocalUsers 方法
  2. 检查outerId字段: 确保 outerId 字段正确填写,这是用户关联的关键字段
  3. 检查用户数据格式: 确保返回的用户数据符合LocalUser模型要求
  4. 检查网络连接: 确保能够访问OAuth服务器

正确的transform实现示例:

java
@Override
protected LocalUser transform(User domain) {
    return LocalUser.builder()
        .outerId(String.valueOf(domain.getId())) // 关键字段,必须唯一
        .name(domain.getName())
        .username(domain.getUsername())
        .phone(domain.getPhone())
        .organization(getOrganizations(domain))
        .build();
}

7. Session转换失败怎么办?

问题描述: OAuth认证成功但Session转换失败,无法保持登录状态。

解决方案:

  1. 检查SSOSessionConverter实现: 确保正确实现了转换逻辑
  2. 检查登录态判断: 确保 isComplete 方法正确判断登录状态
  3. 检查用户转换: 确保UserConverter能正确将LocalUser转换为系统用户
  4. 检查Session存储: 确保Session能正确存储用户信息

正确的Session转换示例:

java
@Override
public boolean convert(HttpSession session, User userInfo) {
    if (null == userInfo) {
        return false;
    }
    // 模拟您系统的登录过程
    session.setAttribute("currentUser", userInfo);
    session.setAttribute("isAuthenticated", true);
    return true;
}

@Override
public boolean isComplete(HttpSession session) {
    return session.getAttribute("currentUser") != null && 
           Boolean.TRUE.equals(session.getAttribute("isAuthenticated"));
}

8. 版本兼容性问题怎么办?

问题描述: SDK与现有框架版本不兼容。

解决方案:

  1. 检查JDK版本: 确保使用JDK 1.7+(推荐JDK 1.8+)
  2. 检查Spring版本: 确保Spring版本满足要求
    • SpringBoot: 2.0+
    • Spring MVC: 4.3+
  3. 检查Servlet版本: 确保Servlet API 3.0+
  4. 选择合适的SDK版本: 根据您的环境选择对应的SDK版本

9. 如何调试OAuth对接问题?

解决方案:

  1. 启用调试日志: 在配置文件中启用DEBUG级别日志
  2. 检查网络请求: 使用浏览器开发者工具查看网络请求
  3. 查看服务器日志: 检查应用服务器和OAuth服务器的日志
  4. 使用测试工具: 使用Postman等工具测试OAuth接口
  5. 分步调试:
    • 先测试配置是否正确
    • 再测试用户转换逻辑
    • 最后测试完整流程

调试配置示例:

yaml
logging:
  level:
    com.flyfish.oauth: DEBUG
    org.springframework.security: DEBUG

10. 内外网地址不一致如何配置URL?

问题描述: 在部署环境中,浏览器访问的地址(外网地址)与服务器之间调用的地址(内网地址)不一致,如何正确配置OAuth客户端?

应用场景:

  • 服务器部署在内网环境,通过负载均衡器或网关对外提供服务
  • 容器化部署中,容器内部网络与外部访问网络不一致
  • 使用代理服务器的环境

解决方案:

需要分别配置服务器调用地址和浏览器访问地址:

  1. server-url: 配置为内网地址,用于服务器之间的API调用
  2. user-authorization-uri: 配置为外网地址,用于浏览器跳转

配置示例:

yaml
oauth:
  client:
    client-id: my-app
    client-secret: $1$MU1BZm/Y$Lg.zzRk35VYpqk8.IcWSM0
    local-url: http://external.yourdomain.com:8080         # 外网访问地址
    server-url: http://192.168.1.100:8088                  # 内网服务器地址,用于API调用
    user-authorization-uri: http://external.authserver.com:8088/login  # 外网认证地址,用于浏览器跳转
    redirect-uri: http://external.yourdomain.com:8080/oauth/callback   # 外网回调地址

详细说明:

  • server-url: OAuth客户端SDK通过此地址调用认证服务器的API接口(如token获取、用户信息查询等)
  • user-authorization-uri: 浏览器通过此地址访问认证服务器的登录页面
  • local-url: 您的应用的外网访问地址
  • redirect-uri: 认证成功后的回调地址,必须是外网可访问的地址

典型部署架构示例:

浏览器 -> 负载均衡器/网关 -> 应用服务器 -> 内网认证服务器
         (外网地址)          (内网地址)    (内网地址)

注意事项:

  1. 确保内网地址在服务器之间可以正常访问
  2. 确保外网地址在浏览器中可以正常访问
  3. 如果使用HTTPS,注意证书配置的域名要匹配
  4. 防火墙要允许相应的端口访问

11. 政务外网自签名证书配置问题

问题描述: 在政务外网环境中,OAuth认证服务器使用自签名HTTPS证书,但Java应用在请求服务器时不信任该证书,导致SSL握手失败和请求失败。

错误现象:

  • javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed
  • unable to find valid certification path to requested target
  • OAuth服务器API调用失败,但浏览器访问正常

解决方案:

方法一:导入根证书到Java信任存储【推荐】

步骤1:下载根证书

  • 在政务外网系统登录页面下方找到证书下载按钮
  • 下载根证书文件(通常为 .crt.cer 格式)

步骤2:导入证书到Java密钥存储

bash
# 使用keytool命令导入证书
keytool -import -alias oac -file ./root.crt -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit

# 或者指定具体的Java路径
keytool -import -alias oac -file ./root.crt -keystore /usr/lib/jvm/java-8-openjdk/jre/lib/security/cacerts -storepass changeit

参数说明:

  • -alias oac: 证书别名,可自定义
  • -file ./root.crt: 证书文件路径
  • -keystore: Java密钥存储文件路径
  • -storepass changeit: 密钥存储密码(Java默认密码)

步骤3:验证证书导入

bash
# 查看密钥存储中的证书
keytool -list -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit | grep oac

步骤4:重启应用服务器

  • 重启Tomcat或其他应用服务器以加载新证书

方法二:使用系统属性禁用SSL验证【不推荐】

java
// 在应用启动时设置系统属性(仅用于测试环境)
System.setProperty("com.sun.net.ssl.checkRevocation", "false");
System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");

或在JVM启动参数中添加:

bash
-Dcom.sun.net.ssl.checkRevocation=false
-Dtrust_all_cert=true

方法三:应用级别信任管理器配置

java
// 创建信任所有证书的管理器(仅用于开发测试)
TrustManager[] trustAllCerts = new TrustManager[] {
    new X509TrustManager() {
        public X509Certificate[] getAcceptedIssuers() { return null; }
        public void checkClientTrusted(X509Certificate[] certs, String authType) { }
        public void checkServerTrusted(X509Certificate[] certs, String authType) { }
    }
};

SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

Docker环境处理:

如果在Docker容器中运行,需要在Dockerfile中添加证书:

dockerfile
# 复制证书文件
COPY root.crt /tmp/root.crt

# 导入证书
RUN keytool -import -noprompt -alias oac -file /tmp/root.crt \
    -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit

# 删除临时证书文件
RUN rm /tmp/root.crt

常见问题:

  1. 权限问题: 导入证书时提示权限不足

    bash
    sudo keytool -import -alias oac -file ./root.crt -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit
  2. 找不到Java路径:

    bash
    # 查找Java安装路径
    echo $JAVA_HOME
    # 或
    java -XshowSettings:properties -version 2>&1 | grep "java.home"
  3. 证书已存在:

    bash
    # 删除已存在的证书
    keytool -delete -alias oac -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit
    # 重新导入
    keytool -import -alias oac -file ./root.crt -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit

安全建议:

  • 生产环境建议使用方法一(导入根证书)
  • 避免在生产环境中禁用SSL验证
  • 定期更新和维护证书
  • 做好证书过期监控

12. 生产环境部署注意事项

关键要点:

  1. HTTPS配置: 生产环境建议使用HTTPS
  2. 域名配置: 确保配置的域名在生产环境中可访问
  3. 防火墙设置: 确保OAuth服务器端口可访问
  4. 负载均衡: 如使用负载均衡,注意Session共享问题
  5. 监控告警: 配置相关监控和告警机制

获取更多帮助

如果以上FAQ未能解决您的问题,请:

  1. 查看 JavaDoc 文档
  2. 下载 Demo 示例
  3. 联系技术支持团队

当前SDK版本: 1.0.7