fbpx

Demystifying How Authentication Works In Spring Security

Spring Security Authentication

In this Post of How Authentication Works In Spring Security , we will cover Authentication Flow in Spring Security . This is going to be a long article as we will be discussing Spring Security Authentication Full Flow .

Spring Security provides comprehensive security services for J2EE-based enterprise software applications. People use Spring Security for many reasons, but most are drawn to the project after finding the security features of J2EE’s Servlet Specification or EJB Specification lack the depth required for typical enterprise application scenarios.

Spring Security Works on Three Core Principles or Steps :-

  1. Authentication
  2. Authorization
  3. Exception handling

We Will See How Spring Initiates and Starts the Whole Authentication Process , but lets discuss Spring Authentication Flow , then we Will deep dive in upcoming Posts.

 

How Authentication Works In Spring Security :-

So Spring  Security basically is a chain of Servlet filters written for various purposes. Each of those filters are meant to do some specific task .

So there are different authentication mechanisms provided in Spring such as Http Basic , Form based login , Ouath1 etc . All these mechanisms are handled by Specific Filters Which extends AbstractAuthenticationProcessingFilter  .  So all requests are handle by this Filter and in the Whole Post we will name it as Authentication Filter. Have a look at different Filters and its Use cases .

How HTTPBasic Authentication Works In Spring Security :-

Once a Servlet request for HttpBasic Authentication reaches Spring Security , Authentication Filter Picks it up and tries to  decode Http Basic Headers . It then checks if Authentication is required or not . If authentication is required It Creates an  instance of UserNamepasswordAuthenticationToken  with username and token  and sets isAuthenticated(false)   This token is  then passed to AuthenticationManager  as shown in diagram below . 

SpringSecurityAuthenticationFlow

 How AuthenticationManager authenticates that token we will see in a while .Now the Authenticated value in this step is Still False till UserNamePassWordAuthenticationToken is passed to AuthenticationManager . So Once AuthenticationManager Processes the Request  with that Token Object  , the status of Authentication value is Changed to true in case of Successful authentication  as shown below else AuthenticationException is thrown.




authentication works in spring security

UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
						username, tokens[1]);				
Authentication authResult = authenticationManager.authenticate(authRequest);

How Authentication Manager handles Authentication In Spring Security:-

Authentication manager is Responsible for Handling Authentication , using different Authentication providers . We can also use a custom authentication Provider like Databse , LDAP etc. So the Sole responsibilty of AuthenticationProvider is to return an Authentication instance with Principal Object and Granted Authorities Populated .

AuthenticationManagerSpringSecurity

Have a look at AuthenticationManager Source Code :-

package org.springframework.security.authentication;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

public interface AuthenticationManager {
    Authentication authenticate(Authentication authentication) throwsAuthenticationException;
}

Once a user sends a request it  reaches the right authentication filter based on the authentication mechanism used.Now it extract the given credentials from the request and then using the supplied values UsernamePasswordAuthenticationToken is  created( the authentication object).Then  it calls ‘authenticate’ method of the Authentication Manager.

The request then passes to Authentication Provider and the Authentication Provider contains an implementation of UserDetailsService. Spring loads the user information in UserDetailsService  by calling loadbyuserName and compares the username/password combination with the credentials supplied at login.

If the user is valid then Authentication Manger creates UsernamePasswordAuthenticationToken  instance with follwing Constructor  , setting authenticated =true .

public UsernamePasswordAuthenticationToken(Object principal, Object credentials,
Collection<? extends GrantedAuthority> authorities) {
		super(authorities);
		this.principal = principal;
		this.credentials = credentials;
		super.setAuthenticated(true); // must use super, as we override
	}

UserNamePasswordAuthenticationToken is the Authentication object which is passed to authenticate method of Authentication Manager. Have a look how Authentication interface in Spring looks like

package org.springframework.security.core;

import java.io.Serializable;
import java.security.Principal;
import java.util.Collection;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.context.SecurityContextHolder;
public interface Authentication extends Principal, Serializable {
	Collection<? extends GrantedAuthority> getAuthorities();
	Object getCredentials();
	Object getDetails();
	Object getPrincipal();
	boolean isAuthenticated();
	void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;
}

