Secure Web Application With Open ID Connect

Tharindu Piyumal
10 min readNov 25, 2023

--

AI ( DALL-E 3 ) view of OIDC

Introduction:

In today’s fast-paced digital world, I created the Service Reservation application to simplify the process of booking vehicle services. My motivation behind this project was to demonstrate the secure usage of IDP (identity provider) , OIDC (OpenID Connect) authentication, focusing on the crucial aspect of web application security.

For the back-end, I chose Spring Boot, a powerful and flexible framework, combined with MySQL for reliable database management. On the front-end, I utilized JSP design an intuitive user interface, ensuring a seamless experience for users. To enhance security, I integrated Asgardeo as the Identity Provider (IDP), harnessing its robust OIDC authentication capabilities.

This application isn’t just about making reservations; it’s a testament to the harmonious blend of user convenience and digital security, ensuring a hassle-free and safe service booking experience for all users.

Project Overview:

In this Service Reservation application, users can effortlessly navigate a variety of features designed for ultimate convenience. First and foremost, the application offers a robust OIDC login system, ensuring secure and authenticated access for every user. Once logged in, users can seamlessly make reservations for vehicle services. The application allows users to not only view their upcoming reservations but also delete them if plans change. Additionally, users can access their profile information, creating a comprehensive and user-friendly experience.

Technologies Used:

For the backend architecture, I leveraged the power of Spring Boot, a cutting-edge Java-based framework known for its simplicity and efficiency. MySQL, a reliable and scalable relational database, serves as the backend’s data management system, ensuring the safe storage and retrieval of user data.

On the fontend, I utilized a combination of technologies to deliver a visually appealing and responsive user interface. JavaServer Pages (JSP) provide dynamic content generation, while JavaScript enhances interactivity and user experience. Bootstrap, a popular CSS framework, was employed to craft a modern and mobile-friendly design.

To streamline the development process, I used Apache Maven as the project management tool, facilitating smooth dependency management and build processes. The application is packaged as a Web Application Archive (WAR), enhancing portability and deployment flexibility. Asgardeo OIDC authentication was integrated, enhancing the application’s security by implementing robust authentication protocols.

Main Dependencies / Libraries / Frameworks and it’s versions

  • Spring Boot 2.5
  • Java 1.8

I have used some dependencies for this project, here is used dependencies in my pom.xml

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>

<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>

<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>4.6.0</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>


<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>

Development Process:

The journey of crafting this Service Reservation application was marked by various challenges and innovative solutions, ultimately leading to a robust and user-friendly platform. Initially, I started the project using JavaServer Pages (JSP). However, as the project evolved, I recognized the need for enhanced security features, prompting a transition to Spring Boot. This transition not only bolstered the application’s security but also streamlined the overall development process, providing a strong foundation for future enhancements.

In the realm of Identity Providers (IDPs), I opted for Asgardeo due to its user-friendly configuration and seamless integration capabilities. While the primary choice was Asgardeo, I also explored Okta as an alternative solution. I documented this exploration in a dedicated Okta branch within my GitHub repository, providing valuable insights for developers interested in Okta integration. It’s essential to note that this branch might be slightly behind in commits and could contain a few bugs in unrelated codes. Still, it serves as a valuable resource for understanding Okta configuration.

During development, I encountered interesting challenges related to input validation. Exploring various input scenarios revealed potential vulnerabilities, particularly regarding invalid data types being saved in the database. To address this, I implemented rigorous input validation techniques, ensuring that only valid and appropriate data types are stored, thus enhancing the overall data integrity and security of the application.

Throughout this process, I gained valuable lessons, particularly in the importance of thorough testing and validation. Testing different input types not only exposed potential issues but also provided invaluable insights into enhancing the application’s resilience against invalid data. These lessons underscored the critical role of meticulous testing in creating a robust and dependable software solution.

In essence, the development process was marked by continuous learning, problem-solving, and a commitment to delivering a secure and efficient Service Reservation application. By overcoming challenges and embracing innovative solutions, the final product stands as a testament to the dedication and expertise invested in its creation.

Security and Authentication:

In this application, I mostly focused on security and Authentication. For authentication, I used the cloud-based IDP (Identity Provider) and OIDC (OpenID Connect) protocol. I tried Both Asgardeo and Okta. For me, Asgardeo is more user-friendly for developers. so, I continued with Asgardeo. however, Okta added the Service Reservation application you can find here.( https://github.com/PiyumalT/ServiceReservation/tree/Okta--OIDC) (Warning: That branch is a few commits behind) , there very small difference between that two and you can easily migrate between them.
Also, spring-boot and its dependencies provide very interesting features for improving security in the application. so, this application requires an authentication token for creating, viewing, and deleting bookings. Also, in the user profile area, information showed using an authentication token, and those details came from IDP. (such as email, name, phone number, country).
I have used a config file for security. So, it can modify security and i allowed users to view Icon images, logos, and Login pages without login. (paths: “/” , “/resources/img/**”) even though I allowed those paths, I only allowed get requests (without login). If you want to allow other URLs without access without authentication, you can add them to that array. i have used spring-boot-starter-oauth2-client , spring-boot-starter-security dependencies for this process.

@Configuration
@EnableWebSecurity
public class ConfigSecurity extends WebSecurityConfigurerAdapter {

@Value("${client.post-logout-uri}")
private String postLogoutUri;
protected void configure(HttpSecurity http) throws Exception {

http.authorizeRequests()
.antMatchers(HttpMethod.GET,"/","/resources/img/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.oauth2Login()
.and()
.logout().logoutUrl("/logout")
.logoutSuccessHandler(oidcLogoutSuccessHandler());
}

Since my goal is avoid OWASP Top 10 vulnerabilities, I took other several actions to avoid unauthorized actions.

Application Home (& app features)

Add Reservation:
In the HTML form (in JSP), I implemented thorough validation protocols encompassing data types, maximum and minimum lengths, and other criteria. Additionally, JavaScript validation was incorporated, preventing users from inputting past dates. Successful completion of both HTML and JavaScript validations triggers data transmission to the back-end. For further security, the back-end conducts a secondary examination of input types, lengths, and validity. For instance, it verifies whether the provided location and time match the predefined lists specified in the application.properties file. Comprehensive validations are enforced on all inputs. If all validations pass, a new reservation is added, and the user is informed of the status. Any attempts to bypass front-end security and perform unauthorized actions are logged in the back-end, associating the activity with the user’s username.

As part of our commitment to ensuring the security of our application, we’ve implemented robust input sanitization measures, particularly focused on preventing malicious code injection. Users, intentionally or not, may attempt to insert harmful scripts or code into input fields. To thwart such attempts, we’ve developed a dedicated class called TextSanitizer. This class plays a pivotal role in sanitizing input data, ensuring that any potential malicious code is neutralized before being stored in the database. Not only does TextSanitizer safeguard against code injection during data storage, but it also ensures that any retrieved data is free from harmful scripts when presented to users. This two-fold approach significantly enhances the overall security posture of our service, providing a robust defense against potential security threats associated with user input.

View Reservations/Upcoming Reservations:
The functionalities of viewing all reservations and upcoming reservations differ slightly. Upcoming reservations allow users to cancel their bookings, while the view reservation functionality permits cancellations only for bookings with future dates. Therefore, before displaying reservation details, the system filters bookings based on the authenticated username and sanitizing malicious characters.

View Reservation Full Details:
Reservation IDs are provided in the address bar as path variables to prevent unauthorized access to booking data. When the back-end receives a view request, it checks whether the booking ID belongs to the requesting user. If there’s a match, the user is allowed to view the information.

Delete Reservation:
On the front-end, the delete option is presented only for reservations with future dates and those associated with the logged-in user. However, to counter potential malicious actions, the back-end validates the request by ensuring it pertains to a reservation with a future date and belongs to the logged-in user. Only then is the deletion allowed. After deletion, the reservation becomes inaccessible to anyone.

View Profile:
Profile data is retrieved from the Identity Provider (IDP) using authentication tokens. This functionality relies on the authenticity of the token, and there are no delete or update methods involved. The system validates the token and displays the corresponding data without compromising security. to make application secure, replace malicious characters from user details also.

Error page:
Furthermore, the application features a custom error page. In the event of errors, such as invalid URLs or internal server issues, users are redirected to this custom error page instead of being presented with the application’s internal error details page. This proactive approach enhances user experience and security by limiting the exposure of sensitive system information. Also, System identify most unauthorized accesses and log them in back-end log..

Configuration

If you wish to run this application on your device, You need OIDC — IDP and mysql database. This guide for setup that things.

IDP : I recommend you to use Asgardeo, since it user friendly. visit console.asgardeo.io and create account or login using 3rd party logins. then you can navigate to applications > Standard-Based Application. Then add name for application and select OAuth2.0 OpenID Connect and click register. Then you can see app related information in the protocol tab window. keep it for later.

Now, Clone / Download service reservation application code in github.

git clone https://github.com/PiyumalT/ServiceReservation.git

Navigate to application.properties:
Open the application.properties file located at ServiceReservation\src\main\resource\.

Add Asgardeo Client ID and Client Secret:
In the application.properties file, find the following lines:
spring.security.oauth2.client.registration.asgardeo.client-id=
spring.security.oauth2.client.registration.asgardeo.client-secret=
Obtain your Client ID and Client Secret from the Asgardeo admin panel and replace the empty values in the properties file with the obtained credentials.

Set Issuer URL:
In the Asgardeo admin panel, go to the Info tab and copy the Issuer URL. Paste it at the end of the following line in application.properties:
spring.security.oauth2.client.provider.asgardeo.issuer-uri=

Configure Authorized Redirect URLs:
In the Asgardeo admin panel, navigate to your application’s Protocol tab. Locate the Authorized Redirect URLs textbox. Depending on your development environment:

  1. If you’re using IntelliJ or a similar IDE, add these URLs:
    http://localhost:8080/
    http://localhost:8080/login/oauth2/code/asgardeo
  2. If you’re using Tomcat or another server application, add URLs in this format (add correct application running address):
    http://localhost:8080/service-reservation/
    http://localhost:8080/service-reservation/login/oauth2/code/asgardeo

Ensure that you have the correct URL pattern; the default opening URL (index address) and address+/login/oauth2/code/asgardeo need to be added. Failure to configure these correctly might result in an error stating “Redirect URL not allowed.”

Configure Allowed Origins:
Add the following allowed origins in the Asgardeo admin panel: (application running address and port)
http://localhost:8080

Next , we need to set User attributes, there are some already selected. you need to add phone, country(in address) attributes and update.(refer below image) if you want , you and select other filed also, if you do it , make sure to modify scope in application.properties according to it.

Now, you Can add person to application. for that navigate to User management> Add user.

Now, you are completed setup asgardeo. Now, setup SQL database, go to application.properties and database info in below lines. data-source url format is like this..

spring.datasource.url = jdbc:mysql://{hostname}:{port}/{database_name}

spring.datasource.url =
spring.datasource.username =
spring.datasource.password =

You can use https://www.freesqldatabase.com/ for create online MySQL database easily.

After this config, you can run your application using user IDE or server.

Run Application On Tomcat server.

  1. Download the WAR file from the repository. (https://raw.githubusercontent.com/PiyumalT/ServiceReservation/master/service-reservation.war)
  2. Copy the WAR file to your Tomcat’s webapps directory. {path to your tomcat}/ webapps/
  3. Start your Tomcat server. You can go to following path and use the following command:

{path to tomcat} > bin

catalina.bat run

(You need to config application.properties file, After the first run of application, go to webapp>service-reservation>WEB-INF>classes and follow the above config instructions to modify application.properties file. Then restart the application. (To stop tomcat server use ctrl+c and enter catalina.bat run command again)

4. Access the application in your web browser using the following URL:

http://localhost:8080/service-reservation

Finally,

Hope you successfully understand , run my application. If you have any confusions let me know tpc@eay.jp. Also, if you found any vulnerability I would love to hear you. So, please let me know using above email.

--

--

No responses yet