Skip to content

Commit 10c1ad3

Browse files
author
Ivan Franchin
committed
project update
- upgrade to spring-boot 2.6.6; - small code refactor. - update README.
1 parent 2adc08a commit 10c1ad3

File tree

7 files changed

+47
-38
lines changed

7 files changed

+47
-38
lines changed

README.md

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ The goal of this project is to implement an application where a user can manage
1414

1515
- ### jobs-api
1616

17-
[`Spring Boot`](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/) Web Java application that exposes a REST API for managing jobs. It has some endpoints that are secured. `jobs-api` uses `Okta` to handle authentication and authorization.
17+
[`Spring Boot`](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/) Web Java application that exposes a REST API for managing jobs. It has some endpoints that are secured. `Okta` is used to handle authentication and authorization.
1818

19-
The table below shows the endpoins, each one are secured or not and the authorization role required to access the secured ones.
19+
The table below shows the endpoins, whether they are secured or not, and the authorization role required to access the secured ones.
2020

2121
| Endpoint | Secured | Role |
2222
| ----------------------- | ------- | --------------------------- |
2323
| `GET /actuator/*` | No | |
24-
| `POST /authenticate` | No | |
24+
| `POST /callback/token` | No | |
2525
| `GET /api/jobs/newest` | No | |
2626
| `POST /api/jobs` | Yes | `JOBS_STAFF` |
2727
| `PUT /api/jobs/{id}` | Yes | `JOBS_STAFF` |
@@ -67,12 +67,12 @@ The picture below is how `Okta Admin Dashboard` looks like
6767
- General Settings
6868
- App integration name: `Jobs Portal SPA`
6969
- Grant type: check `Authorization Code` and `Implicit (hybrid)`
70-
- Sign-in redirect URIs: `http://localhost:3000/implicit/callback` and `http://localhost:8080/authenticate`
70+
- Sign-in redirect URIs: `http://localhost:3000/implicit/callback` and `http://localhost:8080/callback/token`
7171
- Sign-out redirect URIs: `http://localhost:3000`
7272
- Assignments
7373
- Controlled access: `Skip group assignment for now`
7474
- Click `Save` button
75-
- On the next screen, it's shown the 2 important values we will need to configure and run the `Jobs Portal SPA`: `Client ID` and `Okta Domain`
75+
- On the next screen, the `Client ID` and `Okta Domain` of `Jobs Portal SPA` are displayed.
7676

7777
### Create groups
7878

@@ -93,8 +93,8 @@ The picture below is how `Okta Admin Dashboard` looks like
9393
- Enter the following information for the Staff person
9494
- First name: `Mario`
9595
- Last name: `Bros`
96-
- Username: `mario.bros@jobs.com`
97-
- Primary email: `mario.bros@jobs.com`
96+
- Username: `mario.bros@test.com`
97+
- Primary email: `mario.bros@test.com`
9898
- Groups: `JOBS_STAFF` (the group will popup; select it to add it)
9999
- Password: `Set by admin`
100100
- Set a strong password in the text-field that will appear
@@ -103,8 +103,8 @@ The picture below is how `Okta Admin Dashboard` looks like
103103
- Enter the following information for the Customer person
104104
- First name: `Luigi`
105105
- Last name: `Bros`
106-
- Username: `luigi.bros@jobs.com`
107-
- Primary email: `luigi.bros@jobs.com`
106+
- Username: `luigi.bros@test.com`
107+
- Primary email: `luigi.bros@test.com`
108108
- Groups: `JOBS_CUSTOMER` (the group will popup; select it to add it)
109109
- Password: `Set by admin`
110110
- Set a strong password in the text-field that will appear
@@ -159,7 +159,7 @@ The picture below is how `Okta Admin Dashboard` looks like
159159

160160
- In a terminal, navigate to `okta-springboot-react/jobs-api` folder
161161

162-
- Export the following environment variables. Those values were obtained while (adding Application)[#add-application]
162+
- Export the following environment variables. Those values were obtained while [adding Application](#add-application)
163163
```
164164
export OKTA_CLIENT_ID=...
165165
export OKTA_DOMAIN=...
@@ -174,7 +174,7 @@ The picture below is how `Okta Admin Dashboard` looks like
174174
175175
- Open a new terminal and navigate to `okta-springboot-react/jobs-ui` folder
176176
177-
- Create a file called `.env.local` with the following content. Those values were obtained while (adding Application)[#add-application]
177+
- Create a file called `.env.local` with the following content. Those values were obtained while [adding Application](#add-application)
178178
```
179179
REACT_APP_OKTA_CLIENT_ID=<OKTA_CLIENT_ID>
180180
REACT_APP_OKTA_ORG_URL=https://<OKTA_DOMAIN>
@@ -208,23 +208,23 @@ The picture below is how `Okta Admin Dashboard` looks like
208208
209209
- Done!
210210
211-
> **Note:** If you are using the person `luigi.bros@jobs.com`, you will not be able to create/update/delete a job because it doesn't have the required role for it.
211+
> **Note:** If you are using the person `luigi.bros@test.com`, you will not be able to create/update/delete a job because it doesn't have the required role for it.
212212
213213
## Getting Access Token
214214
215-
In order to use just the `jobs-api` endpoints, you must have an access token. Below are the steps to get it.
215+
In order to use just the `jobs-api` endpoints, you must have an `JWT` access token. Below are the steps to get it.
216216
217-
- In a terminal, create the following environment variables. Those values were obtained while (adding Application)[#add-application]
217+
- In a terminal, create the following environment variables. Those values were obtained while [adding Application][#add-application]
218218
```
219219
OKTA_CLIENT_ID=...
220220
OKTA_DOMAIN=...
221221
```
222222
223223
- Get Okta Access Token Url
224224
```
225-
export OKTA_ACCESS_TOKEN_URL="https://${OKTA_DOMAIN}/oauth2/default/v1/authorize?\
225+
OKTA_ACCESS_TOKEN_URL="https://${OKTA_DOMAIN}/oauth2/default/v1/authorize?\
226226
client_id=${OKTA_CLIENT_ID}\
227-
&redirect_uri=http://localhost:8080/authenticate\
227+
&redirect_uri=http://localhost:8080/callback/token\
228228
&scope=openid\
229229
&response_type=token\
230230
&response_mode=form_post\
@@ -234,15 +234,25 @@ In order to use just the `jobs-api` endpoints, you must have an access token. Be
234234
echo $OKTA_ACCESS_TOKEN_URL
235235
```
236236
237-
- Copy the Okta Access Token Url from the previous step and past it in a browser
237+
- Copy the Okta Access Token Url from the previous step and paste it in a browser
238238
239239
- The Okta login page will appear. Enter the username & password of the person added at the step [`Configuring Okta > Add people`](#add-people) and click `Sign In` button
240240
241-
- It will redirect to `authenticate` endpoint of `jobs-api` and the `Access token` will be displayed.
241+
- It will redirect to `/callback/token` endpoint of `jobs-api` and the `Access token` will be displayed, together with other information
242+
```
243+
{
244+
"state": "state",
245+
"access_token": "eyJraWQiOiJyNFdY...",
246+
"token_type": "Bearer",
247+
"expires_in": "3600",
248+
"scope": "openid"
249+
}
250+
```
251+
> **Tip:** In [jwt.io](https://jwt.io), you can decode and verify the `JWT` access token
242252
243253
## Calling jobs-api endpoints using curl
244254
245-
- **`GET api/jobs/newest`**
255+
- **`GET /api/jobs/newest`**
246256
247257
The `api/jobs/newest` endpoint is public, so we can access it without any problem.
248258
```
@@ -254,7 +264,7 @@ In order to use just the `jobs-api` endpoints, you must have an access token. Be
254264
[{"id":"uuulE2sBTYouQKNL1uoV", ...},{"id":"u-ulE2sBTYouQKNL1-qb", ...}]
255265
```
256266
257-
- **`GET api/jobs` without Access Token**
267+
- **`GET /api/jobs` without Access Token**
258268
259269
Try to get the list of jobs without informing the access token.
260270
```
@@ -265,7 +275,7 @@ In order to use just the `jobs-api` endpoints, you must have an access token. Be
265275
HTTP/1.1 401
266276
```
267277
268-
- **`GET api/jobs` with Access Token**
278+
- **`GET /api/jobs` with Access Token**
269279
270280
First, get the access token as explained in [`Getting Access Token`](#getting-access-token) section. Then, create an environment variable for the access token.
271281
```
@@ -282,7 +292,7 @@ In order to use just the `jobs-api` endpoints, you must have an access token. Be
282292
{"content":[{"id":"uISqEWsBpDcNLtN2kZv3","title":"Expert Java Developer - Cloud","company":"Microsoft","logoUrl"...}
283293
```
284294
285-
> **Note:** If you are using the person `luigi.bros@jobs.com`, you will not be able to create/update/delete a job because it doesn't have the required role for it.
295+
> **Note:** If you are using the person `luigi.bros@test.com`, you will not be able to create/update/delete a job because it doesn't have the required role for it.
286296
287297
## Using jobs-api with Swagger
288298
@@ -294,7 +304,7 @@ In order to use just the `jobs-api` endpoints, you must have an access token. Be
294304
295305
- Done! You can now access the sensitive endpoints.
296306
297-
> **Note:** If you are using the person `luigi.bros@jobs.com`, you will not be able to create/update/delete a job because it doesn't have the required role for it.
307+
> **Note:** If you are using the person `luigi.bros@test.com`, you will not be able to create/update/delete a job because it doesn't have the required role for it.
298308
299309
## Shutdown
300310

jobs-api/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>org.springframework.boot</groupId>
77
<artifactId>spring-boot-starter-parent</artifactId>
8-
<version>2.6.5</version>
8+
<version>2.6.6</version>
99
<relativePath/> <!-- lookup parent from repository -->
1010
</parent>
1111

jobs-api/src/main/java/com/mycompany/jobsapi/config/SwaggerConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public OpenAPI customOpenAPI() {
2626

2727
@Bean
2828
public GroupedOpenApi customApi() {
29-
return GroupedOpenApi.builder().group("api").pathsToMatch("/api/**", "/authenticate").build();
29+
return GroupedOpenApi.builder().group("api").pathsToMatch("/api/**").build();
3030
}
3131

3232
@Bean

jobs-api/src/main/java/com/mycompany/jobsapi/rest/CallbackController.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
@RestController
1212
public class CallbackController {
1313

14-
@Operation(summary = "Endpoint used by Okta to send the access token")
15-
@PostMapping("/authenticate")
16-
public Map<String, String> authenticate(@RequestBody MultiValueMap<String, String> queryMap) {
14+
@Operation(summary = "Endpoint used by Okta to send back the JWT access token")
15+
@PostMapping("/callback/token")
16+
public Map<String, String> callbackToken(@RequestBody MultiValueMap<String, String> queryMap) {
1717
return queryMap.toSingleValueMap();
1818
}
1919
}

jobs-api/src/main/java/com/mycompany/jobsapi/config/CorsConfig.java renamed to jobs-api/src/main/java/com/mycompany/jobsapi/security/CorsConfig.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.mycompany.jobsapi.config;
1+
package com.mycompany.jobsapi.security;
22

33
import org.springframework.beans.factory.annotation.Value;
44
import org.springframework.context.annotation.Bean;
@@ -7,7 +7,6 @@
77
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
88
import org.springframework.web.filter.CorsFilter;
99

10-
import java.util.Collections;
1110
import java.util.List;
1211

1312
@Configuration
@@ -17,10 +16,10 @@ public class CorsConfig {
1716
CorsFilter corsFilter(@Value("${app.cors.allowed-origins}") List<String> allowedOrigins) {
1817
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
1918
CorsConfiguration config = new CorsConfiguration();
20-
config.setAllowCredentials(false);
21-
config.setAllowedOrigins(allowedOrigins);
22-
config.setAllowedMethods(Collections.singletonList("*"));
23-
config.setAllowedHeaders(Collections.singletonList("*"));
19+
config.setAllowCredentials(true);
20+
config.setAllowedOriginPatterns(allowedOrigins);
21+
config.addAllowedMethod("*");
22+
config.addAllowedHeader("*");
2423
source.registerCorsConfiguration("/**", config);
2524
return new CorsFilter(source);
2625
}

jobs-api/src/main/java/com/mycompany/jobsapi/security/WebSecurityConfig.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,15 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
1111
@Override
1212
protected void configure(HttpSecurity http) throws Exception {
1313
http.authorizeRequests()
14-
.antMatchers(HttpMethod.POST, "/authenticate").permitAll()
14+
.antMatchers(HttpMethod.POST, "/callback/token").permitAll()
1515
.antMatchers(HttpMethod.GET, "/actuator/**").permitAll()
1616
.antMatchers(HttpMethod.GET, "/api/jobs/newest").permitAll()
1717
.antMatchers(HttpMethod.GET, "/api/jobs", "/api/jobs/**").hasAnyAuthority(JOBS_CUSTOMER, JOBS_STAFF)
1818
.antMatchers(HttpMethod.PUT, "/api/jobs/search").hasAnyAuthority(JOBS_CUSTOMER, JOBS_STAFF)
1919
.antMatchers("/api/jobs", "/api/jobs/**").hasAuthority(JOBS_STAFF)
2020
.antMatchers("/", "/error", "/csrf", "/swagger-ui.html", "/swagger-ui/**", "/v3/api-docs", "/v3/api-docs/**").permitAll()
21-
.anyRequest().authenticated()
22-
.and()
23-
.oauth2ResourceServer().jwt();
21+
.anyRequest().authenticated();
22+
http.oauth2ResourceServer().jwt();
2423
http.cors().and().csrf().disable();
2524
}
2625

jobs-api/src/main/resources/application.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ logging:
3737
level:
3838
org.springframework.data.elasticsearch.core: DEBUG
3939
org.springframework.web.filter.CommonsRequestLoggingFilter: DEBUG
40+
org.springframework.security: DEBUG

0 commit comments

Comments
 (0)