Saturday, May 12, 2018

WebSockets Using Angular SpringBoot

STOMP:

Simple (or Streaming) Text Oriented Message Protocol (STOMP), formerly known as TTMP, is a simple text-based protocol, designed for working with message-oriented middleware (MOM). It provides an interoperable wire format that allows STOMP clients to talk with any message broker supporting the protocol.
The protocol is broadly similar to HTTP, and works over TCP using the following commands:
  1. CONNECT
  2. SEND
  3. SUBSCRIBE
  4. UNSUBSCRIBE
  5. BEGIN
  6. COMMIT
  7. ABORT
  8. ACK
  9. NACK
  10. DISCONNECT

Communication between client and server is through a "frame" consisting of a number of lines. The first line contains the command, followed by headers in the form <key>: <value> (one per line), followed by a blank line and then the body content, ending in a null character. Communication between server and client is through a MESSAGE, RECEIPT or ERROR frame with a similar format of headers and body content.

HTML5 Web Sockets

The HTML5 Web Sockets specification defines the Web Sockets API that enables web pages to use the Web Socket protocol for full-duplex communication with a remote host. It introduces the WebSocket interface and defines a full-duplex communication channel that operates through a single socket over the Web. 

To use HTML5 Web Sockets to connect from a Web client to a remote end-point, you create a new WebSocket instance and provide it with the URL that represents the end-point to which you want to connect. The specification defines a ws:// and a wss:// scheme to indicate WebSocket and WebSocket Secure connections, respectively. A WebSocket connection is established by upgrading from the HTTP protocol to the Web Socket protocol during the initial handshake between the client and the server, over the same underlying TCP/IP connection.



HTML5 Web Sockets use the HTTP Upgrade mechanism to upgrade to the Web Socket protocol. HTML5 Web Sockets feature an HTTP-compatible handshake so that HTTP servers can share their default HTTP and HTTPS ports (80 and 443) with a WebSocket server. To establish a WebSocket connection, the client and server upgrade from the HTTP protocol to the Web Socket protocol during an initial handshake, as shown in Example 1. Once established, WebSocket data frames can be sent back and forth between the client and the server in full-duplex mode.

Client to server:
GET /demo HTTP/1.1
Upgrade: WebSocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
WebSocket-Protocol: sample
Server to client:
HTTP/1.1 101 Web Socket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
WebSocket-Origin: http://example.com
WebSocket-Location: ws://example.com/demo
WebSocket-Protocol: sample

SockJS:


SockJS is a browser JavaScript library that provides a WebSocket-like object. SockJS gives you a coherent, cross-browser, Javascript API which creates a low latency, full duplex, cross-domain communication channel between the browser and the web server.
Under the hood SockJS tries to use native WebSockets first. If that fails it can use a variety of browser-specific transport protocols and presents them through WebSocket-like abstractions.
SockJS-client is intended to work for all modern browsers and in environments which don't support WebSocket protocol, for example behind restrictive corporate proxies. [ https://github.com/sockjs/sockjs-client ]
SockJS-node is a Node.js server side counterpart of SockJS-client browser library written in CoffeeScript. [ https://github.com/sockjs/sockjs-node ]

Spring WebSocket

WebSocket application may use a single URL only for the initial HTTP handshake. All messages thereafter share and flow on the same TCP connection. This points to an entirely different, asynchronous, event-driven, messaging architecture. One that is much closer to traditional messaging applications (e.g. JMS, AMQP).
Spring Framework 4 includes a new spring-messaging module with key abstractions from the Spring Integration project such as Message, MessageChannel, MessageHandler, and others that can serve as a foundation for such a messaging architecture.
The Spring Framework provides support for using STOMP — a simple, messaging protocol originally created for use in scripting languages with frames inspired by HTTP. STOMP is widely supported and well suited for use over WebSocket and over the web.

  1. Message — simple representation for a message including headers and payload. 
  2. MessageHandler — contract for handling a message. 
  3. MessageChannel — contract for sending a message that enables loose coupling between producers and consumers.
  4. SubscribableChannel — MessageChannel with MessageHandler subscribers.
  5. ExecutorSubscribableChannel — SubscribableChannel that uses an Executor for delivering messages. 

Setting Up of Web Socket Project:


  1.        Refer my last blogspot to setup Spring Boot Application
  2.        Add the following dependency in the pom.xml:
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-messaging</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>

3            3.  Override the handleTextMessage in MyHandler class:
public class MyHandler extends TextWebSocketHandler {

   @Override
   protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
          // TODO Auto-generated method stub
          System.out.println("Received Text Message");
          super.handleTextMessage(session, message);
   }
}

4. Enable WebSocket Configuration as shown below:
       @Configuration
       @EnableWebSocket
       public class WebSocketConfig implements WebSocketConfigurer{

       @Override
       public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
              // TODO Auto-generated method stub
              registry.addHandler(myHandler(), "/myHandler")
              .addInterceptors(new HttpSessionHandshakeInterceptor());
       }
      
       @Bean
       public WebSocketHandler myHandler()
       {
              return new MyHandler();
       }

   }

References:


