// Path: wechat-mp-autoconfigure/src/main/java/com/github/hippoom/wechat/mp/security/web/RestAuthenticationEntryPoint.java
// public class RestAuthenticationEntryPoint
//     implements AuthenticationEntryPoint {
// 
//     @Override
//     public void commence(
//         HttpServletRequest request,
//         HttpServletResponse response,
//         AuthenticationException authException) throws IOException {
//         // This is invoked when user tries to access a secured REST resource
//         // without supplying any credentials
//         // We should just send a 401 Unauthorized response
//         // because there is no 'login page' to redirect to
//         response.sendError(SC_UNAUTHORIZED, "Unauthorized");
//     }
// }
// 
// Path: wechat-mp-autoconfigure/src/main/java/com/github/hippoom/wechat/mp/security/web/authentication/WeChatMpOAuth2AuthenticationProcessingFilter.java
// public class WeChatMpOAuth2AuthenticationProcessingFilter
//     extends AbstractAuthenticationProcessingFilter {
// 
//     @Setter
//     private WxMpService wxMpService;
// 
//     public WeChatMpOAuth2AuthenticationProcessingFilter(String defaultFilterProcessesUrl) {
//         super(defaultFilterProcessesUrl);
//     }
// 
//     public WeChatMpOAuth2AuthenticationProcessingFilter(
//         RequestMatcher requiresAuthenticationRequestMatcher) {
//         super(requiresAuthenticationRequestMatcher);
//     }
// 
//     @SneakyThrows
//     @Override
//     public Authentication attemptAuthentication(HttpServletRequest request,
//         HttpServletResponse response)
//         throws AuthenticationException, IOException, ServletException {
// 
//         final String code = request.getParameter("code");
// 
//         WxMpOAuth2AccessToken accessToken = wxMpService.oauth2getAccessToken(code);
// 
//         return new WeChatMpOAuth2AccessTokenAuthentication(accessToken);
//     }
// }
// 
// Path: wechat-mp-autoconfigure/src/main/java/com/github/hippoom/wechat/mp/security/web/authentication/WeChatMpOAuth2AuthenticationSuccessHandler.java
// public class WeChatMpOAuth2AuthenticationSuccessHandler implements AuthenticationSuccessHandler {
// 
//     public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
//         Authentication authentication) throws IOException, ServletException {
// 
//         String origin = request.getParameter("state");
// 
//         URL raw = new URL(
//             new String(Base64.getUrlDecoder().decode(origin.getBytes(Charset.forName("UTF-8"))),
//                 Charset.forName("UTF-8")));
//         response.sendRedirect(raw.toString());
//     }
// }


