Monday, July 3, 2023

How to enable HTTP Basic Authentication in Spring Security using Java and XML Configuration? Example Tutorial

In the last article, I have shown you how to enable Spring security in Java application and today we'll talk about how to enable Basic HTTP authentication in your Java web application using Spring Security. I'll show you how to do that using both the Java configuration and XML configuration if you are using Spring Security 3.1 or lower version, but before that let's understand what is Http basic authentication and why do you need that? One of the most common ways to authenticate a user in a web application is by using a form login like you provide a login page and the user will enter his username and password for authentication. This works great for human users but sometimes there are situations where you can't use a login form for authentication.

For example, if your application user is non-human or other applications then form login is not appropriate. This is quite common as well for example in the case of RESTful web services clients are not human, instead of some other application running on some other server.

There are many such scenarios where your clients are not human, but other systems like all JMS clients produce and consume messages without user interaction, and the same goes with ESB system integration applications.

If you are dealing with these kinds of scenarios then you need to think about enabling authentication other than the form login.  In those case, it makes sense to use the HTTP Basic authentication for authenticating users of service.

Btw, in order to use Spring Security, you should be familiar with Spring framework, it's not mandatory but unless you understand core concepts like Spring bean, dependency injection, container and how Spring works, it would be very difficult to use Spring security properly.

Hence, if you are not familiar with Spring security, it's better to spend some time learning it,




How HTTP Basic Authentication Works

In case of HTTP basic authentication, instead of using a form, user login credentials are passed on the HTTP request header, precisely "Authorization" request header. This header allows you to send username and password into request headers instead of the request body, as is the case of form login authentication. This is ideal for authenticating REST clients.

When HTTP basic authentication is enabled, the client that is sending the request, for example, a browser or a REST client concatenates the username and the password with a colon between them and then use Base64 encoding to encode the resulting string. This string is then sent into "Authorization" header of the request.

For example, if your REST client is using username "userId" and password "passwd", the client creates the string "userId:passwd" and base 64 encode it before sending it in the Authentication header.

When this request reaches to the server then server extract value of the Authorization header and uses the base64 algorithm to decode the password and authenticate a user.

If a request doesn't have Authentication header than server rejects the request with 401 response and also appends header "WWW-Authenticate: Basic realm" to instruct the client that it needs to send username and password in request header for authentication.

If you use a browser then it readers that response and present a login dialog box to allow you to enter username and password. Btw, this is not the safest way to send login credential as you can see it just base64 encoded.

There are better ways to authenticate users like by using digest authentication and OAuth 2.0 introduced in Spring 5. I'll write more about that later.

How to enable Http Basic Authentication in Spring Security




How to enable Http basic authentication in Spring Security using XML config

If you are using the XML configuration file to enable Spring security in your application or working on Spring security 3.1 or lower version, you can just use the <http-basic /> configuration element to enable Http basic authentication in your Java web application.

If you are using form login then you can replace the <login-form> element in your configuration file applicationContext-security.xml with <http-basic />.

You also need to include Spring security namespace in your configuration file and restart your application to pick this change. 

If you are not familiar with what is a namespace and how it helps you to write a concise configuration file, I suggest you read official Spring documentation on Spring framework, which is based on both Spring Security and Spring Boot.

Here is how a sample Spring security configuration file look like with HTTP basic authentication enabled:


applicationContext-security.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
 
<http pattern="/home" security="none"/>
<http use-expressions="true">
  <intercept-url pattern="/**" access="isAuthenticated()" />
  <http-basic />
</http>
 
 
<authentication-manager>
  <authentication-provider>
    <user-service>
      <user name="userId" password="passwd" authorities="ROLE_USER" />
    </user-service>
   </authentication-provider>
</authentication-manager>
 
</beans:beans>



In this case, the only relevant information is the <http-basic /> tag which enables  HTTP basic authentication for entire application but let me explain the configuration little bit more :

1)The first line says that for /home we don't need any security so anyone can access it.

2)The second line <http> says that we are using Spring expression language and that's why we could have used the isAuthenticated() method for intercepting url. 

3) The <intercept-url pattern="/**" access="isAuthenticated()" /> means all URLs need authentication and they will use HTTP basic authentication mechanisms.

4) The authentication manager is not in focus but here we are using in-memory authentication provider with just one user is configured whose username is "userId" and password is "passwd".

We can also enable the same HTTP basic authentication using Java configuration, let's see that too.




How to enable Http Basic Authentication using Java Configuration in Spring Security

In the case of Java configuration, you can configure security aspects of calling methods as shown below. Enabling HTTP Basic authentication using Java configuration is as simple as calling the httpBasic() method on the HttpSecurity object passed into configure() method.

Here's a typical example of Spring Security configuration to enable HTTP basic authentication code:

@Configuration
@EnableWebSecurity
public class HttpBasicAuthenticationAdapter extends
    WebSecurityConfigurerAdapter {

  @Autowired
  public void configureGlobal(AuthenticationManagerBuilder auth)
      throws Exception {
    auth
    .inMemoryAuthentication()
    .withUser("userId").password("passwd")
    .authorities("ROLE_USER");

  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
    .authorizeRequests()
    .antMatchers("/securityNone").permitAll()
    .anyRequest().authenticated()
    .and()
    .httpBasic()
    .realmName("Your App");

  }

}

You can combine security constraint using joiner methods like and(). If you want to turn off HTTP basic authentication just remove the call to httpBasic() method and you are done.

Btw, HTTP basic authentication is not the safest way to authenticate as you know you can decode password by intercepting traffic and using Base64 algorithm but it works for most common needs like testing.

There are better ways to perform authentication in production or real-world RESTful web service like Digest authentication.  

Anyway, here is a good diagram which explains how HTTP basic authentication works, a good one to remember this concept after reading this article:

How HTTP Basic Authentication Works



That's all about how to enable HTTP basic authentication in Spring Security. You have learned both XML and Java configuration to enable Http basic authentication using Spring security. As I said, if you are developing RESTful Web Services using Spring MVC then you need to understand how to enable HTTP basic authentication by using Java code or XML configuration and how it works.  Even though it's not good for production, it's extremely helpful for testing and QA purpose.


Other Spring Security articles and resources you may like to explore
Thanks for reading this article so far, if you like this article and my explanation about how to enable HTTP Basic Authentication in Spring Security then please share with your friends and colleagues.

P. S. - If you are looking for some free courses to learn Spring framework and Spring Boot, you can also take a look at this list of free Spring MVC and Spring Online courses to kick-start your journey in the powerful world of Spring framework.

No comments :

Post a Comment