Now this Authentication object  is then passed to Authentication Filter . Authentication Filter Sets the Authentication Object Containing Principal and Granted Authorities in Security Context  as Show below extending the above diagram.

How AuthenticationFilter and SecurityContext

How to Configure Multiple Authentication Providers In Spring Security :-

We can configure multiple AuthenticationProviders in Spring Security , that will return Authentication Object if any of them is sucessful .

Spring Security provides a number of AuthenticationProvider implementations,

  1. Dao AuthenticationProvider
  2. Cas AuthenticationProvider
  3. X509  AuthenticationProvider
  4. Jaas AuthenticationProvider
  5. Ldap AuthenticationProvider

In next Post We will See How We Can Create Custom Authentication Providers in Spring Security  and Explain the Authorization Flow .

Now that You have understood the Http-Basic Authentication mechanism in Spring , its same in case of other Authentication Mechanisms in Spring Security . Please let me know in frugalisminds@gmail.com  with Post title in Subject if you have any Questions or clarifications .

Summarizing Authentication Flow Spring Security :-

  • Authentication Filter creates an Authentication Request and Passes to Authentication Manager.
  • Authentication Manager delegates the request to Authentication Provider
  • Authentication Provider calls User Details service loads the User Details and returns the Authenticated Principal.
  • Authentication Manager returns the Authenticated Object to Authentication Filter and Authentication Filter sets the Authentication object in Security Context .

Note :- If you think closely we don’t need an User Details Service as well , the only things that is needed to Authentication Provider is an Authentication object with Principal as any Object and Granted Authorities .

This is the beauty of Spring Framework , where you always have an option to customize stuff.

More Posts On Spring Security :-

FilterChainProxy and DelegatingFilterProxy Uses

Using Custom Authentication Provider Spring Security

 

Article Written and Published By :- Subrat Padhi .

 

Major Difference Between ApplicationContext and BeanFactory in Spring Framework

Major Difference Between ApplicationContext and BeanFactory in Spring Framework :-

We are covering  Difference Between ApplicationContext and BeanFactory and Concepts of Inversion of Control (IOC) ApplicationContext vs BeanFactory vs WebApplicationContext . We will understand the basics of IOC and How ApplicationContext and BeanFactory work together.



Inversion Of Control:-

In a traditional application, the number of objects form together to make the application functionally working , hence the objects of application are dependencies to each other. We use numerous design patterns like Factory , Builder , Decorator to create various classes and create objects for the application . These patterns are best practices used by developers in order to address various problems .

The Spring Framework Inversion of Control (IOC) component or IOC Container provides a formalized means of composing different components into a fully working application ready for use, codifying these patterns.

Dependency Injection and IOC Container:-

Dependency injection (DI) is the implementation of IOC. The process of injecting objects into another object or class dependency is achieved through an assembler or a central configuration engine or an IOC Container. This container is responsible for assembling objects and supply wherever required.

So we need an IOC Container in a framework. The Spring framework also has an IOC Container in the form of ApplicationContext. 

IOC Container and Application Context

There are several implementations of the ApplicationContext interface as shown above. Now you must be wondering why I haven’t discussed BeanFactory. Let’s understand the difference now.

BeanFactory VS AplicationContext Vs WebApplicationContext:-

So ApplicationContext in Spring framework is built on top on BeanFactory and adds some extra functionality such as,

  1. Easy Integration With AOP
  2. Support for internationalization.
  3. Event Propagation

BeanFactory provides Core Configuration framework with basic functionalities, whereas Application context is with some more enhanced functionalities and more of  J2EE enterprise-centric.

Where to Use What?

Usage Scenario of BeanFactory is if you are more concerned about memory consumption and you don’t require all features of ApplicationContext, for eg- In an Applet environment where each memory bytes is important.

Usage Scenario of ApplicationContext is when building most applications in a J2EE-environment, the best option is to use the ApplicationContext since it offers all the features and functionalities of the BeanFactory. It also allows adding some additional customization on top of it.

ApplicationContext and BeanFactory

Please let me know in comments below  Did  you understood the basic concept of BeanFactory and ApplicationContext ?




Constructor Injection and Field Injection Misconception Cleared

