

Table of Contents
1. Overview
In this article, we will see spring security digest authentication example. Spring security provides digest authentication filter using that we can authenticate the user using digest authentication header. Digest authentication header considers of :
base64(expirationTime + ":" + md5Hex(expirationTime + ":" + key)) expirationTime: The date and time when the nonce expires, expressed in milliseconds key: A private key to prevent modification of the nonce token
Why digest authentication?
- It’s more secure than basic authentication. Basic authentication header considers of
base64(user:password)
which means that it’s like plain text anyone can view username and password after decoding base64. - While running application on HTTP (Not secure layer) at that time digest authentication is more preferable.
- Popular browsers like Chome, Mozilla FireFox, and IE etc support digest authentication.
Limitation of digest authentication:
- It is possible to encode the password in the format HEX( MD5(username:realm:password) ) provided the
DigestAuthenticationFilter.passwordAlreadyEncoded
is set totrue
. However, other password encodings will not work with digest authentication. (Ref: https://docs.spring.io/spring-security/site/docs/5.0.0.RELEASE/reference/htmlsingle/#d5e3560)
2. Example

spring security digest authentication example
2.1 pom.xml
Spring security dependency : spring-boot-starter-security
<?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-boot-digest-authentication</artifactId> <version>1.0-SNAPSHOT</version> <description>spring security digest authentication 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> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <!--starter require for spring boot spring security--> <artifactId>spring-boot-starter-security</artifactId> </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 SecurityConfiguration
DigestAuthenticationFilter
is responsible for processing digest available in the request header.DigestAuthenticationFilter
requires entry point andUserDetailsService
consist of User Details like username, password, activation details etc.- For digest authentication,
DigestAuthenticationEntryPoint
require an entry point for authentication. Entry point requires realm and key. /home
is open for all, remaining pages are secure.
package com.javadeveloperzone; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint; import org.springframework.security.web.authentication.www.DigestAuthenticationFilter; /** * Created by JavaDeveloperZone on 04-08-2017. */ @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.addFilter(digestAuthenticationFilter()) // register digest entry point .exceptionHandling().authenticationEntryPoint(digestEntryPoint()) // on exception ask for digest authentication .and() .httpBasic() // it indicate basic authentication is requires .and() .authorizeRequests() .antMatchers( "/home").permitAll() // /home will be accessible directly, no need of any authentication .anyRequest().authenticated(); } DigestAuthenticationFilter digestAuthenticationFilter() throws Exception { DigestAuthenticationFilter digestAuthenticationFilter = new DigestAuthenticationFilter(); digestAuthenticationFilter.setUserDetailsService(userDetailsServiceBean()); digestAuthenticationFilter.setAuthenticationEntryPoint(digestEntryPoint()); return digestAuthenticationFilter; } @Override @Bean public UserDetailsService userDetailsServiceBean() { InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager(); inMemoryUserDetailsManager.createUser(User.withUsername("zone").password("password").roles("USER").build()); return inMemoryUserDetailsManager; } @Bean DigestAuthenticationEntryPoint digestEntryPoint() { DigestAuthenticationEntryPoint bauth = new DigestAuthenticationEntryPoint(); bauth.setRealmName("Digest WF Realm"); bauth.setKey("MySecureKey"); return bauth; } @Bean public AuthenticationManager customAuthenticationManager() throws Exception { return authenticationManager(); } }
2.2 HelloController
RestController
is for rest API.
package com.javadeveloperzone.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * Created by JavaDeveloperZone on 19-07-2017. */ @RestController public class HelloController { @RequestMapping(value = "/secure") public String secure() { return "You are authorize to access this page. This is secure page. "; } @RequestMapping(value = "/home") public String home() { return "This is public page. No need of authentication"; } }
2.3 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 } }
Output:
Let’s try to access secure URL: http://localhost:8080/secure
It will ask for authentication details like username and password.

spring security digest authentication example login
When username and password passed to the server in digest not as simple as basic authentication.

spring security digest authentication example-header information