From d1377efbe2303f3bccd39bd2527c903283bac520 Mon Sep 17 00:00:00 2001 From: joel vega Date: Tue, 10 Nov 2020 17:32:55 -0500 Subject: [PATCH 1/2] made the first two Configs and the Ipml --- shoppingcart/pom.xml | 18 ++++++ .../config/AuthorizationServerConfig.java | 58 +++++++++++++++++++ .../shoppingcart/config/SecurityConfig.java | 31 ++++++++++ .../services/SecurityUserServiceImpl.java | 30 ++++++++++ 4 files changed, 137 insertions(+) create mode 100644 shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/AuthorizationServerConfig.java create mode 100644 shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SecurityConfig.java create mode 100644 shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/SecurityUserServiceImpl.java diff --git a/shoppingcart/pom.xml b/shoppingcart/pom.xml index 1a2d4e3a..46a75631 100644 --- a/shoppingcart/pom.xml +++ b/shoppingcart/pom.xml @@ -76,6 +76,24 @@ 2.9.2 + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.security + spring-security-test + test + + + + org.springframework.security.oauth + spring-security-oauth2 + 2.3.6.RELEASE + + diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/AuthorizationServerConfig.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/AuthorizationServerConfig.java new file mode 100644 index 00000000..fcd82837 --- /dev/null +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/AuthorizationServerConfig.java @@ -0,0 +1,58 @@ +package com.lambdaschool.shoppingcart.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; + +@Configuration +@EnableAuthorizationServer +public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { + + static final String CLIENT_ID = System.getenv("OAUTHCLIENTID"); + static final String CLINET_SECRET = System.getenv("OAUTHCLIENTSECRET"); + static final String GRANT_TYPE_PASSWORD = "password"; + static final String AUTHORIZATION_CODE = "authorization_code"; + + static final String SCOPE_READ = "read"; + static final String SCOPE_WRITE = "write"; + static final String SCOPE_TRUST = "trust"; + + static final int ACCESS_TOKEN_VALIDITY_SECONDS = -1; + + @Autowired + private TokenStore tokenStore; + + @Autowired + private AuthenticationManager authenticationManager; + + @Autowired + private PasswordEncoder encoder; + + @Override + public void configure(ClientDetailsServiceConfigurer configurer) + throws Exception { + configurer.inMemory() + .withClient(CLIENT_ID) + .secret(encoder.encode(CLINET_SECRET)) + .authorizedGrantTypes(GRANT_TYPE_PASSWORD, + AUTHORIZATION_CODE) + .scopes(SCOPE_READ, + SCOPE_WRITE, + SCOPE_TRUST) + .accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS); + } + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) + throws Exception { + endpoints.tokenStore(tokenStore) + .authenticationManager(authenticationManager); + endpoints.pathMapping("/oauth/token", + "/login"); + } +} diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SecurityConfig.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SecurityConfig.java new file mode 100644 index 00000000..359de484 --- /dev/null +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SecurityConfig.java @@ -0,0 +1,31 @@ +package com.lambdaschool.shoppingcart.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.UserDetailsService; + +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + @Bean + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + @Autowired + private UserDetailsService securityUserService; + + @Autowired + public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(securityUserService). passwordEncoder(encoder()); + } +} diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/SecurityUserServiceImpl.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/SecurityUserServiceImpl.java new file mode 100644 index 00000000..3c295d8f --- /dev/null +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/SecurityUserServiceImpl.java @@ -0,0 +1,30 @@ +package com.lambdaschool.shoppingcart.services; + + +import com.lambdaschool.shoppingcart.exceptions.ResourceNotFoundException; +import com.lambdaschool.shoppingcart.models.User; +import com.lambdaschool.shoppingcart.repository.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +@Service(value = "securityUserService") +public class SecurityUserServiceImpl extends UserDetailsService { + @Autowired + UserRepository userRepository; + + @Transactional + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + User user = userRepository.findByUsername(username.toLowerCase()); + + if ( user == null ) { + throw new ResourceNotFoundException("Invalid username or password"); + } + return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), user.getAuthority()); + } +} From 4a8a59f8b55a83a66bb26f24f17cc03903caa45d Mon Sep 17 00:00:00 2001 From: joel vega Date: Tue, 10 Nov 2020 20:01:33 -0500 Subject: [PATCH 2/2] Finished. --- .../config/AuthorizationServerConfig.java | 1 + .../config/ResourceServerConfig.java | 39 +++++++++++++++++++ .../shoppingcart/config/SecurityConfig.java | 16 +++++++- .../controllers/UserController.java | 17 ++++++++ .../shoppingcart/models/User.java | 19 +++++++++ .../services/SecurityUserServiceImpl.java | 2 +- .../shoppingcart/services/UserAuditing.java | 10 +++++ .../services/UserServiceImpl.java | 4 +- 8 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/ResourceServerConfig.java diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/AuthorizationServerConfig.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/AuthorizationServerConfig.java index fcd82837..2aa2e3ae 100644 --- a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/AuthorizationServerConfig.java +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/AuthorizationServerConfig.java @@ -8,6 +8,7 @@ import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; +import org.springframework.security.oauth2.provider.token.TokenStore; @Configuration @EnableAuthorizationServer diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/ResourceServerConfig.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/ResourceServerConfig.java new file mode 100644 index 00000000..42f709e9 --- /dev/null +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/ResourceServerConfig.java @@ -0,0 +1,39 @@ +package com.lambdaschool.shoppingcart.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; +import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; +import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; +import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler; + +@Configuration +@EnableResourceServer +public class ResourceServerConfig extends ResourceServerConfigurerAdapter { + + private static final String RESOURCE_ID = "resource_id"; + + @Override + public void configure(ResourceServerSecurityConfigurer resources) throws Exception { + resources.resourceId(RESOURCE_ID) + .stateless(false); + } + + @Override + public void configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/", "/h2-console/**", "/createnewuser") + .permitAll() + .antMatchers("/roles/**", "/products/**") + .hasAnyRole("ADMIN") + .antMatchers("/logout") + .authenticated() + .and() + .exceptionHandling() + .accessDeniedHandler(new OAuth2AccessDeniedHandler()); + + http.csrf().disable(); + http.headers().frameOptions().disable(); + http.logout().disable(); + } +} diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SecurityConfig.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SecurityConfig.java index 359de484..c353a49d 100644 --- a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SecurityConfig.java +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/config/SecurityConfig.java @@ -9,6 +9,10 @@ import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.oauth2.provider.token.TokenStore; +import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; @Configuration @EnableWebSecurity @@ -26,6 +30,16 @@ public AuthenticationManager authenticationManagerBean() throws Exception { @Autowired public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception { - auth.userDetailsService(securityUserService). passwordEncoder(encoder()); + auth.userDetailsService(securityUserService).passwordEncoder(encoder()); + } + + @Bean + public PasswordEncoder encoder() { + return new BCryptPasswordEncoder(); + } + + @Bean + public TokenStore tokenStore() { + return new InMemoryTokenStore(); } } diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/controllers/UserController.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/controllers/UserController.java index 50737ff4..abbe99fb 100755 --- a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/controllers/UserController.java +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/controllers/UserController.java @@ -6,6 +6,8 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; @@ -70,6 +72,7 @@ public ResponseEntity getUserById( * @return JSON object of the user you seek * @see UserService#findByName(String) UserService.findByName(String) */ + @PreAuthorize(value = "hasAnyRole('ADMIN')") @GetMapping(value = "/user/name/{userName}", produces = "application/json") public ResponseEntity getUserByName( @@ -89,6 +92,7 @@ public ResponseEntity getUserByName( * @return A JSON list of users you seek * @see UserService#findByNameContaining(String) UserService.findByNameContaining(String) */ + @PreAuthorize(value = "hasAnyRole('ADMIN')") @GetMapping(value = "/user/name/like/{userName}", produces = "application/json") public ResponseEntity getUserLikeName( @@ -111,6 +115,7 @@ public ResponseEntity getUserLikeName( * @throws URISyntaxException Exception if something does not work in creating the location header * @see UserService#save(User) UserService.save(User) */ + @PreAuthorize(value = "hasAnyRole('ADMIN')") @PostMapping(value = "/user", consumes = "application/json") public ResponseEntity addNewUser( @@ -148,6 +153,7 @@ public ResponseEntity addNewUser( * @return status of OK * @see UserService#save(User) UserService.save(User) */ + @PreAuthorize(value = "hasAnyRole('ADMIN')") @PutMapping(value = "/user/{userid}", consumes = "application/json") public ResponseEntity updateFullUser( @@ -194,6 +200,7 @@ public ResponseEntity updateUser( * @param id the primary key of the user you wish to delete * @return Status of OK */ + @PreAuthorize(value = "hasAnyRole('ADMIN')") @DeleteMapping(value = "/user/{id}") public ResponseEntity deleteUserById( @PathVariable @@ -202,4 +209,14 @@ public ResponseEntity deleteUserById( userService.delete(id); return new ResponseEntity<>(HttpStatus.OK); } + + @GetMapping(value = "/myinfo", produces = "application/json") + public ResponseEntity getCurrentUserInfo(){ + String uname = SecurityContextHolder.getContext().getAuthentication().getName(); + User user = userService.findByName(uname); + + return new ResponseEntity<>(user, HttpStatus.OK); + } + + } \ No newline at end of file diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/models/User.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/models/User.java index fcc02f61..e0bd9db9 100644 --- a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/models/User.java +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/models/User.java @@ -2,10 +2,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import javax.persistence.*; import javax.validation.constraints.Email; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; /** @@ -170,6 +174,11 @@ public String getPassword() */ public void setPassword(String password) { + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + this.password = passwordEncoder.encode(password); + } + + public void setPasswordNoEncrypt(String password){ this.password = password; } @@ -212,4 +221,14 @@ public void setCarts(Set carts) { this.carts = carts; } + + public List getAuthority(){ + List rtnList = new ArrayList<>(); + + for (UserRoles r : this.roles) { + String myRole = "ROLE_" + r.getRole().getName().toUpperCase(); + rtnList.add(new SimpleGrantedAuthority(myRole)); + } + return rtnList; + } } diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/SecurityUserServiceImpl.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/SecurityUserServiceImpl.java index 3c295d8f..e9bef1c4 100644 --- a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/SecurityUserServiceImpl.java +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/SecurityUserServiceImpl.java @@ -13,7 +13,7 @@ @Transactional @Service(value = "securityUserService") -public class SecurityUserServiceImpl extends UserDetailsService { +public class SecurityUserServiceImpl implements UserDetailsService { @Autowired UserRepository userRepository; diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserAuditing.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserAuditing.java index 725dcee1..3b54b165 100644 --- a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserAuditing.java +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserAuditing.java @@ -1,6 +1,8 @@ package com.lambdaschool.shoppingcart.services; import org.springframework.data.domain.AuditorAware; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import java.util.Optional; @@ -22,7 +24,15 @@ public class UserAuditing public Optional getCurrentAuditor() { String uname; + + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + + if(auth == null) { uname = "SYSTEM"; + } else { + uname = auth.getName(); + } + return Optional.of(uname); } } diff --git a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserServiceImpl.java b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserServiceImpl.java index f88ce29b..80434fb2 100755 --- a/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserServiceImpl.java +++ b/shoppingcart/src/main/java/com/lambdaschool/shoppingcart/services/UserServiceImpl.java @@ -100,7 +100,7 @@ public User save(User user) newUser.setUsername(user.getUsername() .toLowerCase()); - newUser.setPassword(user.getPassword()); + newUser.setPasswordNoEncrypt(user.getPassword()); newUser.setPrimaryemail(user.getPrimaryemail() .toLowerCase()); @@ -140,7 +140,7 @@ public User update( if (user.getPassword() != null) { - currentUser.setPassword(user.getPassword()); + currentUser.setPasswordNoEncrypt(user.getPassword()); } if (user.getPrimaryemail() != null)