™技术博客

框架 | 6.oauth2发放令牌接口地址自定义

2021年8月11日

OAuth 2.0 如何获取令牌


  • 以密码模式为例,获取 Token
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);

}

自定义默认获取令牌地址


  1. 如上文,默认情况下我们需要访问 /oauth/token 获取,也就是所有业务系统的 “登录”接口 都变成这个地址,如何在不重写此接口的情况下,自定义路径地址。
  2. Spring Security OAuth2 为我们提供了丰富的 配置,我们可以在 AuthorizationServerConfigurerAdapter 设置所有内置端点 (Endpoint)路径的自定义 pathMapping
  3. 如下 使用 /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 会根据新的规则 进行路由

扫描二维码,分享此文章