

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.passwordAlreadyEncodedis 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
DigestAuthenticationFilteris responsible for processing digest available in the request header.DigestAuthenticationFilterrequires entry point andUserDetailsServiceconsist of User Details like username, password, activation details etc.- For digest authentication,
DigestAuthenticationEntryPointrequire an entry point for authentication. Entry point requires realm and key. /homeis 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
RestControlleris 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
