×
☰ See All Chapters

Spring Security Introduction

Spring Security is recognized as a robust and highly customizable framework for authentication and access control. In simpler terms, it can be described as a framework that greatly streamlines the implementation of security measures for Spring applications.

Spring Security doesn't provide automatic, foolproof security for your application. It isn't a magical solution that ensures your app is entirely free from vulnerabilities. Instead, developers must actively engage with Spring Security, comprehending how to configure and tailor it to suit the specific requirements of their applications. The process of customization depends on various factors, ranging from the functional requirements of the application to its underlying architecture. In essence, effective implementation of Spring Security requires a nuanced understanding of the intricacies of both the security framework itself and the unique characteristics of the application it is safeguarding.

When users are engaged in discussions or decision-making processes related to software or systems, their primary focus tends to be on functional requirements. These are the features and capabilities that directly contribute to the intended functionality of the system, meeting the user's specific needs or expectations.

While some users may occasionally demonstrate an understanding of performance considerations, which are categorized as nonfunctional requirements, it's relatively uncommon for them to actively prioritize or express significant concern about security aspects. Nonfunctional requirements, such as performance and security, are those that address how the system operates rather than what it does.

Users often overlook or may not give as much attention to security requirements. Security is a critical nonfunctional aspect, encompassing measures to safeguard data, protect against unauthorized access, and ensure the integrity of the system. Despite its importance, users might not always consider security as a top priority, perhaps because it's less tangible than functional aspects or not immediately visible in the day-to-day use of the system. This implies that functional requirements are often more explicit and easily identifiable, while nonfunctional requirements may be subtle and underlying but are crucial for the overall success and reliability of the system.

What is the alternative for Spring Security?

You won't find many alternatives to Spring Security when it comes to securing a Spring application. One option worth considering is Apache Shiro (https://shiro.apache.org). It provides flexibility in configuration and is easy to integrate with both Spring and Spring Boot applications. Apache Shiro can be a viable alternative to the Spring Security approach in certain scenarios.

Different security vulnerabilities in web applications

  1. Broken Authentication: This occurs when authentication mechanisms are improperly implemented, allowing unauthorized users to gain access to privileged accounts. 

  2. Session Fixation: This is a type of attack where an attacker sets a user's session ID to a known value, making it easier for them to hijack the user's session. 

  3. Cross-Site Scripting (XSS): XSS occurs when an application includes untrusted data in a web page, allowing attackers to execute malicious scripts in the context of a user's browser. 

  4. Cross-Site Request Forgery (CSRF): CSRF involves tricking a user's browser into making an unintended and potentially harmful request to another site where the user is authenticated. 

  5. Injections: This refers to the injection of malicious code (e.g., SQL injection, XPath injection, OS command injection, LDAP injection, and the list continues.) into input fields or parameters, leading to unauthorized access or manipulation of data. 

  6. Sensitive Data Exposure: This vulnerability arises when an application inadequately safeguards sensitive information, such as passwords or personal data, potentially exposing it to unauthorized access. For instance, logs might inadvertently disclose versions of dependencies used by the application, enabling attackers to target vulnerabilities in that specific version once identified. Another example involves different error messages generated based on various inputs provided to an endpoint, revealing the context of execution. For instance, distinct error messages for a correct username but incorrect password could make the system more susceptible to a brute force attack. Responses sent to the client should avoid aiding in the identification of potential inputs. While individual pieces of exposed data may seem harmless, aggregating various disclosed pieces could provide the necessary information to adversely impact a system. 

  7. Lack of Method Access Control: Insufficient control over method access (Java methods) can result in unauthorized users invoking specific methods or actions within an application. While a developer may apply authorization rules at the controller layer, the repository lacks awareness of the user and does not restrict the retrieval of data. If a service requests accounts not belonging to the currently authenticated user, the repository will return such accounts. 

  8. Using Dependencies with Known Vulnerabilities: This pertains to the risk of using third-party libraries or components with known security vulnerabilities, which can be exploited by attackers. 

 Overview of OAuth 2

In the digital realm, web applications groove to the beats of front-end technologies like Angular and ReactJS etc., which communicate with the backend through REST endpoints. Not to be outdone, mobile applications for Android and iOS also syncing up with the backend via those slick REST endpoints.

To secure REST endpoints, it is essential to implement authentication and authorization, requiring valid credentials for users. Whether it's the front-end technologies like Angular, ReactJS, Android, or iOS, credentials must be sent with each call. However, it's crucial to note that these credentials are transmitted without encryption. The browser conveys usernames and passwords through Base64 encoding, leaving them exposed in the header of each endpoint call on the network. For user convenience, it's impractical to prompt for credentials in every request or store them on the client side. Recognizing these concerns, OAuth 2 provides an alternative for authentication and authorization, presenting a more robust and secure approach.

Authentication is the process of confirming a user's identity through credentials like passwords. Authorization, on the other hand, determines the specific permissions or access levels granted to an authenticated user, governing their actions within a system. In essence, authentication validates who you are, while authorization dictates what you can do. Authentication is like having an access card to enter an office building, while authorization is the specific access permissions required on the card to enter the production room within the office.

The OAuth 2 framework delineates two distinct entities: the authorization server and the resource server. The authorization server is tasked with granting user authorization and furnishing them with a token, specifying a set of privileges, among other details. With the acquired token and completed authorization, the ability to make or deny a call on a resource is determined by the resource server. The figure below illustrates a comprehensive overview of the standard OAuth 2 authorization flow. Step by step, the following events unfold:

 

  1. User/Client request for a resource in the backend. 

  2. User gets back forbidden error as user has not obtained enough privileges to access resource. 

  3. User request for a authorization token from Authorization server, user has to authenticate himself by posting his username and password or necessary credentials to obtain authorization token. 

  4. Authorization server will send new token if user credentials are valid and authentic. 

  5. The user initiates another request for a resource in the backend, attaching the token obtained from the authorization server either in the request body or in the header. 

  6. Resource server requests the authorization server to check the validity of the token. If the token is valid, the authorization server grants permission to the resource server to respond with the requested resource. 

spring-security-introduction-0
 

A token typically has a fixed, often short, lifetime. When a token expires, the application must acquire a new one. Additionally, the server has the capability to invalidate a token before its scheduled expiration. This flow offers several advantages:

  • The client isn't required to store user credentials; only the access token and, if applicable, the refresh token need to be saved. 

  • User credentials are not exposed by the application, reducing the risk associated with them being transmitted over the network. 

  • If a token is intercepted, it can be invalidated without the need to invalidate the user credentials. 

  • A token can be utilized by a third party to access resources on the user's behalf without impersonating the user. While this introduces a potential vulnerability if the token is stolen, its limited lifespan restricts the window during which such an attack can be effective. 


All Chapters
Author