From f8b8a5d7bb8e08bb1dd5c259bae7358cfc585f13 Mon Sep 17 00:00:00 2001 From: DOHA Date: Sat, 27 Feb 2016 20:37:56 +0200 Subject: [PATCH] oauth refresh token --- .../spring-security-oauth-ui-password/pom.xml | 8 +- .../baeldung/config/CustomPostZuulFilter.java | 70 +++++++++++++++++ .../baeldung/config/CustomPreZuulFilter.java | 52 +++++++++++++ .../org/baeldung/config/HomeController.java | 20 +++++ .../org/baeldung/config/UiApplication.java | 2 + .../src/main/resources/application.properties | 2 - .../src/main/resources/application.yml | 13 ++++ .../src/main/resources/templates/header.html | 77 +++++++++++-------- .../src/main/resources/templates/login.html | 5 +- spring-zuul/spring-zuul-ui/.project | 10 +-- 10 files changed, 216 insertions(+), 43 deletions(-) create mode 100644 spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/CustomPostZuulFilter.java create mode 100644 spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/CustomPreZuulFilter.java create mode 100644 spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/HomeController.java delete mode 100644 spring-security-oauth/spring-security-oauth-ui-password/src/main/resources/application.properties create mode 100644 spring-security-oauth/spring-security-oauth-ui-password/src/main/resources/application.yml diff --git a/spring-security-oauth/spring-security-oauth-ui-password/pom.xml b/spring-security-oauth/spring-security-oauth-ui-password/pom.xml index 4a42081f78..e8b2aa3d0d 100644 --- a/spring-security-oauth/spring-security-oauth-ui-password/pom.xml +++ b/spring-security-oauth/spring-security-oauth-ui-password/pom.xml @@ -17,11 +17,17 @@ org.springframework.boot spring-boot-starter-web - + org.springframework.boot spring-boot-starter-thymeleaf + + + org.springframework.cloud + spring-cloud-starter-zuul + 1.0.4.RELEASE + diff --git a/spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/CustomPostZuulFilter.java b/spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/CustomPostZuulFilter.java new file mode 100644 index 0000000000..319bd2f783 --- /dev/null +++ b/spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/CustomPostZuulFilter.java @@ -0,0 +1,70 @@ +package org.baeldung.config; + +import java.io.InputStream; + +import javax.servlet.http.Cookie; + +import org.apache.commons.io.IOUtils; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.map.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +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()); + + @Override + public Object run() { + final RequestContext ctx = RequestContext.getCurrentContext(); + logger.info("in zuul filter " + ctx.getRequest().getRequestURI()); + if (ctx.getRequest().getRequestURI().contains("oauth/token")) { + + final ObjectMapper mapper = new ObjectMapper(); + JsonNode json; + try { + final InputStream is = ctx.getResponseDataStream(); + final String responseBody = IOUtils.toString(is, "UTF-8"); + + ctx.setResponseBody(responseBody); + + if (responseBody.contains("refresh_token")) { + json = mapper.readTree(responseBody); + final String refreshToken = json.get("refresh_token").getTextValue(); + final Cookie cookie = new Cookie("refreshToken", refreshToken); + cookie.setHttpOnly(true); + cookie.setPath(ctx.getRequest().getContextPath() + "/refreshToken"); + cookie.setMaxAge(2592000); // 30 days + ctx.getResponse().addCookie(cookie); + + logger.info("refresh token = " + refreshToken); + } + } catch (final Exception e) { + logger.error("Error occured in zuul post filter", e); + } + + } + return null; + } + + @Override + public boolean shouldFilter() { + return true; + } + + @Override + public int filterOrder() { + return 10; + } + + @Override + public String filterType() { + return "post"; + } + +} diff --git a/spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/CustomPreZuulFilter.java b/spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/CustomPreZuulFilter.java new file mode 100644 index 0000000000..e0e38b2030 --- /dev/null +++ b/spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/CustomPreZuulFilter.java @@ -0,0 +1,52 @@ +package org.baeldung.config; + +import java.io.UnsupportedEncodingException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.crypto.codec.Base64; +import org.springframework.stereotype.Component; + +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()); + + @Override + public Object run() { + final RequestContext ctx = RequestContext.getCurrentContext(); + logger.info("in zuul filter " + ctx.getRequest().getRequestURI()); + if (ctx.getRequest().getRequestURI().contains("oauth/token")) { + byte[] encoded; + try { + encoded = Base64.encode("fooClientIdPassword:secret".getBytes("UTF-8")); + ctx.addZuulRequestHeader("Authorization", "Basic " + new String(encoded)); + logger.info("pre filter"); + logger.info(ctx.getRequest().getHeader("Authorization")); + } catch (final UnsupportedEncodingException e) { + logger.error("Error occured in pre filter", e); + } + + } + return null; + } + + @Override + public boolean shouldFilter() { + return true; + } + + @Override + public int filterOrder() { + return 111110; + } + + @Override + public String filterType() { + return "pre"; + } + +} diff --git a/spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/HomeController.java b/spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/HomeController.java new file mode 100644 index 0000000000..a56407a58e --- /dev/null +++ b/spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/HomeController.java @@ -0,0 +1,20 @@ +package org.baeldung.config; + +import javax.servlet.http.HttpServletResponse; + +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseStatus; + +@Controller +public class HomeController { + + @RequestMapping(method = RequestMethod.GET, value = "/refreshToken") + @ResponseStatus(HttpStatus.OK) + public void getRefreshToken(@CookieValue(value = "refreshToken", defaultValue = "") String cookie, HttpServletResponse response) { + response.addHeader("refreshToken", cookie); + } +} diff --git a/spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/UiApplication.java b/spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/UiApplication.java index 8f491516aa..60c92d9eef 100644 --- a/spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/UiApplication.java +++ b/spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/UiApplication.java @@ -3,7 +3,9 @@ package org.baeldung.config; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.web.SpringBootServletInitializer; +import org.springframework.cloud.netflix.zuul.EnableZuulProxy; +@EnableZuulProxy @SpringBootApplication public class UiApplication extends SpringBootServletInitializer { diff --git a/spring-security-oauth/spring-security-oauth-ui-password/src/main/resources/application.properties b/spring-security-oauth/spring-security-oauth-ui-password/src/main/resources/application.properties deleted file mode 100644 index e76a587680..0000000000 --- a/spring-security-oauth/spring-security-oauth-ui-password/src/main/resources/application.properties +++ /dev/null @@ -1,2 +0,0 @@ -server.contextPath=/spring-security-oauth-ui-password -server.port=8081 \ No newline at end of file diff --git a/spring-security-oauth/spring-security-oauth-ui-password/src/main/resources/application.yml b/spring-security-oauth/spring-security-oauth-ui-password/src/main/resources/application.yml new file mode 100644 index 0000000000..9c9e9000e7 --- /dev/null +++ b/spring-security-oauth/spring-security-oauth-ui-password/src/main/resources/application.yml @@ -0,0 +1,13 @@ +server: + port: 8081 +zuul: + routes: + foos: + path: /foos/** + url: http://localhost:8081/spring-security-oauth-resource/foos + bars: + path: /bars/** + url: http://localhost:8081/spring-security-oauth-resource/bars + oauth: + path: /oauth/** + url: http://localhost:8081/spring-security-oauth-server/oauth diff --git a/spring-security-oauth/spring-security-oauth-ui-password/src/main/resources/templates/header.html b/spring-security-oauth/spring-security-oauth-ui-password/src/main/resources/templates/header.html index cafba4eb65..92a771de12 100644 --- a/spring-security-oauth/spring-security-oauth-ui-password/src/main/resources/templates/header.html +++ b/spring-security-oauth/spring-security-oauth-ui-password/src/main/resources/templates/header.html @@ -21,52 +21,63 @@ var app = angular.module('myApp', ["ngResource","ngRoute","ngCookies"]); app.controller('mainCtrl', function($scope,$resource,$http,$httpParamSerializer,$cookies) { - $scope.foo = {id:0 , name:"sample foo"}; - $scope.foos = $resource("http://localhost:8081/spring-security-oauth-resource/foos/:fooId",{fooId:'@id'}); + $scope.foo = {id:0 , name:"sample foo"}; + $scope.foos = $resource("foos/:fooId",{fooId:'@id'}); - $scope.getFoo = function(){ - $scope.foo = $scope.foos.get({fooId:$scope.foo.id}); - } - - $scope.data = {grant_type:"password", username: "", password: "", client_id: "fooClientIdPassword"}; - $scope.encoded = btoa("fooClientIdPassword:secret"); + $scope.getFoo = function(){ + $scope.foo = $scope.foos.get({fooId:$scope.foo.id}); + } + $scope.loginData = {grant_type:"password", username: "", password: "", client_id: "fooClientIdPassword"}; + $scope.refreshData = {grant_type:"refresh_token", refresh_token:""}; + var isLoginPage = window.location.href.indexOf("login") != -1; if(isLoginPage){ - if($cookies.get("access_token")){ + if($cookies.get("access_token")){ window.location.href = "index"; - }else{ - $http.defaults.headers.common.Authorization= 'Basic ' + $scope.encoded; } }else{ - if($cookies.get("access_token")){ - $http.defaults.headers.common.Authorization= 'Bearer ' + $cookies.get("access_token"); - }else{ - window.location.href = "login"; - } - + if($cookies.get("access_token")){ + $http.defaults.headers.common.Authorization= 'Bearer ' + $cookies.get("access_token"); + }else{ + refreshAccessToken(); + } } $scope.login = function() { - var req = { + $scope.obtainAccessToken($scope.loginData); + } + + function refreshAccessToken(){ + $http.get("refreshToken"). + success(function(data, status, headers, config) { + if(headers("refreshToken") && headers("refreshToken").length>0){ + $scope.refreshData.refresh_token = headers("refreshToken"); + $scope.obtainAccessToken($scope.refreshData); + }else{ + window.location.href = "login"; + } + }); + } + + $scope.obtainAccessToken = function(params){ + var req = { method: 'POST', - url: "http://localhost:8081/spring-security-oauth-server/oauth/token", - headers: { - "Authorization": "Basic " + $scope.encoded, - "Content-type": "application/x-www-form-urlencoded; charset=utf-8" - }, - data: $httpParamSerializer($scope.data) + url: "oauth/token", + headers: {"Content-type": "application/x-www-form-urlencoded; charset=utf-8"}, + data: $httpParamSerializer(params) } $http(req).then( - function(data){ - $http.defaults.headers.common.Authorization= 'Bearer ' + data.data.access_token; - $cookies.put("access_token", data.data.access_token); - window.location.href="index"; - },function(){ - console.log("error"); - }); - } - + function(data){ + $http.defaults.headers.common.Authorization= 'Bearer ' + data.data.access_token; + var expireDate = new Date (new Date().getTime() + (1000 * data.data.expires_in)); + $cookies.put("access_token", data.data.access_token, {'expires': expireDate}); + window.location.href="index"; + },function(){ + console.log("error"); + window.location.href = "login"; + }); + } }); /*]]>*/ diff --git a/spring-security-oauth/spring-security-oauth-ui-password/src/main/resources/templates/login.html b/spring-security-oauth/spring-security-oauth-ui-password/src/main/resources/templates/login.html index 4d105cec6c..e1e6e3e6e0 100755 --- a/spring-security-oauth/spring-security-oauth-ui-password/src/main/resources/templates/login.html +++ b/spring-security-oauth/spring-security-oauth-ui-password/src/main/resources/templates/login.html @@ -15,16 +15,17 @@
- +
- +
Login +
diff --git a/spring-zuul/spring-zuul-ui/.project b/spring-zuul/spring-zuul-ui/.project index ec0f2cde81..d87aec6bec 100644 --- a/spring-zuul/spring-zuul-ui/.project +++ b/spring-zuul/spring-zuul-ui/.project @@ -20,11 +20,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.springframework.ide.eclipse.core.springbuilder @@ -35,6 +30,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature