How to enable HTTP Basic Authentication in Spring Security using Java and XML Config

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 form login i.e. you provide a login page and 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 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 e.g. all JMS clients produce and consume messages without user interaction and 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.



How HTTP Basic Authentication Works

In case of HTTP basic authentication, instead of using a form, user login credentials are passed on 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 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 enter username and password. Btw, this is not the safest way to send login credential as you can see it just base 64 encoded.

There are better ways to authenticate users e.g. by using digest authentication and OAuth 2.0 introduced in Spring 5. I'll write more about that later but if you are interested, you can check out Spring Security Certification Class by Baeldung to learn more about them.

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 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 Spring in Action 4th Edition by Craig Walls. A great introductory book 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, 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)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. If you are not familiar with Spring expression language, you can first go through Spring Master Class to learn about that.

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 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 e.g.testing.

There are better ways to perform authentication in production or real-world RESTful web service e.g. digest authentication.  I'll write more about that in later posts but If you can't wait then I suggest you go through Spring Security MasterClass and REST with Spring course from Eugen Paraschiv.

He has shared his real-life work experienced in developing RESTful web services using Spring Framework and Spring Security there.

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
Learn Spring Security 4 Basic hands-on
Learn Spring Security 4 Intermediate - Hands-On 
Difference between @RestController and @Controller in Spring MVC?
Difference between @Service, @Component, and @Controller in Spring?
Difference between @RequestParam and @PathVaraible in Spring?
5 Courses to learn Spring Core, Spring MVC, and Spring Boot
3 Online Courses to learn Spring Security better
How to do Role-based Access Control using Spring Security

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.

No comments :

Post a Comment