What is oauth2

What is oauth2

Introduction

Oauth2 设计的目的是为了可以让用户不用提供用户名密码给第三方,也能让第三方可以访问用户的resource。

例如 一个app 可以用微信登录,那就是指这个app会获取用户的微信name, logo 之类的信息去创建用户并登录。
当用户点击使用微信登录时,app会弹出微信授权的扫描界面,当用户打开微信扫描后,用户就可以登录这个app 了。
用户扫描微信授权的二维码,这个动作意味着
一 用户已经登录了微信,即完成了authentication; 二 扫描即表示授权,完成了authorization,即同意app获取用户的微信 user_profile.

这个过程,用户的密码是没有提供给app的,密码还是保存在微信这边,微信只是在用户授权完成之后,返回一个access_token 给app。app 既可用这个access_token 去获取用户的 user_profile 信息。

Information

  • resource owner
    An entity capable of granting access to a protected resource.
    When the resource owner is a person, it is referred to as an end-user.

    例子里这个就是用户

  • resource server
    The server hosting the protected resources, capable of accepting and responding to protected resource requests using access tokens.

    例子里这个就是微信平台

  • authorization server
    The server issuing access tokens to the client after successfully authenticating the resource owner and obtaining authorization.

    例子里这个就是微信平台

  • client
    An application making protected resource requests on behalf of the resource owner and with its authorization.

    例子里就是 app

如何使用oauth2

Client Registration

client 在使用oauth2 之前需要先注册到authorization server 才可以使用。

  • 为什么需要注册呢

通过注册 Client,授权服务器(Authorization Server)可以验证客户端的身份(例如通过 client_id 和 client_secret),确保只有合法的客户端能参与授权流程。

防止恶意应用冒充合法客户端(如钓鱼攻击)。

记录哪些客户端在访问资源,以便 追踪滥用行为(例如频繁请求令牌),统计使用情况或计费,在出现安全问题时快速撤销特定客户端的权限 等。

注册client 到authorization server, server 会返回client_id 和 client_secret 给 client。
client 注册的时候需要提供 redirection URI, client type 和其他一些信息例如 client 名字, description 等。

  • client type
    有 public 和 confidential 这两种。
    只有confidential才可以使用 client_secret。 因为public 无法保证client_secret的安全。

Client 申请authorization 的流程

Oauth 申请authorization grant的流程,根据grant type,有4种,分别是 authorization code, implicit, resource owner password credentials, and client credentials

这里只介绍用得最多也最通用的一种即 authorization code

The authorization code grant type 的类型是可以同时获取access token 和 refresh token的。
而且这种类型是一种 redirection-based 的flow,所以需要client 支持被回调。
下图这个流程是来自于RFC种的流程图,user-agent 一般是指 浏览器。

 +----------+
 | Resource |
 |   Owner  |
 |          |
 +----------+
      ^
      |
     (B)
 +----|-----+          Client Identifier      +---------------+
 |         -+----(A)-- & Redirection URI ---->|               |
 |  User-   |                                 | Authorization |
 |  Agent  -+----(B)-- User authenticates --->|     Server    |
 |          |                                 |               |
 |         -+----(C)-- Authorization Code ---<|               |
 +-|----|---+                                 +---------------+
   |    |                                         ^      v
  (A)  (C)                                        |      |
   |    |                                         |      |
   ^    v                                         |      |
 +---------+                                      |      |
 |         |>---(D)-- Authorization Code ---------'      |
 |  Client |          & Redirection URI                  |
 |         |                                             |
 |         |<---(E)----- Access Token -------------------'
 +---------+       (w/ Optional Refresh Token)

Note: The lines illustrating steps (A), (B), and ( C) are broken into two parts as they pass through the user-agent.

(A) The client 触发浏览器发送request 到authorization endpoint.
The client includes its client identifier, requested scope,
local state, and a redirection URI to which the authorization
server will send the user-agent back once access is granted (or denied).
这里 redirection URI 是optional的,如果不带则server使用在client registration 的提供的。

