Use spring security application / json receiving data

Use spring security application / json receiving data


Look at the simple use of security do not understand security

https://blog.51cto.com/5013162/2404946


When using spring security login user found using the application / josn can not get back into the data
to see UsernamePasswordAuthenticationFilter source found

    //获取密码
    protected String obtainPassword(HttpServletRequest request) {
         return request.getParameter(passwordParameter);
    }
    //获取用户名
    protected String obtainUsername(HttpServletRequest request) {
         return request.getParameter(usernameParameter);
    }

It is acquired not from requestBody directly from the request of

Then we just need to override both methods to obtain the parameters from requestBody

Rewrite UsernamePasswordAuthenticationFilter class

    public class UserAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

        private ThreadLocal<Map<String,String>> threadLocal = new ThreadLocal<>();

        @Override
        protected String obtainPassword(HttpServletRequest request) {
                String password = this.getBodyParams(request).get(super.SPRING_SECURITY_FORM_PASSWORD_KEY);
                if(!StringUtils.isEmpty(password)){
                        return password;
                }
                return super.obtainPassword(request);
        }

        @Override
        protected String obtainUsername(HttpServletRequest request) {
                String username = this.getBodyParams(request).get(super.SPRING_SECURITY_FORM_USERNAME_KEY);
                if(!StringUtils.isEmpty(username)){
                        return username;
                }
                return super.obtainUsername(request);
        }

        /**
         * 获取body参数  body中的参数只能获取一次 
         * @param request
         * @return
         */
        private Map<String,String> getBodyParams(HttpServletRequest request){
                Map<String,String> bodyParams =  threadLocal.get();
                if(bodyParams==null) {
                        ObjectMapper objectMapper = new ObjectMapper();
                        try (InputStream is = request.getInputStream()) {
                                bodyParams = objectMapper.readValue(is, Map.class);
                        } catch (IOException e) {
                        }
                        if(bodyParams==null) bodyParams = new HashMap<>();
                        threadLocal.set(bodyParams);
                }

                return bodyParams;
        }
}

自定义 SecurityConfig 类

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

        @Autowired
        UserDetailServiceImpl userDetailService;
        @Autowired
        LoginSuccessHandler loginSuccessHandler;

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
                //自定义用户验证和加密方式
                auth.userDetailsService(userDetailService).passwordEncoder(new BCryptPasswordEncoder());
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
                http.formLogin()                    //  定义当需要用户登录时候,转到的登录页面。
        //          .loginPage("/login.html") //自定义登录页面
//                .loginProcessingUrl("/login") //自定义登录接口地址
//                .successHandler(loginSuccessHandler)
                                .and()
                                // 定义哪些URL需要被保护、哪些不需要被保护
                                .authorizeRequests().antMatchers("/login").permitAll() //不需要保护的URL
                                .anyRequest()               // 任何请求,登录后可以访问
                                .authenticated()
                                .and()
                                .logout().logoutSuccessUrl("/login").permitAll() // 登出
                                .and()
                                .csrf().disable();
                //配置自定义过滤器 增加post json 支持
                http.addFilterAt(UserAuthenticationFilterBean(), UsernamePasswordAuthenticationFilter.class);
        }

        private UserAuthenticationFilter UserAuthenticationFilterBean() throws Exception {
                UserAuthenticationFilter userAuthenticationFilter = new UserAuthenticationFilter();
                userAuthenticationFilter.setAuthenticationManager(super.authenticationManager());
                userAuthenticationFilter.setAuthenticationSuccessHandler(loginSuccessHandler);
                return userAuthenticationFilter;
        }
}

Log successfully processed class
LoginSuccessHandler.class

@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
        @Override
        public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {

                httpServletResponse.setContentType("application/json;charset=UTF-8");

                httpServletResponse.getWriter().write(authentication.getName());
        }
}

A user verification process based

@Component
public class UserDetailServiceImpl implements UserDetailsService {
        /**
         * 用户校验
         * @param s
         * @return
         * @throws UsernameNotFoundException
         */
        @Override
        public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
                Collection<GrantedAuthority> collection = new ArrayList<>();//权限集合
                String password = new BCryptPasswordEncoder().encode("123456");
                User user = new User(s,password,collection);

                return user;
        }

}

Transformation was complete support post application / json also supports post form-data / x-www -form-urlencoded
can get to the incoming parameters

Guess you like

Origin blog.51cto.com/5013162/2408405