Spring security OAuth2 accept JSON

前端 未结 6 1854
深忆病人
深忆病人 2020-12-09 00:56

I am starting with Spring OAuth2. I would like to send the username and password to /oauth/token endpoint in POST body in application/json format.

curl -X PO         


        
6条回答
  •  清歌不尽
    2020-12-09 01:15

    Also you can modify @jakub-kopřiva solution to support http basic auth for oauth.

    Resource Server Configuration:

    @Configuration
    public class ServerEndpointsConfiguration extends ResourceServerConfigurerAdapter {
    
        @Autowired
        JsonToUrlEncodedAuthenticationFilter jsonFilter;
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
                .addFilterAfter(jsonFilter, BasicAuthenticationFilter.class)
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/test").permitAll()
                .antMatchers("/secured").authenticated();
        }
    }
    

    Filter with internal RequestWrapper

    @Component
    public class JsonToUrlEncodedAuthenticationFilter extends OncePerRequestFilter {
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    
            if (Objects.equals(request.getServletPath(), "/oauth/token") && Objects.equals(request.getContentType(), "application/json")) {
    
                byte[] json = ByteStreams.toByteArray(request.getInputStream());
    
                Map jsonMap = new ObjectMapper().readValue(json, Map.class);;
                Map 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);
            } else {
                filterChain.doFilter(request, response);
            }
        }
    
    
        private class RequestWrapper extends HttpServletRequestWrapper {
    
            private final Map params;
    
            RequestWrapper(HttpServletRequest request, Map 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 getParameterMap() {
                return this.params;
            }
    
            @Override
            public Enumeration getParameterNames() {
                return new Enumerator<>(params.keySet());
            }
    
            @Override
            public String[] getParameterValues(String name) {
                return params.get(name);
            }
        }
    }
    

    And also you need to allow x-www-form-urlencoded authentication

        @Configuration
    public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
    
        ...
    
        @Override
        public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
            oauthServer.allowFormAuthenticationForClients();
        }
    
        ...
    
    }
    

    With this approach you can still use basic auth for oauth token and request token with json like this:

    Header:

    Authorization: Basic bG9yaXpvbfgzaWNwYQ==
    

    Body:

    {
        "grant_type": "password", 
        "username": "admin", 
        "password": "1234"
    }
    

提交回复
热议问题