【问题标题】:Redirecting user to oauth2 authorization server to get token Spring Boot将用户重定向到 oauth2 授权服务器以获取令牌 Spring Boot
【发布时间】:2017-12-27 04:06:58
【问题描述】:

我有 2 个应用程序正在运行,一个是资源服务器,我有需要身份验证才能查看文本的信息。然后我有提供令牌的授权服务器。现在我可以使用 postman 或 Insomnia,添加 auth_url、token_url、client_id、client_secret 并获得令牌。我将令牌添加到标头,然后使用标头向我的资源服务器发出获取请求,它工作得很好。

现在我不知道如何直接从我的资源服务器实现重定向。就像我去的时候

本地主机:9000/家

我想被重定向到:

localhost:9001/登录

我使用 inmemory 用户登录的位置,然后它会将我重定向回 l​​ocalhost:9000/home,我会看到该消息。

实现用户访问 localhost:9000/home 信息的最佳方式是什么?你去 localhost:9000/home,它去 localhost:9001 上的授权服务器,你用用户名和密码登录。批准授权,它会让你回到 localhost:9000/home,然后你可以看到之前受保护的文本,因为你没有访问它的令牌。

资源服务器.java

@SpringBootApplication
@RestController
@EnableResourceServer
@EnableOAuth2Client
public class SampleResourceApplication extends ResourceServerConfigurerAdapter {
        @Override
    public void configure(HttpSecurity http) throws Exception {
        http.antMatcher("/**")
                .authorizeRequests()
                .antMatchers("/", "/login**").hasRole("user")
                .anyRequest().authenticated();
    }

    @Bean
    public RequestContextListener requestContextListener() {
        return new RequestContextListener();
    }

    public static void main(String[] args) {
        SpringApplication.run(SampleResourceApplication.class, args);
    }

    @RequestMapping("/home")
    public String home() {
        return "this is home";
    }

}

我的属性看起来像:

server:
  port: 900
security:
  oauth2:
    client:
      client-id: foo
      client-secret: foosecret
      access-token-uri: http://localhost:9001/auth/oauth/token
      user-authorization-uri: http://localhost:9001/auth/oauth/authorize
      grant-type: USER
      auto-approve-scopes: true
    resource:
      user-info-uri: http://localhost:9001/auth/user

【问题讨论】:

  • 它实际上并不是OAuth2 规范的一部分。通常,当有人在不提供令牌的情况下访问您的 RS 时,您应该返回 401。重定向到 AS 不是你的 RS 工作
  • @Nathan 但解决问题的最佳方法是什么?
  • 当您到达localhost:9000/home 时,您只需得到一个 401(如果需要,您可以在正文中发送一些详细信息)。您的客户应该知道他必须从哪里获得令牌,以及他应该如何获得它。您可以在错误正文中指定原因:“缺少令牌”、“过期令牌”、“范围不足”、...
  • @Nathan 是的,我明白,我更多的是考虑如何实现用户登录功能,因此用户可以在 localhost:9000/home 上查看内容,而无需实际使用邮递员或失眠之类的东西跨度>
  • 我不太明白你现在在问什么。你能更新你的问题,让每个人都能看到吗?这会更清楚:p

标签: java spring-boot oauth-2.0


【解决方案1】:

让我们分离代理:您有用户(即您,也称为资源所有者)、授权服务器资源服务器客户端(访问您的网址的应用程序,即您的浏览器)。

通常,这发生在您的情况:

  1. 当您的客户端访问资源服务器时,它会收到401。根据您的实施,您还可以将 client 直接重定向到您的 AS(使用简单的重定向响应)。
  2. 您的 AS 会提示您输入凭据。在验证它们之后,它会为您颁发一个令牌。然后,您可以使用此令牌访问 RS

您想要获得的(如果我理解正确的话)是使用令牌自动重定向。为此,您只需在步骤 1 结束时重定向到您的 AS 时传递您尝试访问的 url(即localhost:9000/home)。您的 AS hten提示用户输入凭据,生成令牌,将其存储为 cookie(在浏览器的情况下),并将您重定向到他收到的 url (localhost:9000/home)。

编辑:重定向的结果代码是什么。

当您到达configure 时,您首先检查用户是否已通过身份验证。如果他是,那么一切都很好,但如果他不是,你必须抓住这个事件并开始你的重定向。这可以使用链接httpexceptionHandling 方法来完成:

public void configure(HttpSecurity http) throws Exception {
    http.antMatcher("/**")
            .authorizeRequests()
            .antMatchers("/", "/login**").hasRole("user")
            .anyRequest().authenticated()
    .and()
            .exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint());
}

private AuthenticationEntryPoint authenticationEntryPoint() {
    return new AuthenticationEntryPoint() {
        // You can use a lambda here
        @Override
        public void commence(HttpServletRequest aRequest, HttpServletResponse aResponse,
               AuthenticationException aAuthException) throws IOException, ServletException {
            aResponse.sendRedirect(MY_AS_URL + "?redirect_uri=localhost:9001/home");
        }
    };
}

【讨论】:

  • 是的,这就是我正在寻找的,但现在我遇到的问题是重定向到 AS。我不能让它工作。生病添加我的 RS 代码,也许有人可以提供帮助
  • @Jan 给你——希望对你有帮助
  • 看起来不错,并且可以按照预期进行,但是我需要研究为什么登录后的 url 不会将我重定向到 localhost:9000/home,即使它在 url 中有它。但是感谢您的帮助!
  • 当心您的重定向:有时,您最终会重定向到 localhost:9001/localhost:9000/home 之类的东西。祝你好运 ^^ 很高兴看到一次格式良好、经过研究的问题。
  • 嗨 @Nathan 和 Jan:你有它的演示吗?
【解决方案2】:

不幸的是,我不熟悉 Spring 框架,但希望这无论如何都会有所帮助:

OAuth 是一种授权协议。它不处理身份验证(另请参阅:ServerFault 上的“What is the difference between authentication and authorization?”)。

如果我对您的理解正确,您希望用户在转到 /home 并且尚未登录时被重定向到 /login。此步骤与 OAuth 无关,它必须是您应用程序的安全/防火墙设置的一部分。

还请注意,在授权服务器上登录(身份验证)和实际授予应用程序访问您的资源的权利(授权)是有区别的。首先你必须证明你是谁,然后你才能访问你的东西。这是两个独立的步骤。

【讨论】:

    猜你喜欢
    • 2020-04-08
    • 2021-11-23
    • 2016-02-28
    • 2020-11-03
    • 2015-03-31
    • 2018-08-29
    • 2016-06-29
    • 2016-09-06
    • 2019-05-27
    相关资源
    最近更新 更多