Skip to content
This repository has been archived by the owner on Jul 23, 2024. It is now read-only.

Added LDAP security to get the username, updated the endpoints to ret… #167

Merged
merged 1 commit into from
Mar 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions notification-service/.flattened-pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,23 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
</dependency>
<dependency>
<groupId>com.unboundid</groupId>
<artifactId>unboundid-ldapsdk</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
Expand Down Expand Up @@ -116,6 +128,11 @@
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
12 changes: 12 additions & 0 deletions notification-service/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@ The service uses JPA to persist. Postgres is the recommended DB. For the 'dev' p
The UI for this service can be found as a backstage Plugin for a stand-alone Java service (UI + API) in one Jar, check
out implementation-examples/java-services

## Starting the Service

From the root of the 'notification-service' folder, the follow command will start-up the server locally:

```shell

java -jar -Dspring.profiles.active=local -Dserver.port=8081 target/notification-service-1.0.5-SNAPSHOT.jar

```

The service will run against a local h2 database in when running with way.

## FAQ

### We use Slack, is this required?
Expand Down
22 changes: 20 additions & 2 deletions notification-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,24 @@
<!-- START Spring Security Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
</dependency>
<dependency>
<groupId>com.unboundid</groupId>
<artifactId>unboundid-ldapsdk</artifactId>
</dependency>
<!-- END Spring Security Dependencies -->
<!-- START Spring Cloud Dependencies -->
Expand Down Expand Up @@ -111,6 +124,11 @@
<scope>test</scope>
</dependency>
<!-- END Test Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,21 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

/**
* Main entry point into the application
*
* @author Richard Wang (Github: RichardW98)
* @author Annel Ketcha (Github: anludke)
* @author Luke Shannon (Github: lshannon)
*/
@SpringBootApplication
@EnableWebSecurity
@EnableConfigurationProperties
@ConfigurationPropertiesScan("com.redhat.parodos")
public class NotificationServiceApplication {

public static void main(String[] args) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,8 @@
*/
package com.redhat.parodos.notification.controller;

import com.redhat.parodos.notification.enums.Operation;
import com.redhat.parodos.notification.enums.State;
import com.redhat.parodos.notification.dto.NotificationAssemblerDTO;
import com.redhat.parodos.notification.util.SecurityUtil;
import com.redhat.parodos.notification.dto.NotificationRecordResponseDTO;
import com.redhat.parodos.notification.jpa.entity.NotificationRecord;
import com.redhat.parodos.notification.service.NotificationRecordService;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.UUID;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
Expand All @@ -39,6 +32,17 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;

import com.redhat.parodos.notification.dto.NotificationAssemblerDTO;
import com.redhat.parodos.notification.dto.NotificationRecordResponseDTO;
import com.redhat.parodos.notification.enums.Operation;
import com.redhat.parodos.notification.enums.State;
import com.redhat.parodos.notification.jpa.entity.NotificationRecord;
import com.redhat.parodos.notification.service.NotificationRecordService;
import com.redhat.parodos.notification.util.SecurityUtil;

import io.swagger.v3.oas.annotations.tags.Tag;

/**
* Notification record controller
Expand Down Expand Up @@ -77,6 +81,9 @@ public NotificationRecordController(NotificationRecordService notificationRecord
public PagedModel<NotificationRecordResponseDTO> getNotifications(@PageableDefault(size = 100) Pageable pageable,
@RequestParam(value = "state", required = false) State state,
@RequestParam(value = "searchTerm", required = false) String searchTerm) {
if (securityUtil == null || securityUtil.getUsername() == null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "No username associated with this request");
}
Page<NotificationRecord> notificationsRecordPage = this.notificationRecordService
.getNotificationRecords(pageable, securityUtil.getUsername(), state, searchTerm);
return this.notificationRecordPagedResourcesAssembler.toModel(notificationsRecordPage,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2022 Red Hat Developer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.redhat.parodos.notification.security;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;

import lombok.Data;

@ConfigurationProperties(prefix = "spring.ldap.connection")
@ConfigurationPropertiesScan
@Data
public class LdapConnectionProperties {

String userDNPatterns;

String groupSearchBase;

String url;

String managerDN;

String managerPassword;

String passwordAttribute;

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.redhat.parodos.notification.config;
package com.redhat.parodos.notification.security;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

/**
* Local configuration to run the service with no authentication
*
* @author Annel Ketcha (Github: anludke)
*/
@Profile("local")
@Configuration
public class LocalSecurityConfiguration {
public class LocalSecurityConfiguration extends SecurityConfiguration {

@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeHttpRequests(authorize -> authorize.anyRequest().permitAll());
return http.build();
@Override
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
HttpSecurity httpSec = this.setHttpSecurity(http);
httpSec.cors().disable();
httpSec.csrf().disable();
return httpSec.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Copyright (c) 2022 Red Hat Developer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.redhat.parodos.notification.security;

import static org.springframework.security.config.Customizer.withDefaults;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Profile;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.stereotype.Component;

/**
* Security configuration for the application to ensure the main endpoints are locked down
* and an OAuth2 server is enable. The OAuth2 server details can be found in the
* application.yml file
*
* @author Luke Shannon (Github: lshannon)
*
*/

@Component
@Configuration
@Profile("!local")
@DependsOn("org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor")
public class SecurityConfiguration {

@Autowired
private LdapConnectionProperties ldapConnectionProperties;

public HttpSecurity setHttpSecurity(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
http
.authorizeRequests()
.mvcMatchers(HttpMethod.OPTIONS, "/**")
.permitAll()
.mvcMatchers("/api/**")
.fullyAuthenticated()
.and()
.httpBasic(withDefaults())
.headers().frameOptions().disable()
.and()
.formLogin(form -> form.loginProcessingUrl("/login"))
.logout()
.logoutSuccessUrl("/login").permitAll();
// @formatter:on
return http;
}

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
HttpSecurity httpSec = this.setHttpSecurity(http);
return httpSec.build();
}

@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth.ldapAuthentication()
.userDnPatterns(this.ldapConnectionProperties.getUserDNPatterns())
.groupSearchBase(this.ldapConnectionProperties.getGroupSearchBase()).contextSource()
.url(this.ldapConnectionProperties.getUrl())
.managerDn(this.ldapConnectionProperties.getManagerDN())
.managerPassword(this.ldapConnectionProperties.getManagerPassword())
.and()
.passwordCompare()
.passwordEncoder(new BCryptPasswordEncoder())
.passwordAttribute(this.ldapConnectionProperties.getPasswordAttribute());
// @formatter:on
}

}
Loading