V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
Blueming
V2EX  ›  Java

关于单点登录如何获取用户信息的问题

  •  
  •   Blueming · Sep 1, 2020 · 4336 views
    This topic created in 2069 days ago, the information mentioned may be changed or developed.

    最近在学习做单点登录,用的是 spring security oauth2 那套东西。 用的 jwt token,子系统客户端使用 EnableOAuth2Sso 注解。 现在已经实现了单点登录的功能,但是我想在子系统获取当前登录用户的信息,比如 token,然后解析 token,将用户部分信息存到数据库管理。该如何实现呢 因为在浏览器中都是通过点击登录就直接跳转到子系统内部了,所以不清楚 token 是在什么地方获取,或者能不能获取?

    Supplement 1  ·  Sep 1, 2020
    就在刚刚
    我通过遍历 session 里的内容,发现了一个 Attribute 名为 SPRING_SECURITY_CONTEXT 。
    然后获取内容发现了 SecurityContext,然后通过该对象获取到了 Authentication 以及 UserDetails,最终获取到了颁发的 token 。
    这样,目的是达到了。
    那这样是否符合常规操作?或者有没有其他更好的办法?
    20 replies    2020-09-04 12:07:56 +08:00
    securityCoding
        1
    securityCoding  
       Sep 1, 2020
    考虑一下子系统统一走网关, 在网关解析登录态?
    ksice
        2
    ksice  
       Sep 1, 2020
    统一共用一套认证系统不就能取到用户信息?
    hotpot6147
        3
    hotpot6147  
       Sep 1, 2020
    要么在 header 里面要么在 query string 里面
    Blueming
        4
    Blueming  
    OP
       Sep 1, 2020
    @ksice 就是用的一个认证系统,但是全都在浏览器用户点击完成了,不是那种直接用 postman 调用接口返回 token,我就不知道到底该在哪里找到认证系统给我颁发的 token
    Blueming
        5
    Blueming  
    OP
       Sep 1, 2020
    @hotpot6147 我看了下浏览器的记录,是直接先申请授权码然后 302 重定向到申请 token 最后又 302 重定向到子系统的 login,都没有见到 token 的影子
    Nich0la5
        6
    Nich0la5  
       Sep 1, 2020 via Android
    获取认证 token 是两个服务器之间的通信,浏览器当然看不见
    Blueming
        7
    Blueming  
    OP
       Sep 1, 2020
    @Nich0la5 所以我才来问,该如何获取到颁发的 token,总不能 token 都没有吧。我都能直接通过浏览器访问受保护的资源
    JellyDong
        8
    JellyDong  
       Sep 1, 2020
    .NET Core 中有个 Identity Server4 的东西,其它语言的程序也是可以接入的,不知道 Java 有没有类似的
    Nich0la5
        9
    Nich0la5  
       Sep 1, 2020 via Android
    @Blueming 只可能在最后一次重定向里
    enchigo
        10
    enchigo  
       Sep 1, 2020
    spring security oauth2 用起来有那么一丝不顺手 网上资料很多,但是大多都不准确。我这边项目没用 JWT,直接用的 Bearer Token,access_token 也是自己从 RequestContext 里面拿。用户信息的话是通过 SecurityContextHolder 取的,然而 OAuth2Authentication 貌似是私有构造,所以还得用非严格模式的 jackson 序列化和反序列化一次拿到对象,再从中拿到 UserDetail 。我也不知道合不合规,反正就这样做了。
    Blueming
        11
    Blueming  
    OP
       Sep 1, 2020
    @Nich0la5 通过 wireshark 抓包的确看到了,颁发的 token 信息,那该如何在程序代码里处理呢
    Blueming
        12
    Blueming  
    OP
       Sep 1, 2020
    @enchigo 如果今天找不到其他方法,我也只能这样了
    jorneyr
        13
    jorneyr  
       Sep 1, 2020
    这个好像不是 OAuth2 的功能,而是 SSO 的功能
    Blueming
        14
    Blueming  
    OP
       Sep 1, 2020
    @jorneyr 但的确 EnableOAuth2Sso 是 oauth2 包里的东西
    canbingzt
        15
    canbingzt  
       Sep 1, 2020
    Spring Security OAuth 2.x 已经被标记 deprecated,所有 Spring Security OAuth 2.x 内容( Clients 和 Resource Servers )将迁移到 Spring Security 5.2.x,但是 Spring Security 并不提供 Authorization Server,可能需要第三方的组件来提供支持(比如 Keycloak 、cas 等)

    参考 https://github.com/spring-projects/spring-security/wiki/OAuth-2.0-Migration-Guide
    ksice
        16
    ksice  
       Sep 1, 2020
    @Blueming 你是说 token 跳转子平台的时候前端不知道放在哪么
    ksice
        17
    ksice  
       Sep 1, 2020
    @Blueming 如果所有的平台都在一个域名下面,就可以放在 cookie 里面进行共享
    Blueming
        18
    Blueming  
    OP
       Sep 1, 2020
    @ksice 认证中心的域名是 app.com 子系统域名是 a.app.com 这样可以共享吗
    ErrorMan
        19
    ErrorMan  
       Sep 2, 2020
    翻了下以前的代码,以前的文档是 Authorize Server 开启时提供了一个 /me 入口,子系统拿到 JWT token 之后带着这个 token 去访问 /me, 可以拿到 UserDetail 的 JSON 回复。所以我的实现是用 feign 对 Authorize Server 开一个 rpc 请求,而且 feign 请求时会自动携带 JWT token,所以获取过程就变成了调用 feign 的 rpc 拿到和 Authorize Server 定义相同的 UserDetail 然后继续。 看了 append 感觉我的方法已经过时了啊。还有楼上老哥说的被 deprecate 了
    Blueming
        20
    Blueming  
    OP
       Sep 4, 2020
    @ErrorMan 我现在遇到的问题就是不知道怎么在代码里拿到 JWT token
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2491 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 56ms · UTC 08:34 · PVG 16:34 · LAX 01:34 · JFK 04:34
    ♥ Do have faith in what you're doing.