™技术博客

框架 | 15.SpringSecurityOauth2获取token接口改造支持json提交

2021年8月16日

背景


原始接口问题:仅支持url Params

  • TokenEndpount.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    @RequestMapping(value = "/oauth/token", method=RequestMethod.POST)
    public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal, @RequestParam
    Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
    ...
    }
    ```


    ## 改造

    ---

    ### 1. 定义filter

    ```java
    @Component
    public class JsonToUrlEncodedAuthenticationFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

    if (StrUtil.equalsIgnoreCase(request.getServletPath(), SecurityConstants.OAUTH_TOKEN_URL)
    && StrUtil.equalsIgnoreCase(request.getContentType(), "application/json")
    && HttpMethod.POST.name().equalsIgnoreCase(request.getMethod())
    ) {
    byte[] json = ByteStreams.toByteArray(request.getInputStream());
    if (ArrayUtil.isNotEmpty(json)) {
    Map<String, String> jsonMap = new ObjectMapper().readValue(json, Map.class);;
    Map<String, String[]> parameters =
    jsonMap.entrySet().stream()
    .collect(Collectors.toMap(
    Map.Entry::getKey,
    e -> new String[]{e.getValue()})
    );
    HttpServletRequest requestWrapper = new RequestWrapper(request, parameters);
    filterChain.doFilter(requestWrapper, response);
    return;
    }
    }
    filterChain.doFilter(request, response);
    }

    private class RequestWrapper extends HttpServletRequestWrapper {

    private final Map<String, String[]> params;

    RequestWrapper(HttpServletRequest request, Map<String, String[]> params) {
    super(request);
    this.params = params;
    }

    @Override
    public String getParameter(String name) {
    if (this.params.containsKey(name)) {
    return this.params.get(name)[0];
    }
    return "";
    }

    @Override
    public Map<String, String[]> getParameterMap() {
    return this.params;
    }

    @Override
    public Enumeration<String> getParameterNames() {
    return new Enumerator<>(params.keySet());
    }

    @Override
    public String[] getParameterValues(String name) {
    return params.get(name);
    }
    }
    }

    2. 配置拦截器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Primary
@Order(90)
@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {

@Autowired
JsonToUrlEncodedAuthenticationFilter jsonFilter;

@Override
@SneakyThrows
protected void configure(HttpSecurity http) {
http.addFilterBefore(jsonFilter, ChannelProcessingFilter.class);
http.authorizeRequests().antMatchers("/token/**", "/actuator/**", "/mobile/**").permitAll()
.anyRequest().authenticated().and().csrf().disable();
}

}

调用

1
2
3
4
5
6
7
8
9
10
11
curl --location --request POST 'http://localhost:8003/oauth/token' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic dGVzdDp0ZXN0' \
--data-raw '{
"username": "admin",
"password": "123456",
"grant_type": "password",
"scope": "server",
"random": "123456",
"code": "wann"
}'

扫描二维码,分享此文章