Skip to content

Commit

Permalink
JAVA-900: Update OAuth Refresh Token article
Browse files Browse the repository at this point in the history
  • Loading branch information
sampadawagde committed Apr 12, 2020
1 parent 31d32d4 commit 51ef933
Show file tree
Hide file tree
Showing 30 changed files with 10,466 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,8 @@
"clientAuthenticatorType" : "client-secret",
"secret" : "newClientSecret",
"redirectUris" : [ "http://localhost:8082/new-client/login/oauth2/code/custom",
"http://localhost:8089/" ],
"http://localhost:8089/",
"http://localhost:8080/auth/redirect/"],
"webOrigins" : [ "+" ],
"notBefore" : 0,
"bearerOnly" : false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public FooController(IFooService fooService) {
this.fooService = fooService;
}

@CrossOrigin(origins = "http://localhost:8089")
@CrossOrigin(origins = "*")
@GetMapping(value = "/{id}")
public FooDto findOne(@PathVariable Long id) {
Foo entity = fooService.findById(id)
Expand Down
17 changes: 17 additions & 0 deletions oauth-rest/oauth-ui-authorization-code-angular-zuul/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## Spring Security OAuth - Authorization Code Using Zuul
A simple Angular client for Authorization Code Flow Using Zuul

## Run the Module
To run the application, first make sure both authorization and resource server are already running
Then, build the app using command line:
```
mvn clean install
```

Change directory to src/main/resources:
```
cd src/main/resources
```

Finally, run the UIApplication class and hit the app:
http://localhost:8080/
95 changes: 95 additions & 0 deletions oauth-rest/oauth-ui-authorization-code-angular-zuul/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>oauth-ui-authorization-code-angular-zuul</artifactId>

<name>oauth-ui-authorization-code-angular-zuul</name>
<packaging>war</packaging>

<parent>
<groupId>com.baeldung</groupId>
<artifactId>spring-security-oauth</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>

<dependencies>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
<version>${netflix-zuul.version}</version>
</dependency>

<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>

<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.7.5</version>

<configuration>
<nodeVersion>v10.15.3</nodeVersion>
<npmVersion>6.4.1</npmVersion>
<workingDirectory>src/main/resources</workingDirectory>
</configuration>

<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
</execution>

<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
</execution>

<execution>
<id>npm run build</id>
<goals>
<goal>npm</goal>
</goals>

<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>

<resources>
<resource>
<directory>target/resources</directory>
<targetPath>static</targetPath>
</resource>
</resources>

</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.baeldung.config;

import java.io.IOException;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import com.netflix.zuul.http.ServletInputStreamWrapper;

public class CustomHttpServletRequest extends HttpServletRequestWrapper {

private final byte[] bytes;

public CustomHttpServletRequest(final HttpServletRequest request, byte[] bytes) {
super(request);
this.bytes = bytes;
}

@Override
public ServletInputStream getInputStream() throws IOException {
return new ServletInputStreamWrapper(bytes);
}

@Override
public int getContentLength() {
return bytes.length;
}

@Override
public long getContentLengthLong() {
return bytes.length;
}

@Override
public String getMethod() {
return "POST";
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package com.baeldung.config;

import java.io.InputStream;
import java.util.List;
import java.util.Map;

import javax.servlet.http.Cookie;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

@Component
public class CustomPostZuulFilter extends ZuulFilter {

private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final ObjectMapper mapper = new ObjectMapper();

@Override
public Object run() {
final RequestContext ctx = RequestContext.getCurrentContext();
logger.info("in zuul filter " + ctx.getRequest().getRequestURI());

final String requestURI = ctx.getRequest().getRequestURI();

try {
Map<String, List<String>> params = ctx.getRequestQueryParams();

if (requestURI.contains("auth/redirect")) {
final Cookie cookie = new Cookie("code", params.get("code").get(0));
cookie.setHttpOnly(true);
cookie.setPath(ctx.getRequest().getContextPath() + "/auth/token");
//cookie.setMaxAge(2592000); // 30 days

ctx.getResponse().addCookie(cookie);

} else if (requestURI.contains("auth/token") || requestURI.contains("auth/refresh")) {

final InputStream is = ctx.getResponseDataStream();
String responseBody = IOUtils.toString(is, "UTF-8");
if (responseBody.contains("refresh_token")) {
final Map<String, Object> responseMap = mapper.readValue(responseBody,
new TypeReference<Map<String, Object>>() {
});
final String refreshToken = responseMap.get("refresh_token").toString();
responseMap.remove("refresh_token");
responseBody = mapper.writeValueAsString(responseMap);

final Cookie cookie = new Cookie("refreshToken", refreshToken);
cookie.setHttpOnly(true);
cookie.setPath(ctx.getRequest().getContextPath() + "/auth/refresh");
cookie.setMaxAge(2592000); // 30 days

ctx.getResponse().addCookie(cookie);
}
ctx.setResponseBody(responseBody);
}

} catch (Exception e) {
logger.error("Error occured in zuul post filter", e);
}
return null;
}

@Override
public boolean shouldFilter() {
boolean shouldfilter = false;
final RequestContext ctx = RequestContext.getCurrentContext();
String URI = ctx.getRequest().getRequestURI();

if (URI.contains("auth/redirect") || URI.contains("auth/token") || URI.contains("auth/refresh")) {
shouldfilter = true;
}

return shouldfilter;
}

@Override
public int filterOrder() {
return 10;
}

@Override
public String filterType() {
return "post";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package com.baeldung.config;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

@Component
public class CustomPreZuulFilter extends ZuulFilter {

private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final static String REDIRECT_URL = "http://localhost:8080/auth/redirect/";
private final static String CLIENT_ID = "newClient";
private final static String CLIENT_SECRET = "newClientSecret";

@Override
public Object run() {
final RequestContext ctx = RequestContext.getCurrentContext();
logger.info("in zuul filter URI:" + ctx.getRequest().getRequestURI());

final HttpServletRequest req = ctx.getRequest();
String requestURI = req.getRequestURI();

if (requestURI.contains("auth/code")) {
Map<String, List<String>> params = ctx.getRequestQueryParams();
if (params == null) {
params = Maps.newHashMap();
}
params.put("response_type", Lists.newArrayList(new String[] { "code" }));
params.put("scope", Lists.newArrayList(new String[] { "read" }));
params.put("client_id", Lists.newArrayList(new String[] { CLIENT_ID }));
params.put("redirect_uri", Lists.newArrayList(new String[] { REDIRECT_URL }));

ctx.setRequestQueryParams(params);
} else if (requestURI.contains("auth/token") || requestURI.contains("auth/refresh")) {

try {
String cookieValue = requestURI.contains("token") ? extractCookie(req, "code")
: extractCookie(req, "refreshToken");

String formParams = createFormData(requestURI, cookieValue);

byte[] bytes = formParams.getBytes("UTF-8");

ctx.setRequest(new CustomHttpServletRequest(req, bytes));

} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}

private String extractCookie(HttpServletRequest req, String name) {
final Cookie[] cookies = req.getCookies();
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equalsIgnoreCase(name)) {
return cookies[i].getValue();
}
}
}
return null;
}

private String createFormData(String requestURI, String cookieValue) {
String formData;
if (requestURI.contains("token")) {
formData = String.format("grant_type=%s&client_id=%s&client_secret=%s&redirect_uri=%s&code=%s",
"authorization_code", CLIENT_ID, CLIENT_SECRET, REDIRECT_URL, cookieValue);
} else {
formData = String.format("grant_type=%s&client_id=%s&client_secret=%s&refresh_token=%s", "refresh_token",
CLIENT_ID, CLIENT_SECRET, cookieValue);
}
return formData;
}

@Override
public boolean shouldFilter() {
boolean shouldfilter = false;
final RequestContext ctx = RequestContext.getCurrentContext();
String URI = ctx.getRequest().getRequestURI();

if (URI.contains("auth/code") || URI.contains("auth/token") || URI.contains("auth/refresh")) {
shouldfilter = true;
}

return shouldfilter;
}

@Override
public int filterOrder() {
return 6;
}

@Override
public String filterType() {
return "pre";
}

}
Loading

0 comments on commit 51ef933

Please sign in to comment.