constructor injection vs field injection

Constructor Injection and Field Injection Misconception Cleared:-

In this post i am gonna talk about Constructor and Field injection . It came out of a fight between me and my friend that Constructor Injections are better and we had a pretty much bad fight. It all started with this line in my code .

Lemme tell you one thing before we deep dive Constructor Injection and Field Injection is a debatable topic .

Let me know in comments what do you think .

@Autowired
private ClassA A;;

I used to be a huge fan of this piece of line . But I have been mistaken and I admit it .

I was aware of the dependency injection types  , but those differences seem to me good for interview or too much theoretical. It is possible that  I didn’t want to understand those in a deeper level .

Most of us are pretty much confident about writing a cleaner code and above line does makes our code clean . 


What Is Wrong :-

Using DI Containers we make sure that a class doesn’t have to manage its own dependencies , but here we are making our class to manage its own dependencies. Class should be more independent .Using a Constructor Injection here makes more sense.

Lets think of a scenario where your Service class has a field injected .Think a moment While writing test cases can you have a look a class and figure out the dependencies needed for the class ?? . No You cant , you have to go and explore the class , then you will be able to find out the dependencies used in your classes.

Now again , once you want to assign some mock values to your  private fields it is not easy .You have to setup a spring Context as Spring  can inject dependencies into private fields . You might need to use reflection in worst cases .

I know most people says reflection is common now a days , but my friend doing these , The Whole purpose of dependency injection goes for  a toss . As , the main purpose of DI was to write code that is easier to test and Write code that is highly decoupled.

Summarize What happens to Following Code :-

class MyService{
 
  @Autowired
  private ClassA A;
  
  public void doSomething() {
    A.doSomething();
  }
}

So basically what you are saying over here is :-

“I have this class with private state, to which I have attached @Autowired annotations, which means that the state can be automatically changed by some agent from the outside, even though my state has all been declared private.” 

Your JUNIT test cases starts breaking here as you will be doing below 

MyService service= new MyService();
service.doSomething(); // -> NullPointerException

You are allowing anyone to create a instance using default constructor and change state of your object which is not good.

How to Solve this :-

Well , we are going forward to explain Constructor Injection but  in terms of usability . Lets have a look at the solution of the above problem .

class MyService{
 
  private final ClassA A;
  
  @Inject
  public MyService(ClassA A) {
   
    this.A= A;
  }

  public void doSomething() {
    A.doSomething();
  }
}

Short Summary :-

  1. No null pointer as the class has the mandatory dependency provided at the time of creating object.
  2. Final fields adds too immutability here .
  3. As a consumer i know what all dependencies are required before creating object of this classs.
  4. Looks like a lot of code ? We can use Lombok to remove this boilerplate 
  5. If you feel you classes has a lot of dependencies , you probably need to rethink about your design and segregate your classes in different modules.




Have a Look In Case you Have a Frugalismind !

How to Configure SSL In Spring Boot 2

SSL Configuration Spring Boot 2.0

How to Configure SSL In Spring Boot 2:-

In this post, we are going to learn How to Configure SSL in Spring Boot 2. There are two different ways to configure SSL in Spring Boot 2.

  1. Using Default Configurations.
  2. Using Custom Configurations.

One of the prerequisites to Configure SSL is to have an SSL Certificate.

We can generate an SSL certificate ourselves known as a self-signed certificate for the development. 

In production, you should use a certificate issued by a trusted Certificate Authority (CA). It gives you a certificate file basically which we need to use in our code.

We will see how we can use the Self Signed Certificate file to Configure SSL In Spring Boot 2.

Tools and Technologies Used:-

  • Java JDK 8 (1.8.0_152)
  • Spring Boot 2.0.4.RELEASE
  • Maven 3.5

Using Basic Configurations to Setup SSL In Spring Boot 2:-

Spring Boot provides a way to configure SSL . We can mention few properties in our application and we are good to go.

Let’s Check a few of the properties below.

server.port=8443
security.require-ssl=true
server.ssl.key-store-type=JKS
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=frugalis007
server.ssl.key-alias=tomcat

As you can see in above properties we have used JKS keystore file type and given the name as keystore.jks This is the Self Signed Certificate has been generated and its copied under src/main/resources folder in spring boot.