https://tutorialedge.net/typescript/angular/angular-websockets-tutorial/
https://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/pdf/spring-framework-reference.pdf
https://en.wikipedia.org/wiki/Streaming_Text_Oriented_Messaging_Protocol
http://www.rabbitmq.com/stomp.html
https://www.infoq.com/articles/Web-Sockets-Proxy-Servers
https://stackoverflow.com/tags/sockjs/info
http://stomp.github.io/stomp-specification-1.2.html#Abstract
https://docs.spring.io/spring-integration/reference/pdf/spring-integration-reference.pdf
https://docs.spring.io/spring-integration/docs/4.3.x/reference/pdf/spring-integration-reference.pdf
http://www.baeldung.com/websockets-spring
http://www.devglan.com/spring-boot/spring-boot-angular-websocket

Thursday, April 26, 2018

Spring Security and Spring Boot Setup in Java Web Application

Features:

LDAP authentication, authorization, role-based access control,  remembers the password, URL protection, concurrent active sessions management 

Steps to Add Spring Security:

1.       Declare a delegating proxy filter in web.xml or using annotations.
2.       Add the ContextLoaderListener in web.xml or using annotations.
3.       Provide actual security constraints(security chain filter) on applicationContext-Security.xml or using annotations

Internal Flow of Spring Security:

1.       Filters are created, maintained and destroyed by Servlet Container.
2.       Web Container initializes the declared filters by calling their init(FilterConfig config) method.
3.       Filter  then delegates the actual pre-processing and post processing task to Spring Aware Filter implementations provided by Spring Framework

Steps to Call Spring Security Flow

1.       Every time a request or response comes and matches the URL pattern of the filter then Servlet container calls the DelegatingFilterProxy's doFilter() method for the request and response filtering.
2.       doFilter method has access to ServletRequest,ServletResponse and a FilterChain object, which means it can modify request headers,response headers and response body before sending the request to Servlet response to Client.
3.       Filter Chain Object has been used to further routing.

Version:

Spring Boot Version: 1.5.12
Java Version:8

Setting Up Eclipse Workspace:

1.       Create a simple maven project in Eclipse
2.       Add the following spring-boot project
                <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
                <modelVersion>4.0.0</modelVersion>
                <groupId>com.deepdiveonjava</groupId>
                <artifactId>SpringSecurityPOC</artifactId>
                <version>0.0.1-SNAPSHOT</version>
                <parent>
                                <groupId>org.springframework.boot</groupId>
                                <artifactId>spring-boot-starter-parent</artifactId>
                                <version>1.5.12.RELEASE</version>
                </parent>
      <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
      </properties>            
<!-- Add typical dependencies for a web application -->
                <dependencies>
                                <dependency>
                                                <groupId>org.springframework.boot</groupId>
                                                <artifactId>spring-boot-starter-web</artifactId>
                                </dependency>
 <dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
                </dependencies>
                <!-- Package as an executable jar -->
                <build>
                                <plugins>
                                                <plugin>
                                                                <groupId>org.springframework.boot</groupId>
                                                                <artifactId>spring-boot-maven-plugin</artifactId>
                                                </plugin>
                                </plugins>
                </build>
</project>
3.       Create the main class MyApplication:
@SpringBootApplication
public class MyApplication {
                public static void main(String[] args) {
                                // TODO Auto-generated method stub
                                SpringApplication.run(MyApplication.class, args);

                }

}
4.       Add WebSecurityConfig changes:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
//@Bean tag means it will add reference variable of                userDetailsService of type UserDetailsService in //Application context
        @Bean
        public UserDetailsService userDetailsService()
        {
                        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
                        manager.createUser(User.withUsername("rohit").password("jaimatadi").roles("USER").build());
                        return manager;
        }

}
5.       Add the SecurityWebApplicationInitializer in the project
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer{
        public SecurityWebApplicationInitializer()
        {
                        super(WebSecurityConfig.class);
        }

}
6.       Add WebController in the project:
@RestController
@RequestMapping(value = "/webcontroller")
public class WebController {
       
        @RequestMapping("/hello")
        public Map<String, Object> helloWorld() {
                        Map<String,Object> responseMap = new HashMap<String,Object>();
                        Map<String,Object> statusMap = new HashMap<String,Object>();
                        responseMap.put("id", "World");
                        statusMap.put("status", "Success");
                        statusMap.put("code", 200);
                        responseMap.put("response", statusMap);
                        return responseMap;
        }
}

Execution of the Project:

1.       Run the Spring Boot Application
2.       Hit the Controller link and you will redirected to the form login
3.       URL:
http://localhost:8080/webcontroller/hello
4.       It will be redirected to the Spring form login page and above credentials will work for the same.


References:

http://javarevisited.blogspot.in/2017/05/how-to-enable-spring-security-in-java-web-application.html
https://docs.spring.io/spring-boot/docs/1.5.12.RELEASE/reference/pdf/spring-boot-reference.pdf
https://docs.spring.io/spring-security/site/docs/4.2.x/reference/pdf/spring-security-reference.pdf
https://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/pdf/spring-framework-reference.pdf