OAuth 2.0 如何获取令牌
1 2 3 4 5 6
| curl --location --request POST 'http://oauth-server/oauth/token' \ --header 'Authorization: Basic dGVzdDp0ZXN0' \ --data-urlencode 'username=admin' \ --data-urlencode 'password=123456' \ --data-urlencode 'scope=server' \ --data-urlencode 'grant_type=password'
|
1 2 3 4 5 6 7
| { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" }
|
- 原流程其实去访问 OAuth 2.0 提供的 /oauth/token 源码如下
TokenEndpoint.postAccessToken
1 2 3 4 5 6 7
| @RequestMapping(value = "/oauth/token", method=RequestMethod.POST) public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal, @RequestParam Map<String, String> parameters){ ... return getResponse(token);
}
|
自定义默认获取令牌地址
- 如上文,默认情况下我们需要访问 /oauth/token 获取,也就是所有业务系统的 “登录”接口 都变成这个地址,如何在不重写此接口的情况下,自定义路径地址。
- Spring Security OAuth2 为我们提供了丰富的 配置,我们可以在 AuthorizationServerConfigurerAdapter 设置所有内置端点 (Endpoint)路径的自定义 pathMapping
- 如下 使用 /aiops/login 覆盖 原有的/oauth/token,注意这里是覆盖一旦配置 原有路径将失效
1 2 3 4 5 6 7 8
| @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) { endpoints .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST) .pathMapping("/oauth/token","/login"); } }
|
获取令牌地址就变成如下
1 2 3 4 5 6
| curl --location --request POST 'http://oauth-server/pig4cloud/login' \ --header 'Authorization: Basic dGVzdDp0ZXN0' \ --data-urlencode 'username=admin' \ --data-urlencode 'password=123456' \ --data-urlencode 'scope=server' \ --data-urlencode 'grant_type=password'
|
源码剖析
- spring security oauth2 是如何实现 这种端点自定义配置的呢?
- AuthorizationServerEndpointsConfigurer 被写入到自定义 HandlerMapping
1 2 3 4 5 6 7 8 9
| private FrameworkEndpointHandlerMapping frameworkEndpointHandlerMapping() { if (frameworkEndpointHandlerMapping == null) { frameworkEndpointHandlerMapping = new FrameworkEndpointHandlerMapping(); frameworkEndpointHandlerMapping.setMappings(patternMap); frameworkEndpointHandlerMapping.setPrefix(prefix); frameworkEndpointHandlerMapping.setInterceptors(interceptors.toArray()); } return frameworkEndpointHandlerMapping; }
|
- SpringMVC DispatcherServlet 会根据新的规则 进行路由