(B) 这个时候会弹出登录框提示用户输入用户名,密码来认证,认证后会显示需要授权的内容,用户再确认授权。

( C) 用户授权之后,server 会返回一个authorization code 并让浏览器通过redirection URI回到client.
类似下面这样
HTTP/1.1 302 Found Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz

(D) client 带上前面收到的 authorization code 和其他的一些参数来请求 server 的token endpoint 来获取token.
参数需要 grant_typecodeclient_id, redirect_uri(optional, must be identical and included if A step brings), client_secret(optional, if need authenticate client).

这个步骤有一个问题,就是server 怎么验证client 的身份呢?正对类型为credential的,client 可以带上client_secret,但是对于public 类型的,或者client_secret 不够安全的,容易泄露的,怎么验证申请token 的client 就是获得授权的client呢? 这个时候就可以使用 Proof Key for Code Exchange (PKCE) 了。

PKCE 是oauth2 流程的一种扩展,简单来说就是在client 在 A 步骤(authorization request)的时候带上一个随机数给server。
然后在申请token步骤中,client也带上相同的随机数,如果server校验和之前的一样,那就确实是相同的client。

(E) Authorization server 通过了client 的认证,则返回access token and, optionally, a refresh token。注意,这一步access token 是不会通过 user-agent 了,因为access token 是什么重要的,不能泄露。

access token无效了或过期了,就可以用refresh token 是用来获取access token 的。 注意 refresh token 是发送给oauthrization server 的,不能发给 resource server。 而access token是发给 resource server 去获取resource 的。

  +--------+                                           +---------------+
  |        |--(A)------- Authorization Grant --------->|               |
  |        |                                           |               |
  |        |<-(B)----------- Access Token -------------|               |
  |        |               & Refresh Token             |               |
  |        |                                           |               |
  |        |                            +----------+   |               |
  |        |--(C)---- Access Token ---->|          |   |               |
  |        |                            |          |   |               |
  |        |<-(D)- Protected Resource --| Resource |   | Authorization |
  | Client |                            |  Server  |   |     Server    |
  |        |--(E)---- Access Token ---->|          |   |               |
  |        |                            |          |   |               |
  |        |<-(F)- Invalid Token Error -|          |   |               |
  |        |                            +----------+   |               |
  |        |                                           |               |
  |        |--(G)----------- Refresh Token ----------->|               |
  |        |                                           |               |
  |        |<-(H)----------- Access Token -------------|               |
  +--------+           & Optional Refresh Token        +---------------+

               Figure: Refreshing an Expired Access Token

Client 获取resource

通过access token 获取 resource

 +--------+                               +---------------+
 |        |--(A)----- Access Token ------>|    Resource   |
 | Client |                               |     Server    |
 |        |<-(B)--- Protected Resource ---|               |
 +--------+                               +---------------+

           Figure: Access Protected Resource

References

Oauth2 specification

