Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MVP #15

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

MVP #15

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
17 changes: 17 additions & 0 deletions shoppingcart/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,23 @@
<version>2.9.2</version>
</dependency>
<!-- Swagger Dependencies End -->
<!--Start of security dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.6.RELEASE</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
import org.springframework.security.oauth2.provider.token.TokenStore;


@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

static final String CLIENT_ID = System.getenv("OAUTHCLIENTID");
static final String CLIENT_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 TRUST = "trust";

static final int ACCESS_TOKEN_VALIDITY_SECONDS = -1; //doesn't expire


@Autowired
private TokenStore tokenStore;

@Autowired
private AuthenticationManager authenticationManager;

@Autowired
private PasswordEncoder encoder;


@Override
public void configure(ClientDetailsServiceConfigurer client) throws Exception
{
client.inMemory()
.withClient(CLIENT_ID)
.secret(encoder.encode(CLIENT_SECRET))
.authorizedGrantTypes(GRANT_TYPE_PASSWORD, AUTHORIZATION_CODE)
.scopes(SCOPE_READ, SCOPE_WRITE, TRUST)
.accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS);
}

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore)
.authenticationManager(authenticationManager);
endpoints.pathMapping("/oauth/token", "/login");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.lambdaschool.shoppingcart.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
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)
{
resources.resourceId(RESOURCE_ID)
.stateless(false);
}
//
// For the routes /carts/**
// All authenticated users can access /carts/***
// Remove the user/{userid} path variable from all the routes
// Use the authenticated as the user to work with

@Override
public void configure(HttpSecurity http) throws Exception
{
http.authorizeRequests()
.antMatchers("/",
"/h2-console/**",
"/swagger-resources/**",
"/swagger-resource/**",
"/swagger-ui.html",
"/v2/api-docs",
"/webjars/**")
.permitAll()
.antMatchers("/roles/**", "/products/**")
.hasAnyRole("ADMIN")
.antMatchers(HttpMethod.POST, "/users/**", "/oauth/revoke-token", "/logout")
.authenticated()
.and()
.exceptionHandling()
.accessDeniedHandler(new OAuth2AccessDeniedHandler());

http.csrf().disable();

http.headers().frameOptions().disable();

http.logout().disable();


}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
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;
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
@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());
}

@Bean
public TokenStore tokenStore()
{
return new InMemoryTokenStore();
}

@Bean
public PasswordEncoder encoder()
{
return new BCryptPasswordEncoder();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.lambdaschool.shoppingcart.config;

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
* Spring uses filters to manage web traffic. Here we manually add a CORS (Cross-Origin Resource Sharing) filter to the chain.
* Using the Order annotation, we tell Spring this is the most important filter. If this filter blocks a request,
* don't do anything else. Just block the request.
*/
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCorsFilter
implements Filter
{
@Override
public void doFilter(
ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain)
throws
IOException,
ServletException
{
// Convert our request and response to Http ones. If they are not Http ones, an exception would be thrown
// that would handled by our exception handler!
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest) servletRequest;

// white list domains that can access this API. * says let everyone access it. To restrict access use something like
// response.setHeader("Access-Control-Allow-Origin",
// "https://lambdaschool.com/");
response.setHeader("Access-Control-Allow-Origin",
"*");

// white list http methods that can be used with this API. * says lets them all work! To restrict access use something like
// response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Allow-Methods",
"*");

// while list access headers that can be used with this API. * says lets them all work! To restrict access use something like
// response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, content-type, access_token");
response.setHeader("Access-Control-Allow-Headers",
"*");

// maximum seconds results can be cached
response.setHeader("Access-Control-Max-Age",
"3600");

if (HttpMethod.OPTIONS.name()
.equalsIgnoreCase(request.getMethod()))
{
response.setStatus(HttpServletResponse.SC_OK);
} else
{
filterChain.doFilter(servletRequest,
servletResponse);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

@RestController
Expand All @@ -25,34 +26,38 @@ public ResponseEntity<?> listCartItemsByUserId(
@PathVariable
long userid)
{
User u = userService.findUserById(userid);
User u = userService.findByName(SecurityContextHolder.getContext()
.getAuthentication()
.getName());
return new ResponseEntity<>(u,
HttpStatus.OK);
}

@PutMapping(value = "/add/user/{userid}/product/{productid}",
produces = {"application/json"})
public ResponseEntity<?> addToCart(
@PathVariable
long userid,
@PathVariable
long productid)
{
// pulls current user through context and sets as long userId (security)
long userid = userService.findByName(SecurityContextHolder.getContext()
.getAuthentication().getName()).getUserid();

CartItem addCartTtem = cartItemService.addToCart(userid,
productid,
"I am not working");
return new ResponseEntity<>(addCartTtem,
HttpStatus.OK);
}

@DeleteMapping(value = "/remove/user/{userid}/product/{productid}",
@DeleteMapping(value = "/remove/user/{userid}/product/{procductid}",
produces = {"application/json"})
public ResponseEntity<?> removeFromCart(
@PathVariable
long userid,
@PathVariable
long productid)
{
long userid = userService.findByName(SecurityContextHolder.getContext()
.getAuthentication().getName()).getUserid();
CartItem removeCartItem = cartItemService.removeFromCart(userid,
productid,
"I am still not working");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.lambdaschool.shoppingcart.controllers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.http.HttpServletRequest;

@Controller
public class LogoutController
{
@Autowired
private TokenStore tokenStore;

@GetMapping(value = {"/oauth/revoke-token", "/logout"}, produces = "application/json")
public ResponseEntity<?> logoutSelf(HttpServletRequest request)
{
String authHeader = request.getHeader("Authorization");
if(authHeader != null)
{
String tokenValue = authHeader.replace("Bearer", "").trim();
OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
tokenStore.removeAccessToken(accessToken);
}

return new ResponseEntity<>(HttpStatus.OK);
}

}
Loading