Spring Security and JSON Authentication

前端 未结 8 1693
我在风中等你
我在风中等你 2020-11-28 05:11

I\'ve an application in spring/spring-mvc that totally uses JSON communications. Now I need to authenticate my application with spring security 3 (that uses LdapAuthenticati

8条回答
  •  臣服心动
    2020-11-28 05:44

    Look at this example: https://github.com/fuhaiwei/springboot_security_restful_api

    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Autowired
        private UserDetailsService userDetailsService;
    
        @Autowired
        private CustomLoginHandler customLoginHandler;
    
        @Autowired
        private CustomLogoutHandler customLogoutHandler;
    
        @Autowired
        private CustomAccessDeniedHandler customAccessDeniedHandler;
    
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(userDetailsService);
        }
    
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .antMatchers("/api/admin/**").hasRole("ADMIN")
                    .antMatchers("/api/basic/**").hasRole("BASIC")
                    .antMatchers("/api/session").permitAll()
                    .antMatchers(HttpMethod.GET).permitAll()
                    .antMatchers("/api/**").hasRole("BASIC");
    
            http.formLogin();
    
            http.logout()
                    .logoutUrl("/api/session/logout")
                    .addLogoutHandler(customLogoutHandler)
                    .logoutSuccessHandler(customLogoutHandler);
    
            http.exceptionHandling()
                    .accessDeniedHandler(customAccessDeniedHandler)
                    .authenticationEntryPoint(customAccessDeniedHandler);
    
            http.csrf()
                    .ignoringAntMatchers("/api/session/**");
    
            http.addFilterBefore(new AcceptHeaderLocaleFilter(), UsernamePasswordAuthenticationFilter.class);
    
            http.addFilterAt(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    
            http.addFilterAfter(new CsrfTokenResponseHeaderBindingFilter(), CsrfFilter.class);
        }
    
        private CustomAuthenticationFilter customAuthenticationFilter() throws Exception {
            CustomAuthenticationFilter filter = new CustomAuthenticationFilter();
            filter.setAuthenticationSuccessHandler(customLoginHandler);
            filter.setAuthenticationFailureHandler(customLoginHandler);
            filter.setAuthenticationManager(authenticationManager());
            filter.setFilterProcessesUrl("/api/session/login");
            return filter;
        }
    
        private static void responseText(HttpServletResponse response, String content) throws IOException {
            response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
            byte[] bytes = content.getBytes(StandardCharsets.UTF_8);
            response.setContentLength(bytes.length);
            response.getOutputStream().write(bytes);
            response.flushBuffer();
        }
    
        @Component
        public static class CustomAccessDeniedHandler extends BaseController implements AuthenticationEntryPoint, AccessDeniedHandler {
            // NoLogged Access Denied
            @Override
            public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
                responseText(response, errorMessage(authException.getMessage()));
            }
    
            // Logged Access Denied
            @Override
            public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {
                responseText(response, errorMessage(accessDeniedException.getMessage()));
            }
        }
    
        @Component
        public static class CustomLoginHandler extends BaseController implements AuthenticationSuccessHandler, AuthenticationFailureHandler {
            // Login Success
            @Override
            public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
                LOGGER.info("User login successfully, name={}", authentication.getName());
                responseText(response, objectResult(SessionController.getJSON(authentication)));
            }
    
            // Login Failure
            @Override
            public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException {
                responseText(response, errorMessage(exception.getMessage()));
            }
        }
    
        @Component
        public static class CustomLogoutHandler extends BaseController implements LogoutHandler, LogoutSuccessHandler {
            // Before Logout
            @Override
            public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
    
            }
    
            // After Logout
            @Override
            public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
                responseText(response, objectResult(SessionController.getJSON(null)));
            }
        }
    
        private static class AcceptHeaderLocaleFilter implements Filter {
            private AcceptHeaderLocaleResolver localeResolver;
    
            private AcceptHeaderLocaleFilter() {
                localeResolver = new AcceptHeaderLocaleResolver();
                localeResolver.setDefaultLocale(Locale.US);
            }
    
            @Override
            public void init(FilterConfig filterConfig) {
            }
    
            @Override
            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
                Locale locale = localeResolver.resolveLocale((HttpServletRequest) request);
                LocaleContextHolder.setLocale(locale);
    
                chain.doFilter(request, response);
            }
    
            @Override
            public void destroy() {
            }
        }    
    }
    
    
    
    public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    
        @Override
        public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
            UsernamePasswordAuthenticationToken authRequest;
            try (InputStream is = request.getInputStream()) {
                DocumentContext context = JsonPath.parse(is);
                String username = context.read("$.username", String.class);
                String password = context.read("$.password", String.class);
                authRequest = new UsernamePasswordAuthenticationToken(username, password);
            } catch (IOException e) {
                e.printStackTrace();
                authRequest = new UsernamePasswordAuthenticationToken("", "");
            }
            setDetails(request, authRequest);
            return this.getAuthenticationManager().authenticate(authRequest);
        }
    
    }
    

提交回复
热议问题