import static org.springframework.security.config.http.SessionCreationPolicy.IF_REQUIRED;
import com.github.hippoom.wechat.mp.security.web.RestAuthenticationEntryPoint;
import com.github.hippoom.wechat.mp.security.web.authentication.WeChatMpOAuth2AuthenticationProcessingFilter;
import com.github.hippoom.wechat.mp.security.web.authentication.WeChatMpOAuth2AuthenticationSuccessHandler;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.mp.api.WxMpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.security.web.csrf.CsrfAuthenticationStrategy;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
     * @return see {@link RequestMatcher}
     */
    protected RequestMatcher requireCsrfProtectionMatcher() {
        return new AntPathRequestMatcher("/rel/**/me");
    }

    @Bean
    protected CsrfTokenRepository csrfTokenRepository() {
        return CookieCsrfTokenRepository.withHttpOnlyFalse();
    }

    @Bean
    protected CsrfAuthenticationStrategy sessionAuthenticationStrategy() {
        return new CsrfAuthenticationStrategy(csrfTokenRepository());
    }


    @Bean
    protected RestAuthenticationEntryPoint restAuthenticationEntryPoint() {
        return new RestAuthenticationEntryPoint();
    }

    protected WeChatMpOAuth2AuthenticationProcessingFilter
        // @formatter:off
        weChatMpOAuth2AuthenticationProcessingFilter(WxMpService wxMpService) {

        WeChatMpOAuth2AuthenticationProcessingFilter filter =
            new WeChatMpOAuth2AuthenticationProcessingFilter("/wechat/oauth/token");
        filter.setWxMpService(wxMpService);
        filter
// Path: wechat-mp-autoconfigure/src/main/java/com/github/hippoom/wechat/mp/security/web/RestAuthenticationEntryPoint.java
// public class RestAuthenticationEntryPoint
//     implements AuthenticationEntryPoint {
// 
//     @Override
//     public void commence(
//         HttpServletRequest request,
//         HttpServletResponse response,
//         AuthenticationException authException) throws IOException {
//         // This is invoked when user tries to access a secured REST resource
//         // without supplying any credentials
//         // We should just send a 401 Unauthorized response
//         // because there is no 'login page' to redirect to
//         response.sendError(SC_UNAUTHORIZED, "Unauthorized");
//     }
// }
// 
// Path: wechat-mp-autoconfigure/src/main/java/com/github/hippoom/wechat/mp/security/web/authentication/WeChatMpOAuth2AuthenticationProcessingFilter.java
// public class WeChatMpOAuth2AuthenticationProcessingFilter
//     extends AbstractAuthenticationProcessingFilter {
// 
//     @Setter
//     private WxMpService wxMpService;
// 
//     public WeChatMpOAuth2AuthenticationProcessingFilter(String defaultFilterProcessesUrl) {
//         super(defaultFilterProcessesUrl);
//     }
// 
//     public WeChatMpOAuth2AuthenticationProcessingFilter(
//         RequestMatcher requiresAuthenticationRequestMatcher) {
//         super(requiresAuthenticationRequestMatcher);
//     }
// 
//     @SneakyThrows
//     @Override
//     public Authentication attemptAuthentication(HttpServletRequest request,
//         HttpServletResponse response)
//         throws AuthenticationException, IOException, ServletException {
// 
//         final String code = request.getParameter("code");
// 
//         WxMpOAuth2AccessToken accessToken = wxMpService.oauth2getAccessToken(code);
// 
//         return new WeChatMpOAuth2AccessTokenAuthentication(accessToken);
//     }
// }
// 
// Path: wechat-mp-autoconfigure/src/main/java/com/github/hippoom/wechat/mp/security/web/authentication/WeChatMpOAuth2AuthenticationSuccessHandler.java
// public class WeChatMpOAuth2AuthenticationSuccessHandler implements AuthenticationSuccessHandler {
// 
//     public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
//         Authentication authentication) throws IOException, ServletException {
// 
//         String origin = request.getParameter("state");
// 
//         URL raw = new URL(
//             new String(Base64.getUrlDecoder().decode(origin.getBytes(Charset.forName("UTF-8"))),
//                 Charset.forName("UTF-8")));
//         response.sendRedirect(raw.toString());
//     }
// }


// Path: wechat-mp-autoconfigure/src/main/java/com/github/hippoom/wechat/mp/autoconfigure/security/web/WeChatMpWebSecurityConfigurerAdapter.java
import static org.springframework.security.config.http.SessionCreationPolicy.IF_REQUIRED;
import com.github.hippoom.wechat.mp.security.web.RestAuthenticationEntryPoint;
import com.github.hippoom.wechat.mp.security.web.authentication.WeChatMpOAuth2AuthenticationProcessingFilter;
import com.github.hippoom.wechat.mp.security.web.authentication.WeChatMpOAuth2AuthenticationSuccessHandler;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.mp.api.WxMpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.security.web.csrf.CsrfAuthenticationStrategy;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;

     * @return see {@link RequestMatcher}
     */
    protected RequestMatcher requireCsrfProtectionMatcher() {
        return new AntPathRequestMatcher("/rel/**/me");
    }

    @Bean
    protected CsrfTokenRepository csrfTokenRepository() {
        return CookieCsrfTokenRepository.withHttpOnlyFalse();
    }

    @Bean
    protected CsrfAuthenticationStrategy sessionAuthenticationStrategy() {
        return new CsrfAuthenticationStrategy(csrfTokenRepository());
    }


    @Bean
    protected RestAuthenticationEntryPoint restAuthenticationEntryPoint() {
        return new RestAuthenticationEntryPoint();
    }

    protected WeChatMpOAuth2AuthenticationProcessingFilter
        // @formatter:off
        weChatMpOAuth2AuthenticationProcessingFilter(WxMpService wxMpService) {

        WeChatMpOAuth2AuthenticationProcessingFilter filter =
            new WeChatMpOAuth2AuthenticationProcessingFilter("/wechat/oauth/token");
        filter.setWxMpService(wxMpService);
        filter
            .setAuthenticationSuccessHandler(new WeChatMpOAuth2AuthenticationSuccessHandler());