While generating the Self Signed Certificate it asks for the password and we set alias which we have added in our properties.

As 8080 is considered to be a non-SSL port, We have configured the server port as 8443, to follow a standard.

Now Create a rest Service and run your application, you will be able to access the application using HTTPS. This is the simplest way to configure  SSL in any Spring Boot applications. Let’s have a look at the advanced level of configurations

Using Custom Configurations to Setup SSL in Spring Boot 2:-

Lets have a look at what we want here . We want our Keystore password to be encrypted in properties file using our own custom encryptor .

For the above requirement we need to Customize the Spring Boot SSL configurations.In Order to customize Spring Boot SSL configurations we need to Implement WebServerFactoryCustomizer

Any bean implementing this interface will get a callback with the server factory before the server itself is started . We can customize the Port ,Address,Password of the embedded Server.

package com.frugalis.ssl.App;

import java.io.File;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.apache.catalina.connector.Connector;
import org.apache.coyote.http11.Http11NioProtocol;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import com.frugalis.common.PasswordDecryptor;

@Component
@Profile("prod")
public class CustomServletContainer implements
		WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Inject
    private PasswordDecryptor passwordDecrypt;

	@Value("${key-store}")
	private String keystoreFile;
	@Value("${key-alias}")
	private String keystoreAlias;
	@Value("${key-store-type}")
	private String keystoreType;
	@Value("${key-password}")
	private String keystorePass;
        @Value("${port}")
        private int tlsPort;

	public void customize(TomcatServletWebServerFactory factory) {

		factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {

		@Override
		public void customize(Connector connector) {
		
		connector.setPort(8443);
                connector.setSecure(true);
                connector.setScheme("https");
                connector.setAttribute("keyAlias", "tomcat");
                connector.setAttribute("keystorePass", "password");

                File file = new File(keystoreFile);
                String absoluteKeystoreFile = file.getAbsolutePath();
                
                connector.setAttribute("keystoreFile", absoluteKeystoreFile);
                connector.setAttribute("clientAuth", "false");
                connector.setAttribute("sslProtocol", "TLS");
                connector.setAttribute("SSLEnabled", true);

                Http11NioProtocol proto = (Http11NioProtocol) connector.getProtocolHandler();

                proto.setSSLEnabled(true);
                proto.setKeystoreFile(keystoreFile);
                proto.setKeystorePass(keystorePass);
                proto.setKeystoreType(keystoreType);
                proto.setKeyAlias(keystoreAlias);
		}
		});
	}

    @PostConstruct
    public void ProcessPassword() {
          keystorePass = passwordDecrypt.decryptPassword(keystorePass);
    }  
}

We have Configured Profiling to enable SSL in production mode in Spring Boot 2 .

Note:- In  a typical commercial  production environment we basically don’t enable SSL in application level instead its preferred to enable in the VIP level . Let me know if you guys face any issues.

Load a File From Classpath In Spring Boot

How to Load a File From Class path Spring Boot

Load a File From Classpath In Spring Boot

In this post, we are going to check How to Load a File From Classpath In Spring Boot. Long back I was working on a very simple project.

We realized Reading a property source in Spring boot is easy and it can get tricky as well .

As Spring works on the concept of fat jar it is  good to know for developer the best ways to load a file from classpath  in spring boot .

In this post, we’ll see various ways to access and load the contents of a file that’s on the classpath using Spring.

I wanted to read a JSON file from the resources folder.src/main/resources Hence written a code something like this below.

	
        @Value("classpath:test.json")
	private Resource resource;

        File file = resource.getFile();

Now, this code works completely fine once I run it using,mvn:spring-boot:run but as soon I’m building and packaging the application using maven and running it as simple executable jar I’m getting an exception. Let’s go ahead and find out the solution now.

Using InputStream  

We can use InputStream to read a file from classpath in your Spring boot application . Let’s define the name of json file to be read with Resource .

        
        @Value("classpath:test.json")
	Resource resourceFile;

