fbpx

Using Custom Authentication Provider Spring Security

Custom Auth Provider Spring Security

In this post we are going to find out why we need Custom Authentication Provider in Spring Security . Why do we need to implement this .

If You have  followed previous post about Flow of Authentication in Spring Security .

Spring Security has several areas where patterns you have defined are tested against incoming requests in order to decide how the request should be handled.

How Authentication Provider Flow Start :-

This occurs when the FilterChainProxy decides which filter chain a request should be passed through and also when the FilterSecurityInterceptor decides which security constraints apply to a request.

Once it reaches the right authentication filter based on the authentication mechanism used ,  it extract the given credentials  from the request and then using the supplied values it creates the authentication object.

The it calls 'authenticate' method of the AuthenticationManager.

Now once Authentication manager tries to authenticate the request it  passes through the authentication providers to authenticate the user.

All the Authentication Providers inside spring security framework implement this interface .

Have a look at the Authentication Provider interface below :-

package org.springframework.security.authentication;

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

public interface AuthenticationProvider {
	Authentication authenticate(Authentication authentication)
			throws AuthenticationException;

	boolean supports(Class<?> authentication);
}

Now As you know for Writing a Custom Authentication provider in Spring Security , you basically should create your own implementation .

But Wait , Lets find out Why do we need a Custom Authentication Provider in Your Spring based applications by example .

Use Cases where we Need Custom Authentication Provider :-

Lets say you are using authentication services provided by some third party in the form of Jar or an API.

In that case you can use the Spring Security Custom Authentication Provider to validate the username and password using the API . Once the validation is successful  we create the Authentication object and return to Spring Security framework.

Lets Implement a Custom Authentication Provider In Spring Security , by implementing Authentication Provider interface .

Lets Configure Spring Boot First before Configuring Custom Authentication Provider .

Configure Spring Security Configuration for Custom Provider 

package com.frugalis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
@ComponentScan("com.frugalis")
public class CustAuthProviderConfig extends WebSecurityConfigurerAdapter {
  
    @Autowired
    private CustomAuthenticationProvider authProvider;
 
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authProvider);
    }
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated()
            .and().httpBasic();
    }
}

The above code registers a custom authentication provider and authorize users .Now lets define a Custom Authentication Provider

package com.frugalis;

import java.util.ArrayList;
import java.util.List;

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

	boolean shouldAuthenticateAgainstThirdPartySystem = true;

	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		String name = authentication.getName();
		String password = authentication.getCredentials().toString();

		if (name.equals("admin") && password.equals("password")) {
			final List<GrantedAuthority> grantedAuths = new ArrayList<>();
			grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
			final UserDetails principal = new User(name, password, grantedAuths);
			final Authentication auth = new UsernamePasswordAuthenticationToken(principal, password, grantedAuths);
			return auth;
		} else {
			return null;
		}

	}

	@Override
	public boolean supports(Class<?> authentication) {

		return authentication.equals(UsernamePasswordAuthenticationToken.class);
	}

}

Code Explanation

In above code we have retrieved Username and password from the Authentication object . Once We retrieve the Authentication Object and Credentials , we are validating the username and password .

You can perform database based authentication , we have done a hard coded validation here .

Once user is valid we try and set GRANTED_AUTHORITY in list of String and return an UserDetails Object to the Caller an Authentication object . Instead of spring provided UserDetails , we can customize the User object set in principal and return .

FilterChainProxy and DelegatingFilterProxy Uses

Filter Chain Proxy and Delegating Filter Proxy

FilterChainProxy and DelegatingFilterProxy  is a good topic to know . We will discuss this topic as most of you were asking me earlier lot of times. In Order to understand FilterChainProxy and DeligatingFilterproxy one must understand the servlet filters first .

DelegatingFilterProxy :-

When a request reaches the server ,it is intercepted by SpringSecurityFilterChain(ex: DelegatingFilterProxy) , then it delegates the request to Spring security framework where the security tasks defined will be handled by security filters defined in application context.

Note:( DeligatingFilterProxy provides the link between application context and web.xml. What DelegatingFilterProxy does Here ?  It is just delegating the request  to a Spring-managed bean that implements the Servlet Filter interface , that is the reason probably the name is DeligatingFilterProxy .

This enables the bean to get benefit from the Spring web application context lifecycle support and configuration flexibility. The bean must  have the same name as that in the filter-name element as below.

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

SpringSecurityFilterChain and FilterChainProxy :-

Now Once a Servlet request reaches the Filter , DelegatingFilterProxy gets initialized , as a part of its Initialization it looks for the filter name , in above example the filter name is springSecurityFilterChain .

This  is basically a Spring Bean , Now If you see there are no bean with name springSecurityFilterChain is present in Spring Context . So what is this springSecurityFilterChain represents . So SpringSecurityFilterChain is an alias for bean FilterChainProxy . It returns a FilterChainProxy object actually .

if You want to know how this Proxy gets called and initialized , please go through the stackoverflow link present here which explains SpringSecurityFilterChain  and FilterChainProxy in detail.

FilterChainProxy: –

FilterChainProxy lets us add a single entry to web.xml and deal entirely with the application context file for managing our web security beans. It is wired using a DelegatingFilterProxy, just like in the example above, but with the filter-name set to the bean name “filterChainProxy”.

At runtime the FilterChainProxy will locate the first URI pattern that matches the current web request and the list of filter beans specified by the filters attribute will be applied to that request. The filters will be invoked in the order they are defined, so you have complete control over the filter chain which is applied to a particular URL.

FilterChainProxy will always delegate init(FilterConfig) and destroy() methods through to the underlaying Filters if such methods are called against FilterChainProxy itself. In this case, FilterChainProxy guarantees to only initialize and destroy each Filter bean once, no matter how many times it is declared in the filter chain(s).

After that this filter will invoke to the next possible set of filter chains in the order. filterChainProxy consists of an ordered list of security filters that are defined in the spring application context which is alias of springSecurityFilterChain bean.

By default when we add ‹http› element  SecurityContextPersistenceFilter,ExceptionTranslationFilter and FilterSecurityInterceptor will be added, And as we have set auto-config to true, BasicAuthenticationFilter, LogoutFilter and UsernamePasswordAuthenticationFilter also gets added to the filter chain.Filter chain keeps skipping until the right filter is reached.

There are Different Filters that Works behind the Scene , once different modes of authentications are uses. Please have a look at the diagram below .

Spring SecurityFiltersAndUses

This is a basic Comparison of FilterChainProxy and DelegatingFilterProxy.

Written by – Subrat Padhi.

Demystifying How Authentication Works In Spring Security

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 .