Closed tur-ing closed 8 years ago
OK, seems that this is not related to a CORS problem - it is more an authorization problem! The host is protected by Spring Security, so the socket listener can not access it (401 error):
Acutually, I would like to go through Zuul. Everything is working fine there now. But Zuul does not seem to have WebSocket proxy abilities.
UI Server
@SpringBootApplication
@EnableZuulProxy
@EnableOAuth2Sso
@EnableDiscoveryClient
public class SaCenterApplication extends WebSecurityConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(SaCenterApplication.class, args);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**").authorizeRequests()
.antMatchers("/index.html", "/home.html", "/").permitAll().anyRequest()
.authenticated().and().csrf().csrfTokenRepository(csrfTokenRepository())
.and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
}
private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request
.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null
|| token != null && !token.equals(cookie.getValue())) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
};
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
}
Authorization Server
@SpringBootApplication
@Configuration
@RestController
@EnableDiscoveryClient
@EnableResourceServer
@EnableAutoConfiguration
@EnableAuthorizationServer
public class SaAuthApplication {
@Autowired
private DataSource dataSource;
@RequestMapping("/user")
public Principal user(Principal user) {
return user;
}
public static void main(String[] args) {
SpringApplication.run(SaAuthApplication.class, args);
}
@Configuration
@EnableResourceServer
protected static class ResourceServer extends ResourceServerConfigurerAdapter {
@Autowired
private TokenStore tokenStore;
@Override
public void configure(ResourceServerSecurityConfigurer resources)
throws Exception {
resources.tokenStore(tokenStore);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated();
}
}
@Configuration
@EnableAuthorizationServer
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager auth;
@Autowired
private DataSource dataSource;
private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
@Bean
public JdbcTokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
@Bean
protected AuthorizationCodeServices authorizationCodeServices() {
return new JdbcAuthorizationCodeServices(dataSource);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security)
throws Exception {
security.passwordEncoder(passwordEncoder);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.authorizationCodeServices(authorizationCodeServices())
.authenticationManager(auth).tokenStore(tokenStore())
.approvalStoreDisabled();
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// @formatter:off
clients.jdbc(dataSource)
.passwordEncoder(passwordEncoder)
.withClient("my-trusted-client")
.authorizedGrantTypes("password", "authorization_code",
"refresh_token", "implicit")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("read", "write", "trust")
.resourceIds("oauth2-resource")
.accessTokenValiditySeconds(600).and()
.withClient("my-client-with-registered-redirect")
.authorizedGrantTypes("authorization_code")
.authorities("ROLE_CLIENT").scopes("read", "trust")
.resourceIds("oauth2-resource")
.redirectUris("http://anywhere?key=value").and()
.withClient("my-client-with-secret")
.authorizedGrantTypes("client_credentials", "password")
.authorities("ROLE_CLIENT").scopes("read")
.resourceIds("oauth2-resource").secret("secret");
// @formatter:on
}
}
@Autowired
public void init(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth.jdbcAuthentication().dataSource(dataSource).withUser("dave")
.password("secret").roles("USER");
// @formatter:on
}
}
Resource Server
@SpringBootApplication
@EnableDiscoveryClient
@EnableResourceServer
public class SaEmployeeApplication {
public static void main(String[] args) {
SpringApplication.run(SaEmployeeApplication.class, args);
}
}
That may a bit out of scope for what we want to cover in this tutorial.
Have you looked at https://spring.io/guides/tutorials/spring-security-and-angular-js/? I realize it's Angular and you are using React, but they cover a lot of stuff you are alluding to such as Spring Security, Zuul, and OAuth2. You might want to skim over it, and see if it addresses the issues you interested in tackling.
OK. @gregturn if you need ideas for a new tutorial, I have a lot of them ;-)
My desire for new tutorials is hedged by my ability to maintain them. ;)
I want to access the WebSocket from another host. I tried to set the
.setAllowedOrigins("*")
to enable CORS like this, which does not work: