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

Deploy branch #14

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
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
64 changes: 61 additions & 3 deletions shoppingcart/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.8.RELEASE</version>
<version>2.2.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.lambdaschool</groupId>
<artifactId>shoppingcart</artifactId>
<artifactId>oktafoundation</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>shoppingcart</name>
<name>oktafoundation</name>
<description>Demo project for Spring Boot</description>

<properties>
Expand Down Expand Up @@ -42,6 +42,11 @@
<!-- <scope>runtime</scope>-->
</dependency>

<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
Expand Down Expand Up @@ -76,14 +81,67 @@
<version>2.9.2</version>
</dependency>
<!-- Swagger Dependencies End -->

<!-- Security Dependencies Start -->
<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>

<dependency>
<groupId>com.okta.spring</groupId>
<artifactId>okta-spring-boot-starter</artifactId>
<version>1.4.0</version>
</dependency>
<!-- Security Dependencies End -->

<!-- https://mvnrepository.com/artifact/io.rest-assured/spring-mock-mvc -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>spring-mock-mvc</artifactId>
<version>3.3.0</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<finalName>simone-web35deploy</finalName>

<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

<plugin>
<groupId>com.heroku.sdk</groupId>
<artifactId>heroku-maven-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<appName>${project.build.finalName}</appName>
<includeTarget>false</includeTarget>
<includes>
<include>${project.build.directory}/${project.build.finalName}.jar</include>
</includes>
<jdkVersion>${java.version}</jdkVersion>
<processTypes>
<web>java $JAVA_OPTS -Dserver.port=$PORT -jar target/${project.build.finalName}.jar</web>
</processTypes>
</configuration>
</plugin>

</plugins>
</build>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
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;

/**
* This class enables and configures the Authorization Server. The class is also responsible for granting authorization to the client.
* This class is responsible for generating and maintaining the access tokens.
*/
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig
extends AuthorizationServerConfigurerAdapter
{
/**
* Client Id is the user name for the client application. It is read from the environment variable OAUTHCLIENTID
*/
static final String CLIENT_ID = System.getenv("OAUTHCLIENTID");

/**
* Client secret is the password for the client application. It is read from the environment variable OAUTHCLIENTSECRET
*/
static final String CLIENT_SECRET = System.getenv("OAUTHCLIENTSECRET"); // read from environment variable

/**
* We are using username and password to authenticate a user
*/
static final String GRANT_TYPE_PASSWORD = "password";

/**
* We are using the client id and client security combination to authorize the client.
* The client id and security can be base64 encoded into a single API key or code
*/
static final String AUTHORIZATION_CODE = "authorization_code";

/**
* Scopes are meant to limit what a user can do with the application as a whole.
* Here we allow the user to read from the application.
* Currently we are not implementing scope in our applications. We are just setting up the framework to do so.
*/
static final String SCOPE_READ = "read";

/**
* Scopes are meant to limit what a user can do with the application as a whole.
* Here we allow the user to write to the application.
* Currently we are not implementing scope in our applications. We are just setting up the framework to do so.
*/
static final String SCOPE_WRITE = "write";

/**
* Scopes are meant to limit what a user can do with the application as a whole.
* Here we say the user is trusted.
* Currently we are not implementing scope in our applications. We are just setting up the framework to do so.
*/
static final String TRUST = "trust";

/**
* Tells how long in seconds the access code should be kept valid. After this timeout, the user has to sign on again.
* set to -1 if you want the token to be valid forever. 1 * 60 * 60 would give us 1 hour.
*/
static final int ACCESS_TOKEN_VALIDITY_SECONDS = -1;

/**
* The token store is configured in Security Config. However, the authorization server manages it
*/
@Autowired
private TokenStore tokenStore;

/**
* The authentication server authenticates a user to that user user gets assigned an access token that is managed by the authorization server
*/
@Autowired
private AuthenticationManager authenticationManager;

/**
* The authorization server must encrypt the client secret so needs to know what password encoder is in use.
*/
@Autowired
private PasswordEncoder encoder;

/**
* Method to configure the Client Details Service for our application. This is created and managed by Spring.
* We just need to give it our custom configuration.
*
* @param configurer The ClientDetailsServiceConfigurer used in our application. Spring Boot Security created this for us.
* We just use it.
* @throws Exception if the configuration fails
*/
@Override
public void configure(ClientDetailsServiceConfigurer configurer)
throws
Exception
{
configurer.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);
}

/**
* Connects are endpoints to our custom authentication server and token store.
* We can also rename the endpoints for certain oauth functions
*
* @param endpoints The Authorization Server Endpoints Configurer is created and managed by Spring Boot Security.
* We give the configurer some custom configuration and let it work!
* @throws Exception if the configuration fails
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws
Exception
{
endpoints.tokenStore(tokenStore)
.authenticationManager(authenticationManager);
// here instead of our clients requesting authentication at the endpoint /oauth/token, they request it at the endpoint /login
endpoints.pathMapping("/oauth/token",
"/login");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
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;

/**
* Once the client has gained authorization, users need to gain authentication. This class is response for handling that.
* It also configures which roles have access to which endpoints. So controls the users' access!
*/
@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);
}

/**
* This method configures which roles can access which endpoints
*
* @param http Our HttpSecurity object that is maintains by Spring
* @throws Exception in case the configurations fails
*/
@Override
public void configure(HttpSecurity http)
throws
Exception
{
// our antMatchers control which roles of users have access to which endpoints
// we must order our antmatchers from most restrictive to least restrictive.
// So restrict at method level before restricting at endpoint level.
// permitAll = everyone and their brother
// authenticated = any authenticated, signed in, user
// hasAnyRole = must be authenticated and be assigned this role!
http.authorizeRequests()
.antMatchers("/",
"/h2-console/**",
"/swagger-resources/**",
"/swagger-resource/**",
"/swagger-ui.html",
"/v2/api-docs",
"/webjars/**")
.permitAll()
.antMatchers("/users/**",
"/roles/**",
"/products/**")
.hasAnyRole("ADMIN")
.antMatchers("/users/**",
"/oauth/revoke-token",
"/logout")
.authenticated()
.and()
.exceptionHandling()
.accessDeniedHandler(new OAuth2AccessDeniedHandler());

// http.requiresChannel().anyRequest().requiresSecure(); required for https

// disable the creation and use of Cross Site Request Forgery Tokens.
// These tokens require coordination with the front end client that is beyond the scope of this class.
// See https://www.yawintutor.com/how-to-enable-and-disable-csrf/ for more information
http.csrf()
.disable();

// this disables all of the security response headers. This is necessary for access to the H2 Console.
// Normally, Spring Security would include headers such as
// Cache-Control: no-cache, no-store, max-age=0, must-revalidate
// Pragma: no-cache
// Expires: 0
// X-Content-Type-Options: nosniff
// X-Frame-Options: DENY
// X-XSS-Protection: 1; mode=block
http.headers()
.frameOptions()
.disable();

// This application implements its own logout procedure so disable the one built into Spring Security
http.logout()
.disable();
}
}
Loading