Let’s See How We can read the File , We will now show you actual code to Write and retrieve the content of file from your spring boot based application.

	
    private void testResource(Resource resource) {
		try {
			InputStream resourcee = resource.getInputStream();
			String text = null;
			try (final Reader reader = new InputStreamReader(resourcee)) {
				text = CharStreams.toString(reader);
			}
			System.out.println(text);

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

We have seen How we can Load a File From Classpath In Spring Boot If the file is inside a jar.

Reading as a File:-

There is another way to load resources in spring boot. We are now going to check how we can load a file from classpath in spring boot if the file is present in the filesystem not inside a jar.

	
	public void testResourceFile() throws IOException {
		File resource = new ClassPathResource("test.json").getFile();
		String text = new String(Files.readAllBytes(resource.toPath()));
	}

Reading Resource as ResourceLoader:-

ResourceLoader is used to loads resources from class-path as well as file system. It is one of the very commonly used way to read a file from classpath .

@Autowired
ResourceLoader resourceLoader;
Resource resource=resourceLoader.getResource("classpath:test.json");

Now we can use resource.getInputStream() or resource.getFile() as required.

Using ResourceUtils:-

Load a file from classpath in spring boot using ResourceUtils resolves the given resource location to a,java.io.File i.e. to a file in the file system.It doesn’t check if the file exists or not.

It is my most preferred way of doing it in any spring boot based application i am working .

ResourceUtils.getFile("classpath:test.json");

Note:-   Visit this Site to Understand More about Basics Of Java and Collections.

Server Side Load Balancing With Netflix Zuul and Eureka

Server Side Load balancing With Zuul & Eureka

Server Side Load Balancing With Netflix Zuul and Eureka:-

In this post, we will talk about server-side load balancing With Zuul and Eureka. Let us take a while and understand what is meant by server-side load balancing. In simple word, we distribute our user requests.In a Spring Cloud MicroServices ecosystem load balancing is an important and common functionality .

Zuul acts as a gateway for requests from websites, mobile devices to the backend of your service. Zuul is an edge service that provides dynamic routing, monitoring, resiliency, security, and many more features.

1. Why Do We Need Zuul:-

The amount of high traffic sometimes results in complex production issues. We want a system that can rapidly react to these changes. This technique was used when a new page from the website needed tuning for a smaller set of mobile devices or a group of customers.




If Performance problems, as well as unexplained errors, were observed. It was difficult to debug the issues because the problems were only happening for a small set of customers or a small set of devices. By diverting the traffic to a single instance, it becomes easier to debug in real time. It is done using Zuul filters in a netflix Zuul Load balancer. Zuul uses different types of filters that we can implement for various purpose, read more about this here.

2.Project Setup:-

We are going to set up and run three projects.

  1. Eureka Service Discovery – Service Registry for Our Backend Services. Please have a look at our previous example about Creating Eureka Service Discovery.
  2. Customer Service – A rest API which is basically a backend service in a real-time scenario. Visit my previous post about Writing  Service Rest With Spring Boot.
  3. Zuul Gateway – API Gateway to serve requests and call our internal backend services.in this case, it acts as a proxy and calls our customer service Internally.

3.Configure Zuul Communicating With Eureka

Now we have to Configure our  Zuul to Communicate with Eureka Server and mark our application as Zuul Proxy . To do this we need to use @EnableZuulProxy  annotation  in our main application file.

Add the following configuration in your  application.yml file.

spring:
  application:
    name: proxy-service

server:
  port: 8060

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

logging:
  pattern: 
    console: "%d{yyyy-MM-dd HH:mm:ss} ${LOG_LEVEL_PATTERN:-%5p} %m%n"
              
zuul:
  routes:
    customer:
      path: /customer/**
      serviceId: customer-service

Here we are registering our proxy server to Eureka service Registry assuming eureka running on 8761 port. Our Proxy Server will run on 8060.

We also configured routes for our Zuul proxy. We already have our customer service registered with Eureka Registry. Hence we now have just configured the routes to access the customer service.customer-service the name of the service we registered.

Once Zuul receives a request for a particular service , it internally uses Netflix Ribbon to lookup for services available from Eureka Service Discovery.

We can run multiple instances of our rest service and our API gateway will use both of the instances in round robin fashion.

Testing Zuul Eureka Service Discovery

Download Code