<think>Hmm, the user is asking about the usage between Java services and OAuth. Let me analyze this carefully based on the conversation history and references. First, looking back at the dialogue chain: The user initially asked "What is OAuth?" and received a comprehensive explanation. Then they followed up with a more specific query about Java-OAuth integration methods, citing several Java-related OAuth references [^1][^2][^3][^4][^5]. Ah, I notice all provided references are Java-focused - particularly about implementing OAuth 2.0 servers/clients in Java. The user seems to be transitioning from conceptual understanding to practical implementation. Their actual need appears to be: "As a Java developer, how do I actually implement OAuth in my services?" Breaking this down: - They'll need server-side components (authorization server setup) - Client integration techniques - Token handling workflows - Probably Spring Security OAuth2 given the Java context [^1][^4] - Database considerations for token storage [^5] The references mention key technical points: [^1] and [^4] discuss full Java-based OAuth implementation including auth/resource servers [^2] emphasizes Java's role in secure API authorization [^3] shows actual token request code [^5] reveals database-backed token management I should structure the response around implementation phases while weaving in these reference points. The user is clearly at the "how-to" stage after grasping OAuth basics. Since they cited Spring-specific examples, I'll focus on that ecosystem while keeping concepts transferable. Potential pitfalls to address: - Overwhelming the user with Spring Security complexity - Neglecting token security best practices - Forgetting practical examples like the code snippet in [^3] Better organize by development lifecycle: setup→configuration→client integration→security hardening. The JDBC token storage mention in [^5] is particularly valuable for production scenarios. Should demonstrate with concrete class/method names like AuthorizationCodeServices bean [^5] and OAuthAccessTokenResponse usage [^3]. </think>以下详细说明Java服务与OAuth的整合方法,结合引用内容分步解析核心实现: --- ### 一、OAuthJava中的核心组件 1. **授权服务器配置** - 使用Spring Security OAuth2库创建授权服务器 - 关键配置项: ```java @Configuration @EnableAuthorizationServer public class AuthServerConfig extends AuthorizationServerConfigurerAdapter { @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("web-app") // 客户端ID .secret(passwordEncoder.encode("secret")) // 密钥 .authorizedGrantTypes("authorization_code", "refresh_token") // 授权类型 .scopes("read", "write"); // 权限范围 } } ``` 参考数据库存储方案可改用`JdbcClientDetailsService`[^5] 2. **资源服务器保护API** - 验证访问令牌并拦截非法请求: ```java @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/api/**").authenticated(); // 保护API路径 } } ``` --- ### 二、客户端接入流程(授权码模式) 1. **用户重定向到授权端点** ```java String authUrl = "https://auth-server/oauth/authorize?" + "response_type=code&" + "client_id=web-app&" + "redirect_uri=http://client/callback"; response.sendRedirect(authUrl); // 触发用户授权 ``` 2. **获取访问令牌** - 用授权码交换令牌: ```java OAuthAccessTokenResponse tokenResponse = oAuthClient.accessToken( new AccessTokenRequest(authorizationCode, redirectUri), OAuth.HttpMethod.POST ); // 通过HTTP POST请求令牌[^3] String accessToken = tokenResponse.getAccessToken(); ``` 3. **调用受保护API** ```java HttpHeaders headers = new HttpHeaders(); headers.setBearerAuth(accessToken); // 令牌放入Authorization头 ResponseEntity<String> response = restTemplate.exchange( "https://resource-server/api/data", HttpMethod.GET, new HttpEntity<>(headers), String.class ); ``` --- ### 三、关键安全实践 1. **令牌存储** - 推荐数据库存储(如`oauth_access_token`表)替代内存存储[^5] - 使用JdbcTokenStore: ```java @Bean public TokenStore tokenStore(DataSource dataSource) { return new JdbcTokenStore(dataSource); } ``` 2. **加密配置** ```java @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); // 强哈希加密 } ``` 3. **刷新令牌机制** ```java if (tokenResponse.getExpiresIn() < 300) { // 令牌即将过期 RefreshTokenRequest refreshRequest = new RefreshTokenRequest( tokenResponse.getRefreshToken(), clientCredentials ); tokenResponse = oAuthClient.refreshToken(refreshRequest); } ``` --- ### 四、典型应用场景 | 场景 | 实施方案 | 优势 | |---------------------|----------------------------------|--------------------------| | 单点登录(SSO) | 多个服务共用同一授权服务器 | 统一认证入口[^1] | | API网关保护 | 网关层集成资源服务器配置 | 统一鉴权控制[^4] | | 第三方应用集成 | 提供authorization_code授权流程 | 避免密码泄露[^2] | > 通过标准化OAuth流程,Java应用可实现: > ✅ 用户身份与第三方应用解耦 [^2] > ✅ 细粒度资源访问控制 [^4] > ✅ 令牌自动刷新机制提升体验 [^1] ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值