1. Overview

In this article, we will explain Spring security custom authentication provider example. Spring security provides database authentication, LDAP authentication but sometimes it might not enough based on our requires so spring boot also provides custom authentication using interfaceAuthenticationProvider.

AuthenticationProvider the interface which contains a authenticatemethod in which we can write our custom code for user authentication. When the user enters username & password spring security will call methodauthenticate where our custom code will be executed. One valid authentication,  Authentication reference will be returned which contains username and ROLE. On Invalid authentication, proper Exception will return be like BadCredentialsException.

2. Example

Spring security custom authentication provider example

Spring security custom authentication provider example

2.1 pom.xml

spring-boot-starter-security dependency must be required in CLASSPATH.

<?xml version="1.0" encoding="UTF-8"?>
<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>spring-boot-example</groupId>
    <artifactId>spring-security-custom-authentication</artifactId>
    <version>1.0-SNAPSHOT</version>
    <description>Spring security custom authentication provider example</description>
    <!-- Inherit defaults from Spring Boot -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
    </parent>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/com.lambdaworks/lettuce -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>                <!-- for tomcat web container-->
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>  <!--starter require for spring boot spring security-->
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>              <!--fot jap compilation need provide scope runtime or provided because it available in tomcat -->
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>runtime</scope>     <!-- in my case provided not working so write runtime-->
        </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>

2.2 application.properties

spring.mvc.view.prefix: /WEB-INF/jsp/
spring.mvc.view.suffix: .jsp

2.3 CustomAuthentication

Here we have written custom code for authentication :

package com.javadeveloperzone;

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

import java.util.Collections;

/**
 * Created by Java Developer Zone on 25-12-2017.
 * This class will check custom Authentication and return Authentication object if username and password is current
 *
 */
public class CustomAuthentication implements AuthenticationProvider {
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String user = authentication.getName();
        String password = authentication.getCredentials().toString();
        if (user.equalsIgnoreCase("user") && password.equals("mypassword")) {           // replace your custom code here for custom authentication
            return new UsernamePasswordAuthenticationToken
                    (user, password, Collections.emptyList());
        } else {
            throw new BadCredentialsException("External system authentication failed");
        }
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return true;
    }
}

2.4 SecurityConfiguration

For example purpose, we have used in-memory user. HttpSecurty‘sauthenticationProvider we have passed a reference of  CustomAuthentication.

package com.javadeveloperzone;

import org.springframework.beans.factory.annotation.Autowired;
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;



/**
 * Created by JavaDeveloperZone on 13-11-2017.
 */
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Autowired      // here is configuration related to spring boot basic authentication
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user").password("mypassword").roles("USER")
            .and()
            .withUser("admin").password("mypassword").roles("ADMIN");// those are user name and password
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests().antMatchers("/loginFailed").permitAll()
            .and()
            .authorizeRequests().antMatchers("/**").authenticated()
            .and()
            .formLogin()
            .loginPage("/login").successForwardUrl("/loginSuccess")
            .permitAll().and().authenticationProvider(new CustomAuthentication());
    }
}


2.5 SpringBootConfig

package com.javadeveloperzone;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

/**
 * Created by JavaDeveloperZone on 19-07-2017.
 */

@SpringBootApplication
@ComponentScan // Using a root package also allows the @ComponentScan annotation to be used without needing to specify a basePackage attribute
public class SpringBootConfig {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(SpringBootConfig.class, args);            // it wil start application
    }
}

2.6 login.jsp

<%--
  Created by IntelliJ IDEA.
  User: Java Developer Zone
  Date: 18-03-2017
  Time: 07:34
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Spring security custom authentication example - Login</title>
</head>
<body>
<h1>spring security custom authentication provider</h1>
<form name='f' action='/login' method='POST'>
    User: <input type='text' name='username' value=''>
    Password: <input type='password' name='password'/>
    <input type="hidden"
           name="${_csrf.parameterName}"
           value="${_csrf.token}"/>
    <input name="submit" type="submit" value="Login"/>
</form>
</body>
</html>

2.7 loginFailed.jsp

<%--
  Created by IntelliJ IDEA.
  User: Java Developer Zone
  Date: 18-03-2017
  Time: 07:34
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Spring security custom authentication provider example - LoginFailed</title>
</head>
<body>
Login Failed
</body>
</html>

2.8 welcome.jsp

<%--
  Created by IntelliJ IDEA.
  User: Java Developer Zone
  Date: 18-03-2017
  Time: 07:34
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Spring security custom authentication provider example - Welcome</title>
</head>
<body>
<h1>User is login using spring boot custom authentication provider</h1></body>
</html>

Output

http://localhost:8080/login

User Login Page

User Login Page

 

After Correct username & Password

User Login Success using custom authentication

User Login Success using custom authentication

3. Conclusion

In this article, we have learned about spring security custom authentication provider where we can write custom code for user authentication, Custom authentication can be used for form-based as well as basic authentication.

4. References

Spring security document

Was this post helpful?
Let us know, if you liked the post. Only in this way, we can improve us.
Yes
No

Leave a Reply

Your email address will not be published. Required fields are marked *