首先,感谢https://github.com/liyiorg/weixin-popular,使用了一些关于微信的代码,其次,参考了网上一些springboot springsecurity oauth2 登录的文章。
自己的代码,自己测试过,微信登录木有问题。配置一下自己的appid和secret就可以使用,如果有问题,可以给我留言。
github:https://github.com/luotuo/springboot-security-wechat
MyOAuth2RestTemplate这个类也改了很多,因为微信的登录基本不怎么按照套路出牌,各种在改参数,所以代码里面也只能改改改。。。
欢迎大家fork、star、pr
也欢迎留言
这个文件很重要
@Configuration
@EnableWebSecurity //启用web权限
@EnableGlobalMethodSecurity(prePostEnabled = true) //启用方法验证
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Autowired
private MyFilterSecurityInterceptor myFilterSecurityInterceptor;
@Autowired
private OAuth2ClientContext oauth2ClientContext;
@Resource
private UserService userService;
@Resource
private UserWechatService userWechatService;
@Resource
private UserPrivilegeService userPrivilegeService;
@Resource
private PrivilegeConfigService privilegeConfigService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
//任何访问都必须授权
.anyRequest().fullyAuthenticated()
//配置那些路径可以不用权限访问
.mvcMatchers("/login", "/login/wechat").permitAll()
.and()
.formLogin()
//登陆成功后的处理,因为是API的形式所以不用跳转页面
.successHandler(new MyAuthenticationSuccessHandler())
//登陆失败后的处理
.failureHandler(new MySimpleUrlAuthenticationFailureHandler())
.and()
//登出后的处理
.logout().logoutSuccessHandler(new RestLogoutSuccessHandler())
.and()
//认证不通过后的处理
.exceptionHandling()
.authenticationEntryPoint(new RestAuthenticationEntryPoint());
http.addFilterAt(myFilterSecurityInterceptor, FilterSecurityInterceptor.class);
http.addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
//http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
http.csrf().disable();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder(){
//密码加密
//return new BCryptPasswordEncoder(16);
return new MyPasswordEncoder("2");
}
/**
* 登出成功后的处理
*/
public static class RestLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
//Do nothing!
}
}
/**
* 权限不通过的处理
*/
public static class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
"Authentication Failed: " + authException.getMessage());
}
}
@Bean
public FilterRegistrationBean oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(filter);
registration.setOrder(-100);
return registration;
}
@Bean
public Filter ssoFilter() {
CompositeFilter filter = new CompositeFilter();
List<Filter> filters = new ArrayList<>();
filters.add(ssoFilter(wechat(), "/login/wechat"));
filter.setFilters(filters);
return filter;
}
@Bean
public Filter ssoFilter(ClientResources client, String path) {
MappingJackson2HttpMessageConverter customJsonMessageConverter = new
MappingJackson2HttpMessageConverter();
customJsonMessageConverter.setSupportedMediaTypes(Arrays.asList(MediaType.TEXT_PLAIN));
MyOAuth2ClientAuthenticationProcessingFilter filter = new MyOAuth2ClientAuthenticationProcessingFilter(path);
filter.setAllowSessionCreation(true);
MyOAuth2RestTemplate template = new MyOAuth2RestTemplate(client.getClient(), oauth2ClientContext);
template.setMessageConverters(Arrays.asList(customJsonMessageConverter));
filter.setRestTemplate(template);
MyUserInfoTokenServices tokenServices = new MyUserInfoTokenServices(client.getResource().getUserInfoUri(),
client.getClient().getClientId(),
userService,
userWechatService,
userPrivilegeService,
privilegeConfigService);
tokenServices.setRestTemplate(template);
filter.setTokenServices(tokenServices);
return filter;
}
@Bean
@ConfigurationProperties(prefix = "wechat")
public ClientResources wechat() {
return new ClientResources();
}
}
class ClientResources {
@NestedConfigurationProperty
private AuthorizationCodeResourceDetails client = new AuthorizationCodeResourceDetails();
@NestedConfigurationProperty
private ResourceServerProperties resource = new ResourceServerProperties();
public AuthorizationCodeResourceDetails getClient() {
return client;
}
public ResourceServerProperties getResource() {
return resource;
}
}