Setting cookies on redirect
First, I will set a cookie value on redirect.
I created two micronaut applications.
When a user access the application1, it redirects to application2 and set a cookie.
[Application1] HomeController.java
<span>package</span> <span>jp.masanori</span><span>;</span><span>import</span> <span>java.util.Optional</span><span>;</span><span>import</span> <span>java.net.URI</span><span>;</span><span>import</span> <span>org.slf4j.Logger</span><span>;</span><span>import</span> <span>org.slf4j.LoggerFactory</span><span>;</span><span>import</span> <span>io.micronaut.http.HttpResponse</span><span>;</span><span>import</span> <span>io.micronaut.http.MutableHttpResponse</span><span>;</span><span>import</span> <span>io.micronaut.http.annotation.Controller</span><span>;</span><span>import</span> <span>io.micronaut.http.annotation.Get</span><span>;</span><span>import</span> <span>io.micronaut.http.cookie.Cookie</span><span>;</span><span>import</span> <span>io.micronaut.http.cookie.Cookies</span><span>;</span><span>import</span> <span>io.micronaut.http.cookie.SameSite</span><span>;</span><span>import</span> <span>io.micronaut.http.HttpRequest</span><span>;</span><span>import</span> <span>io.micronaut.http.annotation.CookieValue</span><span>;</span><span>@Controller</span><span>(</span><span>"/"</span><span>)</span><span>public</span> <span>class</span> <span>HomeController</span> <span>{</span><span>private</span> <span>final</span> <span>Logger</span> <span>logger</span><span>;</span><span>public</span> <span>HomeController</span><span>()</span> <span>{</span><span>this</span><span>.</span><span>logger</span> <span>=</span> <span>LoggerFactory</span><span>.</span><span>getLogger</span><span>(</span><span>HomeController</span><span>.</span><span>class</span><span>);</span><span>}</span><span>@Get</span><span>(</span><span>"/"</span><span>)</span><span>public</span> <span>String</span> <span>index</span><span>(</span><span>@CookieValue</span><span>(</span><span>"SESSION-VALUE"</span><span>)</span> <span>Optional</span><span><</span><span>String</span><span>></span> <span>sessionValue</span><span>,</span><span>HttpRequest</span><span><</span><span>String</span><span>></span> <span>req</span><span>)</span> <span>{</span><span>if</span> <span>(</span><span>sessionValue</span><span>.</span><span>isPresent</span><span>())</span> <span>{</span><span>logger</span><span>.</span><span>debug</span><span>(</span><span>"OK: "</span> <span>+</span> <span>sessionValue</span><span>.</span><span>get</span><span>());</span><span>}</span> <span>else</span> <span>{</span><span>logger</span><span>.</span><span>debug</span><span>(</span><span>"No cookie"</span><span>);</span><span>}</span><span>Cookies</span> <span>c</span> <span>=</span> <span>req</span><span>.</span><span>getCookies</span><span>();</span><span>for</span> <span>(</span><span>var</span> <span>v</span> <span>:</span> <span>c</span><span>.</span><span>getAll</span><span>())</span> <span>{</span><span>logger</span><span>.</span><span>debug</span><span>(</span><span>"--------Cookie---------"</span><span>);</span><span>logger</span><span>.</span><span>debug</span><span>(</span><span>"Name:"</span> <span>+</span> <span>v</span><span>.</span><span>getName</span><span>());</span><span>logger</span><span>.</span><span>debug</span><span>(</span><span>"Value: "</span> <span>+</span> <span>v</span><span>.</span><span>getValue</span><span>());</span><span>logger</span><span>.</span><span>debug</span><span>(</span><span>"Domain:"</span> <span>+</span> <span>v</span><span>.</span><span>getDomain</span><span>());</span><span>logger</span><span>.</span><span>debug</span><span>(</span><span>"Path: "</span> <span>+</span> <span>v</span><span>.</span><span>getPath</span><span>());</span><span>logger</span><span>.</span><span>debug</span><span>(</span><span>"MaxAge: "</span> <span>+</span> <span>v</span><span>.</span><span>getMaxAge</span><span>());</span><span>logger</span><span>.</span><span>debug</span><span>(</span><span>"SameSite: "</span> <span>+</span> <span>v</span><span>.</span><span>getSameSite</span><span>());</span><span>logger</span><span>.</span><span>debug</span><span>(</span><span>"HttpOnly: "</span> <span>+</span> <span>v</span><span>.</span><span>isHttpOnly</span><span>());</span><span>logger</span><span>.</span><span>debug</span><span>(</span><span>"Secure: "</span> <span>+</span> <span>v</span><span>.</span><span>isSecure</span><span>());</span><span>}</span><span>return</span> <span>"Hello World!"</span><span>;</span><span>}</span><span>@Get</span><span>(</span><span>"/redirect"</span><span>)</span><span>public</span> <span>MutableHttpResponse</span><span><</span><span>Object</span><span>></span> <span>redirectToOutTasks</span><span>()</span> <span>{</span><span>URI</span> <span>location</span> <span>=</span> <span>URI</span><span>.</span><span>create</span><span>(</span><span>"http://ourtasks.masanori.jp:8083/ourtasks/pages/cookie"</span><span>);</span><span>Cookie</span> <span>ck</span> <span>=</span> <span>Cookie</span><span>.</span><span>of</span><span>(</span><span>"SESSION-VALUE"</span><span>,</span> <span>"Hello Micronaut!"</span><span>);</span><span>return</span> <span>HttpResponse</span><span>.</span><span>redirect</span><span>(</span><span>location</span><span>)</span><span>.</span><span>cookie</span><span>(</span><span>ck</span><span>);</span><span>}</span><span>}</span><span>package</span> <span>jp.masanori</span><span>;</span> <span>import</span> <span>java.util.Optional</span><span>;</span> <span>import</span> <span>java.net.URI</span><span>;</span> <span>import</span> <span>org.slf4j.Logger</span><span>;</span> <span>import</span> <span>org.slf4j.LoggerFactory</span><span>;</span> <span>import</span> <span>io.micronaut.http.HttpResponse</span><span>;</span> <span>import</span> <span>io.micronaut.http.MutableHttpResponse</span><span>;</span> <span>import</span> <span>io.micronaut.http.annotation.Controller</span><span>;</span> <span>import</span> <span>io.micronaut.http.annotation.Get</span><span>;</span> <span>import</span> <span>io.micronaut.http.cookie.Cookie</span><span>;</span> <span>import</span> <span>io.micronaut.http.cookie.Cookies</span><span>;</span> <span>import</span> <span>io.micronaut.http.cookie.SameSite</span><span>;</span> <span>import</span> <span>io.micronaut.http.HttpRequest</span><span>;</span> <span>import</span> <span>io.micronaut.http.annotation.CookieValue</span><span>;</span> <span>@Controller</span><span>(</span><span>"/"</span><span>)</span> <span>public</span> <span>class</span> <span>HomeController</span> <span>{</span> <span>private</span> <span>final</span> <span>Logger</span> <span>logger</span><span>;</span> <span>public</span> <span>HomeController</span><span>()</span> <span>{</span> <span>this</span><span>.</span><span>logger</span> <span>=</span> <span>LoggerFactory</span><span>.</span><span>getLogger</span><span>(</span><span>HomeController</span><span>.</span><span>class</span><span>);</span> <span>}</span> <span>@Get</span><span>(</span><span>"/"</span><span>)</span> <span>public</span> <span>String</span> <span>index</span><span>(</span><span>@CookieValue</span><span>(</span><span>"SESSION-VALUE"</span><span>)</span> <span>Optional</span><span><</span><span>String</span><span>></span> <span>sessionValue</span><span>,</span> <span>HttpRequest</span><span><</span><span>String</span><span>></span> <span>req</span><span>)</span> <span>{</span> <span>if</span> <span>(</span><span>sessionValue</span><span>.</span><span>isPresent</span><span>())</span> <span>{</span> <span>logger</span><span>.</span><span>debug</span><span>(</span><span>"OK: "</span> <span>+</span> <span>sessionValue</span><span>.</span><span>get</span><span>());</span> <span>}</span> <span>else</span> <span>{</span> <span>logger</span><span>.</span><span>debug</span><span>(</span><span>"No cookie"</span><span>);</span> <span>}</span> <span>Cookies</span> <span>c</span> <span>=</span> <span>req</span><span>.</span><span>getCookies</span><span>();</span> <span>for</span> <span>(</span><span>var</span> <span>v</span> <span>:</span> <span>c</span><span>.</span><span>getAll</span><span>())</span> <span>{</span> <span>logger</span><span>.</span><span>debug</span><span>(</span><span>"--------Cookie---------"</span><span>);</span> <span>logger</span><span>.</span><span>debug</span><span>(</span><span>"Name:"</span> <span>+</span> <span>v</span><span>.</span><span>getName</span><span>());</span> <span>logger</span><span>.</span><span>debug</span><span>(</span><span>"Value: "</span> <span>+</span> <span>v</span><span>.</span><span>getValue</span><span>());</span> <span>logger</span><span>.</span><span>debug</span><span>(</span><span>"Domain:"</span> <span>+</span> <span>v</span><span>.</span><span>getDomain</span><span>());</span> <span>logger</span><span>.</span><span>debug</span><span>(</span><span>"Path: "</span> <span>+</span> <span>v</span><span>.</span><span>getPath</span><span>());</span> <span>logger</span><span>.</span><span>debug</span><span>(</span><span>"MaxAge: "</span> <span>+</span> <span>v</span><span>.</span><span>getMaxAge</span><span>());</span> <span>logger</span><span>.</span><span>debug</span><span>(</span><span>"SameSite: "</span> <span>+</span> <span>v</span><span>.</span><span>getSameSite</span><span>());</span> <span>logger</span><span>.</span><span>debug</span><span>(</span><span>"HttpOnly: "</span> <span>+</span> <span>v</span><span>.</span><span>isHttpOnly</span><span>());</span> <span>logger</span><span>.</span><span>debug</span><span>(</span><span>"Secure: "</span> <span>+</span> <span>v</span><span>.</span><span>isSecure</span><span>());</span> <span>}</span> <span>return</span> <span>"Hello World!"</span><span>;</span> <span>}</span> <span>@Get</span><span>(</span><span>"/redirect"</span><span>)</span> <span>public</span> <span>MutableHttpResponse</span><span><</span><span>Object</span><span>></span> <span>redirectToOutTasks</span><span>()</span> <span>{</span> <span>URI</span> <span>location</span> <span>=</span> <span>URI</span><span>.</span><span>create</span><span>(</span><span>"http://ourtasks.masanori.jp:8083/ourtasks/pages/cookie"</span><span>);</span> <span>Cookie</span> <span>ck</span> <span>=</span> <span>Cookie</span><span>.</span><span>of</span><span>(</span><span>"SESSION-VALUE"</span><span>,</span> <span>"Hello Micronaut!"</span><span>);</span> <span>return</span> <span>HttpResponse</span><span>.</span><span>redirect</span><span>(</span><span>location</span><span>)</span> <span>.</span><span>cookie</span><span>(</span><span>ck</span><span>);</span> <span>}</span> <span>}</span>package jp.masanori; import java.util.Optional; import java.net.URI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.micronaut.http.HttpResponse; import io.micronaut.http.MutableHttpResponse; import io.micronaut.http.annotation.Controller; import io.micronaut.http.annotation.Get; import io.micronaut.http.cookie.Cookie; import io.micronaut.http.cookie.Cookies; import io.micronaut.http.cookie.SameSite; import io.micronaut.http.HttpRequest; import io.micronaut.http.annotation.CookieValue; @Controller("/") public class HomeController { private final Logger logger; public HomeController() { this.logger = LoggerFactory.getLogger(HomeController.class); } @Get("/") public String index(@CookieValue("SESSION-VALUE") Optional<String> sessionValue, HttpRequest<String> req) { if (sessionValue.isPresent()) { logger.debug("OK: " + sessionValue.get()); } else { logger.debug("No cookie"); } Cookies c = req.getCookies(); for (var v : c.getAll()) { logger.debug("--------Cookie---------"); logger.debug("Name:" + v.getName()); logger.debug("Value: " + v.getValue()); logger.debug("Domain:" + v.getDomain()); logger.debug("Path: " + v.getPath()); logger.debug("MaxAge: " + v.getMaxAge()); logger.debug("SameSite: " + v.getSameSite()); logger.debug("HttpOnly: " + v.isHttpOnly()); logger.debug("Secure: " + v.isSecure()); } return "Hello World!"; } @Get("/redirect") public MutableHttpResponse<Object> redirectToOutTasks() { URI location = URI.create("http://ourtasks.masanori.jp:8083/ourtasks/pages/cookie"); Cookie ck = Cookie.of("SESSION-VALUE", "Hello Micronaut!"); return HttpResponse.redirect(location) .cookie(ck); } }
Enter fullscreen mode Exit fullscreen mode
[Application2] PageController.java
<span>package</span> <span>jp.masanori.apps</span><span>;</span><span>import</span> <span>java.util.Optional</span><span>;</span><span>import</span> <span>org.slf4j.Logger</span><span>;</span><span>import</span> <span>org.slf4j.LoggerFactory</span><span>;</span><span>import</span> <span>io.micronaut.http.HttpResponse</span><span>;</span><span>import</span> <span>io.micronaut.http.MediaType</span><span>;</span><span>import</span> <span>io.micronaut.http.annotation.Controller</span><span>;</span><span>import</span> <span>io.micronaut.http.annotation.CookieValue</span><span>;</span><span>import</span> <span>io.micronaut.http.annotation.Get</span><span>;</span><span>import</span> <span>io.micronaut.http.annotation.Produces</span><span>;</span><span>import</span> <span>io.micronaut.views.View</span><span>;</span><span>@Controller</span><span>(</span><span>"/pages"</span><span>)</span><span>public</span> <span>class</span> <span>PageController</span> <span>{</span><span>private</span> <span>final</span> <span>Logger</span> <span>logger</span><span>;</span><span>public</span> <span>PageController</span><span>()</span> <span>{</span><span>this</span><span>.</span><span>logger</span> <span>=</span> <span>LoggerFactory</span><span>.</span><span>getLogger</span><span>(</span><span>PageController</span><span>.</span><span>class</span><span>);</span><span>}</span><span>@Produces</span><span>(</span><span>MediaType</span><span>.</span><span>TEXT_HTML</span><span>)</span><span>@Get</span><span>(</span><span>"/cookie"</span><span>)</span><span>@View</span><span>(</span><span>"editTask"</span><span>)</span><span>public</span> <span>HttpResponse</span><span><</span><span>String</span><span>></span> <span>getCookieSample</span><span>(</span><span>@CookieValue</span><span>(</span><span>"SESSION-VALUE"</span><span>)</span> <span>Optional</span><span><</span><span>String</span><span>></span> <span>sessionValue</span><span>)</span> <span>{</span><span>if</span> <span>(</span><span>sessionValue</span><span>.</span><span>isPresent</span><span>())</span> <span>{</span><span>logger</span><span>.</span><span>debug</span><span>(</span><span>"OK: "</span> <span>+</span> <span>sessionValue</span><span>.</span><span>get</span><span>());</span><span>}</span> <span>else</span> <span>{</span><span>logger</span><span>.</span><span>debug</span><span>(</span><span>"No cookie"</span><span>);</span><span>}</span><span>return</span> <span>HttpResponse</span><span>.</span><span>ok</span><span>();</span><span>}</span><span>}</span><span>package</span> <span>jp.masanori.apps</span><span>;</span> <span>import</span> <span>java.util.Optional</span><span>;</span> <span>import</span> <span>org.slf4j.Logger</span><span>;</span> <span>import</span> <span>org.slf4j.LoggerFactory</span><span>;</span> <span>import</span> <span>io.micronaut.http.HttpResponse</span><span>;</span> <span>import</span> <span>io.micronaut.http.MediaType</span><span>;</span> <span>import</span> <span>io.micronaut.http.annotation.Controller</span><span>;</span> <span>import</span> <span>io.micronaut.http.annotation.CookieValue</span><span>;</span> <span>import</span> <span>io.micronaut.http.annotation.Get</span><span>;</span> <span>import</span> <span>io.micronaut.http.annotation.Produces</span><span>;</span> <span>import</span> <span>io.micronaut.views.View</span><span>;</span> <span>@Controller</span><span>(</span><span>"/pages"</span><span>)</span> <span>public</span> <span>class</span> <span>PageController</span> <span>{</span> <span>private</span> <span>final</span> <span>Logger</span> <span>logger</span><span>;</span> <span>public</span> <span>PageController</span><span>()</span> <span>{</span> <span>this</span><span>.</span><span>logger</span> <span>=</span> <span>LoggerFactory</span><span>.</span><span>getLogger</span><span>(</span><span>PageController</span><span>.</span><span>class</span><span>);</span> <span>}</span> <span>@Produces</span><span>(</span><span>MediaType</span><span>.</span><span>TEXT_HTML</span><span>)</span> <span>@Get</span><span>(</span><span>"/cookie"</span><span>)</span> <span>@View</span><span>(</span><span>"editTask"</span><span>)</span> <span>public</span> <span>HttpResponse</span><span><</span><span>String</span><span>></span> <span>getCookieSample</span><span>(</span><span>@CookieValue</span><span>(</span><span>"SESSION-VALUE"</span><span>)</span> <span>Optional</span><span><</span><span>String</span><span>></span> <span>sessionValue</span><span>)</span> <span>{</span> <span>if</span> <span>(</span><span>sessionValue</span><span>.</span><span>isPresent</span><span>())</span> <span>{</span> <span>logger</span><span>.</span><span>debug</span><span>(</span><span>"OK: "</span> <span>+</span> <span>sessionValue</span><span>.</span><span>get</span><span>());</span> <span>}</span> <span>else</span> <span>{</span> <span>logger</span><span>.</span><span>debug</span><span>(</span><span>"No cookie"</span><span>);</span> <span>}</span> <span>return</span> <span>HttpResponse</span><span>.</span><span>ok</span><span>();</span> <span>}</span> <span>}</span>package jp.masanori.apps; import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.micronaut.http.HttpResponse; import io.micronaut.http.MediaType; import io.micronaut.http.annotation.Controller; import io.micronaut.http.annotation.CookieValue; import io.micronaut.http.annotation.Get; import io.micronaut.http.annotation.Produces; import io.micronaut.views.View; @Controller("/pages") public class PageController { private final Logger logger; public PageController() { this.logger = LoggerFactory.getLogger(PageController.class); } @Produces(MediaType.TEXT_HTML) @Get("/cookie") @View("editTask") public HttpResponse<String> getCookieSample(@CookieValue("SESSION-VALUE") Optional<String> sessionValue) { if (sessionValue.isPresent()) { logger.debug("OK: " + sessionValue.get()); } else { logger.debug("No cookie"); } return HttpResponse.ok(); } }
Enter fullscreen mode Exit fullscreen mode
Set cookies into subdomains
By defaut, the application2 can’t get the cookie value.
When I access sample.masanori.jp:8086(HomeController.index() of application1 is called),
I will get logs like below.
--------Cookie---------Name:SESSION-VALUEValue: Hello Micronaut!Domain:nullPath: nullMaxAge: -9223372036854775808SameSite: Optional.emptyHttpOnly: falseSecure: false--------Cookie--------- Name:SESSION-VALUE Value: Hello Micronaut! Domain:null Path: null MaxAge: -9223372036854775808 SameSite: Optional.empty HttpOnly: false Secure: false--------Cookie--------- Name:SESSION-VALUE Value: Hello Micronaut! Domain:null Path: null MaxAge: -9223372036854775808 SameSite: Optional.empty HttpOnly: false Secure: false
Enter fullscreen mode Exit fullscreen mode
Because their domains are just added into the hosts file of Windows,
so if I change the application1 domain into “ourtasks.masanori.jp:8086”, the application2 can get the cookie value.
hosts
...127.0.0.1 ourtasks.masanori.jp127.0.0.1 sample.masanori.jp... 127.0.0.1 ourtasks.masanori.jp 127.0.0.1 sample.masanori.jp... 127.0.0.1 ourtasks.masanori.jp 127.0.0.1 sample.masanori.jp
Enter fullscreen mode Exit fullscreen mode
To share cookie values between their domains, I will add some options.
[Application1] HomeController.java
<span>...</span><span>@Get</span><span>(</span><span>"/redirect"</span><span>)</span><span>public</span> <span>MutableHttpResponse</span><span><</span><span>Object</span><span>></span> <span>redirectToOutTasks</span><span>()</span> <span>{</span><span>URI</span> <span>location</span> <span>=</span> <span>URI</span><span>.</span><span>create</span><span>(</span><span>"http://ourtasks.masanori.jp:8083/ourtasks/pages/cookie"</span><span>);</span><span>Cookie</span> <span>ck</span> <span>=</span> <span>Cookie</span><span>.</span><span>of</span><span>(</span><span>"SESSION-VALUE"</span><span>,</span> <span>"Hello Micronaut!!"</span><span>);</span><span>// To avoid accessing the cookie value from the client-side</span><span>ck</span><span>.</span><span>httpOnly</span><span>(</span><span>true</span><span>);</span><span>// Share the cookie value on "masanori.jp" or "*.masanori.jp".</span><span>// Both the application1 and application2 have to belong to these domains. </span><span>ck</span><span>.</span><span>domain</span><span>(</span><span>"masanori.jp"</span><span>);</span><span>ck</span><span>.</span><span>sameSite</span><span>(</span><span>SameSite</span><span>.</span><span>Strict</span><span>);</span><span>return</span> <span>HttpResponse</span><span>.</span><span>redirect</span><span>(</span><span>location</span><span>)</span><span>.</span><span>cookie</span><span>(</span><span>ck</span><span>);</span><span>}</span><span>}</span><span>...</span> <span>@Get</span><span>(</span><span>"/redirect"</span><span>)</span> <span>public</span> <span>MutableHttpResponse</span><span><</span><span>Object</span><span>></span> <span>redirectToOutTasks</span><span>()</span> <span>{</span> <span>URI</span> <span>location</span> <span>=</span> <span>URI</span><span>.</span><span>create</span><span>(</span><span>"http://ourtasks.masanori.jp:8083/ourtasks/pages/cookie"</span><span>);</span> <span>Cookie</span> <span>ck</span> <span>=</span> <span>Cookie</span><span>.</span><span>of</span><span>(</span><span>"SESSION-VALUE"</span><span>,</span> <span>"Hello Micronaut!!"</span><span>);</span> <span>// To avoid accessing the cookie value from the client-side</span> <span>ck</span><span>.</span><span>httpOnly</span><span>(</span><span>true</span><span>);</span> <span>// Share the cookie value on "masanori.jp" or "*.masanori.jp".</span> <span>// Both the application1 and application2 have to belong to these domains. </span> <span>ck</span><span>.</span><span>domain</span><span>(</span><span>"masanori.jp"</span><span>);</span> <span>ck</span><span>.</span><span>sameSite</span><span>(</span><span>SameSite</span><span>.</span><span>Strict</span><span>);</span> <span>return</span> <span>HttpResponse</span><span>.</span><span>redirect</span><span>(</span><span>location</span><span>)</span> <span>.</span><span>cookie</span><span>(</span><span>ck</span><span>);</span> <span>}</span> <span>}</span>... @Get("/redirect") public MutableHttpResponse<Object> redirectToOutTasks() { URI location = URI.create("http://ourtasks.masanori.jp:8083/ourtasks/pages/cookie"); Cookie ck = Cookie.of("SESSION-VALUE", "Hello Micronaut!!"); // To avoid accessing the cookie value from the client-side ck.httpOnly(true); // Share the cookie value on "masanori.jp" or "*.masanori.jp". // Both the application1 and application2 have to belong to these domains. ck.domain("masanori.jp"); ck.sameSite(SameSite.Strict); return HttpResponse.redirect(location) .cookie(ck); } }
Enter fullscreen mode Exit fullscreen mode
Set cookies for Undertow
When I use Under tow as a web server, the above code could not set cookies.
(Although I can see the value on a web browser, but I could not get it on my application)
So I should add “Set-Cookie” into the HttpResponse headers.
build.gradle
<span>...</span><span>micronaut</span> <span>{</span><span>runtime</span><span>(</span><span>"undertow"</span><span>)</span><span>testRuntime</span><span>(</span><span>"junit5"</span><span>)</span><span>processing</span> <span>{</span><span>incremental</span><span>(</span><span>true</span><span>)</span><span>annotations</span><span>(</span><span>"jp.masanori.*"</span><span>)</span><span>}</span><span>aot</span> <span>{</span><span>...</span><span>}</span><span>}</span><span>...</span><span>...</span> <span>micronaut</span> <span>{</span> <span>runtime</span><span>(</span><span>"undertow"</span><span>)</span> <span>testRuntime</span><span>(</span><span>"junit5"</span><span>)</span> <span>processing</span> <span>{</span> <span>incremental</span><span>(</span><span>true</span><span>)</span> <span>annotations</span><span>(</span><span>"jp.masanori.*"</span><span>)</span> <span>}</span> <span>aot</span> <span>{</span> <span>...</span> <span>}</span> <span>}</span> <span>...</span>... micronaut { runtime("undertow") testRuntime("junit5") processing { incremental(true) annotations("jp.masanori.*") } aot { ... } } ...
Enter fullscreen mode Exit fullscreen mode
PageController.java
<span>...</span><span>@Get</span><span>(</span><span>"/jwt"</span><span>)</span><span>public</span> <span>MutableHttpResponse</span><span><?></span> <span>tryJwt</span><span>(</span><span>@CookieValue</span><span>(</span><span>"JWT-VALUE"</span><span>)</span> <span>Optional</span><span><</span><span>String</span><span>></span> <span>sessionValue</span><span>)</span> <span>{</span><span>if</span> <span>(</span><span>sessionValue</span><span>.</span><span>isPresent</span><span>())</span> <span>{</span><span>logger</span><span>.</span><span>info</span><span>(</span><span>"OK: "</span> <span>+</span> <span>sessionValue</span><span>.</span><span>get</span><span>());</span><span>return</span> <span>HttpResponse</span><span>.</span><span>ok</span><span>();</span><span>}</span> <span>else</span> <span>{</span><span>return</span> <span>HttpResponse</span><span>.</span><span>ok</span><span>()</span><span>// I could not use "cookie()" for Undertow</span><span>/* .cookie(ck) */</span><span>.</span><span>header</span><span>(</span><span>"Set-Cookie"</span><span>,</span> <span>String</span><span>.</span><span>format</span><span>(</span><span>"JWT-VALUE=%s;path=/;HttpOnly;"</span><span>,</span> <span>"Hello"</span><span>));</span><span>}</span><span>}</span><span>...</span><span>...</span> <span>@Get</span><span>(</span><span>"/jwt"</span><span>)</span> <span>public</span> <span>MutableHttpResponse</span><span><?></span> <span>tryJwt</span><span>(</span><span>@CookieValue</span><span>(</span><span>"JWT-VALUE"</span><span>)</span> <span>Optional</span><span><</span><span>String</span><span>></span> <span>sessionValue</span><span>)</span> <span>{</span> <span>if</span> <span>(</span><span>sessionValue</span><span>.</span><span>isPresent</span><span>())</span> <span>{</span> <span>logger</span><span>.</span><span>info</span><span>(</span><span>"OK: "</span> <span>+</span> <span>sessionValue</span><span>.</span><span>get</span><span>());</span> <span>return</span> <span>HttpResponse</span><span>.</span><span>ok</span><span>();</span> <span>}</span> <span>else</span> <span>{</span> <span>return</span> <span>HttpResponse</span><span>.</span><span>ok</span><span>()</span> <span>// I could not use "cookie()" for Undertow</span> <span>/* .cookie(ck) */</span> <span>.</span><span>header</span><span>(</span><span>"Set-Cookie"</span><span>,</span> <span>String</span><span>.</span><span>format</span><span>(</span><span>"JWT-VALUE=%s;path=/;HttpOnly;"</span><span>,</span> <span>"Hello"</span><span>));</span> <span>}</span> <span>}</span> <span>...</span>... @Get("/jwt") public MutableHttpResponse<?> tryJwt(@CookieValue("JWT-VALUE") Optional<String> sessionValue) { if (sessionValue.isPresent()) { logger.info("OK: " + sessionValue.get()); return HttpResponse.ok(); } else { return HttpResponse.ok() // I could not use "cookie()" for Undertow /* .cookie(ck) */ .header("Set-Cookie", String.format("JWT-VALUE=%s;path=/;HttpOnly;", "Hello")); } } ...
Enter fullscreen mode Exit fullscreen mode
Set JWT to cookies
I will try setting JWT as a cookie value using java-jwt.
PageController.java
<span>import</span> <span>java.util.Date</span><span>;</span><span>import</span> <span>java.util.Optional</span><span>;</span><span>import</span> <span>org.slf4j.Logger</span><span>;</span><span>import</span> <span>org.slf4j.LoggerFactory</span><span>;</span><span>import</span> <span>com.auth0.jwt.JWT</span><span>;</span><span>import</span> <span>com.auth0.jwt.algorithms.Algorithm</span><span>;</span><span>import</span> <span>com.auth0.jwt.exceptions.JWTCreationException</span><span>;</span><span>import</span> <span>com.auth0.jwt.exceptions.JWTVerificationException</span><span>;</span><span>import</span> <span>com.auth0.jwt.interfaces.Claim</span><span>;</span><span>import</span> <span>com.auth0.jwt.interfaces.DecodedJWT</span><span>;</span><span>import</span> <span>com.auth0.jwt.interfaces.JWTVerifier</span><span>;</span><span>import</span> <span>io.micronaut.core.util.CollectionUtils</span><span>;</span><span>import</span> <span>io.micronaut.http.HttpRequest</span><span>;</span><span>import</span> <span>io.micronaut.http.HttpResponse</span><span>;</span><span>import</span> <span>io.micronaut.http.MediaType</span><span>;</span><span>import</span> <span>io.micronaut.http.MutableHttpResponse</span><span>;</span><span>import</span> <span>io.micronaut.http.annotation.Controller</span><span>;</span><span>import</span> <span>io.micronaut.http.annotation.CookieValue</span><span>;</span><span>import</span> <span>io.micronaut.http.annotation.Get</span><span>;</span><span>import</span> <span>io.micronaut.http.annotation.Produces</span><span>;</span><span>import</span> <span>io.micronaut.views.View</span><span>;</span><span>import</span> <span>io.micronaut.http.cookie.Cookies</span><span>;</span><span>@Controller</span><span>(</span><span>"/pages"</span><span>)</span><span>public</span> <span>class</span> <span>PageController</span> <span>{</span><span>...</span><span>@Get</span><span>(</span><span>"/jwt"</span><span>)</span><span>public</span> <span>MutableHttpResponse</span><span><?></span> <span>tryJwt</span><span>(</span><span>@CookieValue</span><span>(</span><span>"JWT-VALUE"</span><span>)</span> <span>Optional</span><span><</span><span>String</span><span>></span> <span>sessionValue</span><span>)</span> <span>{</span><span>if</span> <span>(</span><span>sessionValue</span><span>.</span><span>isPresent</span><span>())</span> <span>{</span><span>if</span> <span>(</span><span>validateJwt</span><span>(</span><span>sessionValue</span><span>))</span> <span>{</span><span>return</span> <span>HttpResponse</span><span>.</span><span>ok</span><span>();</span><span>}</span> <span>else</span> <span>{</span><span>return</span> <span>HttpResponse</span><span>.</span><span>unauthorized</span><span>();</span><span>}</span><span>}</span> <span>else</span> <span>{</span><span>return</span> <span>HttpResponse</span><span>.</span><span>ok</span><span>()</span><span>/* .cookie(ck) */</span><span>.</span><span>header</span><span>(</span><span>"Set-Cookie"</span><span>,</span> <span>String</span><span>.</span><span>format</span><span>(</span><span>"JWT-VALUE=%s;path=/;HttpOnly;"</span><span>,</span> <span>generateJwt</span><span>()));</span><span>}</span><span>}</span><span>private</span> <span>String</span> <span>generateJwt</span><span>()</span> <span>{</span><span>try</span> <span>{</span><span>Date</span> <span>expireTime</span> <span>=</span> <span>new</span> <span>Date</span><span>();</span><span>expireTime</span><span>.</span><span>setTime</span><span>(</span><span>expireTime</span><span>.</span><span>getTime</span><span>()</span> <span>+</span> <span>10000</span><span>);</span><span>Algorithm</span> <span>algorithm</span> <span>=</span> <span>Algorithm</span><span>.</span><span>HMAC256</span><span>(</span><span>"secret"</span><span>);</span><span>return</span> <span>JWT</span><span>.</span><span>create</span><span>()</span><span>.</span><span>withClaim</span><span>(</span><span>"message"</span><span>,</span> <span>"hello"</span><span>)</span><span>.</span><span>withIssuer</span><span>(</span><span>"masanori"</span><span>)</span><span>.</span><span>withExpiresAt</span><span>(</span><span>expireTime</span><span>)</span><span>.</span><span>sign</span><span>(</span><span>algorithm</span><span>);</span><span>}</span> <span>catch</span> <span>(</span><span>JWTCreationException</span> <span>exception</span><span>)</span> <span>{</span><span>logger</span><span>.</span><span>error</span><span>(</span><span>"JWT Error: "</span><span>,</span> <span>exception</span><span>);</span><span>}</span><span>return</span> <span>null</span><span>;</span><span>}</span><span>private</span> <span>boolean</span> <span>validateJwt</span><span>(</span><span>Optional</span><span><</span><span>String</span><span>></span> <span>value</span><span>)</span> <span>{</span><span>if</span> <span>(</span><span>value</span><span>.</span><span>isPresent</span><span>()</span> <span>==</span> <span>false</span><span>)</span> <span>{</span><span>return</span> <span>false</span><span>;</span><span>}</span><span>try</span> <span>{</span><span>Algorithm</span> <span>algorithm</span> <span>=</span> <span>Algorithm</span><span>.</span><span>HMAC256</span><span>(</span><span>"secret"</span><span>);</span><span>JWTVerifier</span> <span>verifier</span> <span>=</span> <span>JWT</span><span>.</span><span>require</span><span>(</span><span>algorithm</span><span>)</span><span>.</span><span>withIssuer</span><span>(</span><span>"masanori"</span><span>)</span><span>.</span><span>build</span><span>();</span><span>DecodedJWT</span> <span>jwt</span> <span>=</span> <span>verifier</span><span>.</span><span>verify</span><span>(</span><span>value</span><span>.</span><span>get</span><span>());</span><span>Claim</span> <span>message</span> <span>=</span> <span>jwt</span><span>.</span><span>getClaim</span><span>(</span><span>"message"</span><span>);</span><span>if</span> <span>(</span><span>message</span><span>.</span><span>isMissing</span><span>()</span> <span>==</span> <span>false</span> <span>&&</span> <span>message</span><span>.</span><span>isNull</span><span>()</span> <span>==</span> <span>false</span><span>)</span> <span>{</span><span>logger</span><span>.</span><span>info</span><span>(</span><span>"decoded message: "</span> <span>+</span> <span>message</span><span>.</span><span>asString</span><span>());</span><span>}</span><span>return</span> <span>true</span><span>;</span><span>}</span> <span>catch</span> <span>(</span><span>JWTVerificationException</span> <span>exception</span><span>)</span> <span>{</span><span>logger</span><span>.</span><span>error</span><span>(</span><span>"JWT validate failed "</span><span>,</span> <span>exception</span><span>);</span><span>return</span> <span>false</span><span>;</span><span>}</span><span>}</span><span>...</span><span>import</span> <span>java.util.Date</span><span>;</span> <span>import</span> <span>java.util.Optional</span><span>;</span> <span>import</span> <span>org.slf4j.Logger</span><span>;</span> <span>import</span> <span>org.slf4j.LoggerFactory</span><span>;</span> <span>import</span> <span>com.auth0.jwt.JWT</span><span>;</span> <span>import</span> <span>com.auth0.jwt.algorithms.Algorithm</span><span>;</span> <span>import</span> <span>com.auth0.jwt.exceptions.JWTCreationException</span><span>;</span> <span>import</span> <span>com.auth0.jwt.exceptions.JWTVerificationException</span><span>;</span> <span>import</span> <span>com.auth0.jwt.interfaces.Claim</span><span>;</span> <span>import</span> <span>com.auth0.jwt.interfaces.DecodedJWT</span><span>;</span> <span>import</span> <span>com.auth0.jwt.interfaces.JWTVerifier</span><span>;</span> <span>import</span> <span>io.micronaut.core.util.CollectionUtils</span><span>;</span> <span>import</span> <span>io.micronaut.http.HttpRequest</span><span>;</span> <span>import</span> <span>io.micronaut.http.HttpResponse</span><span>;</span> <span>import</span> <span>io.micronaut.http.MediaType</span><span>;</span> <span>import</span> <span>io.micronaut.http.MutableHttpResponse</span><span>;</span> <span>import</span> <span>io.micronaut.http.annotation.Controller</span><span>;</span> <span>import</span> <span>io.micronaut.http.annotation.CookieValue</span><span>;</span> <span>import</span> <span>io.micronaut.http.annotation.Get</span><span>;</span> <span>import</span> <span>io.micronaut.http.annotation.Produces</span><span>;</span> <span>import</span> <span>io.micronaut.views.View</span><span>;</span> <span>import</span> <span>io.micronaut.http.cookie.Cookies</span><span>;</span> <span>@Controller</span><span>(</span><span>"/pages"</span><span>)</span> <span>public</span> <span>class</span> <span>PageController</span> <span>{</span> <span>...</span> <span>@Get</span><span>(</span><span>"/jwt"</span><span>)</span> <span>public</span> <span>MutableHttpResponse</span><span><?></span> <span>tryJwt</span><span>(</span><span>@CookieValue</span><span>(</span><span>"JWT-VALUE"</span><span>)</span> <span>Optional</span><span><</span><span>String</span><span>></span> <span>sessionValue</span><span>)</span> <span>{</span> <span>if</span> <span>(</span><span>sessionValue</span><span>.</span><span>isPresent</span><span>())</span> <span>{</span> <span>if</span> <span>(</span><span>validateJwt</span><span>(</span><span>sessionValue</span><span>))</span> <span>{</span> <span>return</span> <span>HttpResponse</span><span>.</span><span>ok</span><span>();</span> <span>}</span> <span>else</span> <span>{</span> <span>return</span> <span>HttpResponse</span><span>.</span><span>unauthorized</span><span>();</span> <span>}</span> <span>}</span> <span>else</span> <span>{</span> <span>return</span> <span>HttpResponse</span><span>.</span><span>ok</span><span>()</span> <span>/* .cookie(ck) */</span> <span>.</span><span>header</span><span>(</span><span>"Set-Cookie"</span><span>,</span> <span>String</span><span>.</span><span>format</span><span>(</span><span>"JWT-VALUE=%s;path=/;HttpOnly;"</span><span>,</span> <span>generateJwt</span><span>()));</span> <span>}</span> <span>}</span> <span>private</span> <span>String</span> <span>generateJwt</span><span>()</span> <span>{</span> <span>try</span> <span>{</span> <span>Date</span> <span>expireTime</span> <span>=</span> <span>new</span> <span>Date</span><span>();</span> <span>expireTime</span><span>.</span><span>setTime</span><span>(</span><span>expireTime</span><span>.</span><span>getTime</span><span>()</span> <span>+</span> <span>10000</span><span>);</span> <span>Algorithm</span> <span>algorithm</span> <span>=</span> <span>Algorithm</span><span>.</span><span>HMAC256</span><span>(</span><span>"secret"</span><span>);</span> <span>return</span> <span>JWT</span><span>.</span><span>create</span><span>()</span> <span>.</span><span>withClaim</span><span>(</span><span>"message"</span><span>,</span> <span>"hello"</span><span>)</span> <span>.</span><span>withIssuer</span><span>(</span><span>"masanori"</span><span>)</span> <span>.</span><span>withExpiresAt</span><span>(</span><span>expireTime</span><span>)</span> <span>.</span><span>sign</span><span>(</span><span>algorithm</span><span>);</span> <span>}</span> <span>catch</span> <span>(</span><span>JWTCreationException</span> <span>exception</span><span>)</span> <span>{</span> <span>logger</span><span>.</span><span>error</span><span>(</span><span>"JWT Error: "</span><span>,</span> <span>exception</span><span>);</span> <span>}</span> <span>return</span> <span>null</span><span>;</span> <span>}</span> <span>private</span> <span>boolean</span> <span>validateJwt</span><span>(</span><span>Optional</span><span><</span><span>String</span><span>></span> <span>value</span><span>)</span> <span>{</span> <span>if</span> <span>(</span><span>value</span><span>.</span><span>isPresent</span><span>()</span> <span>==</span> <span>false</span><span>)</span> <span>{</span> <span>return</span> <span>false</span><span>;</span> <span>}</span> <span>try</span> <span>{</span> <span>Algorithm</span> <span>algorithm</span> <span>=</span> <span>Algorithm</span><span>.</span><span>HMAC256</span><span>(</span><span>"secret"</span><span>);</span> <span>JWTVerifier</span> <span>verifier</span> <span>=</span> <span>JWT</span><span>.</span><span>require</span><span>(</span><span>algorithm</span><span>)</span> <span>.</span><span>withIssuer</span><span>(</span><span>"masanori"</span><span>)</span> <span>.</span><span>build</span><span>();</span> <span>DecodedJWT</span> <span>jwt</span> <span>=</span> <span>verifier</span><span>.</span><span>verify</span><span>(</span><span>value</span><span>.</span><span>get</span><span>());</span> <span>Claim</span> <span>message</span> <span>=</span> <span>jwt</span><span>.</span><span>getClaim</span><span>(</span><span>"message"</span><span>);</span> <span>if</span> <span>(</span><span>message</span><span>.</span><span>isMissing</span><span>()</span> <span>==</span> <span>false</span> <span>&&</span> <span>message</span><span>.</span><span>isNull</span><span>()</span> <span>==</span> <span>false</span><span>)</span> <span>{</span> <span>logger</span><span>.</span><span>info</span><span>(</span><span>"decoded message: "</span> <span>+</span> <span>message</span><span>.</span><span>asString</span><span>());</span> <span>}</span> <span>return</span> <span>true</span><span>;</span> <span>}</span> <span>catch</span> <span>(</span><span>JWTVerificationException</span> <span>exception</span><span>)</span> <span>{</span> <span>logger</span><span>.</span><span>error</span><span>(</span><span>"JWT validate failed "</span><span>,</span> <span>exception</span><span>);</span> <span>return</span> <span>false</span><span>;</span> <span>}</span> <span>}</span> <span>...</span>import java.util.Date; import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.JWTCreationException; import com.auth0.jwt.exceptions.JWTVerificationException; import com.auth0.jwt.interfaces.Claim; import com.auth0.jwt.interfaces.DecodedJWT; import com.auth0.jwt.interfaces.JWTVerifier; import io.micronaut.core.util.CollectionUtils; import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpResponse; import io.micronaut.http.MediaType; import io.micronaut.http.MutableHttpResponse; import io.micronaut.http.annotation.Controller; import io.micronaut.http.annotation.CookieValue; import io.micronaut.http.annotation.Get; import io.micronaut.http.annotation.Produces; import io.micronaut.views.View; import io.micronaut.http.cookie.Cookies; @Controller("/pages") public class PageController { ... @Get("/jwt") public MutableHttpResponse<?> tryJwt(@CookieValue("JWT-VALUE") Optional<String> sessionValue) { if (sessionValue.isPresent()) { if (validateJwt(sessionValue)) { return HttpResponse.ok(); } else { return HttpResponse.unauthorized(); } } else { return HttpResponse.ok() /* .cookie(ck) */ .header("Set-Cookie", String.format("JWT-VALUE=%s;path=/;HttpOnly;", generateJwt())); } } private String generateJwt() { try { Date expireTime = new Date(); expireTime.setTime(expireTime.getTime() + 10000); Algorithm algorithm = Algorithm.HMAC256("secret"); return JWT.create() .withClaim("message", "hello") .withIssuer("masanori") .withExpiresAt(expireTime) .sign(algorithm); } catch (JWTCreationException exception) { logger.error("JWT Error: ", exception); } return null; } private boolean validateJwt(Optional<String> value) { if (value.isPresent() == false) { return false; } try { Algorithm algorithm = Algorithm.HMAC256("secret"); JWTVerifier verifier = JWT.require(algorithm) .withIssuer("masanori") .build(); DecodedJWT jwt = verifier.verify(value.get()); Claim message = jwt.getClaim("message"); if (message.isMissing() == false && message.isNull() == false) { logger.info("decoded message: " + message.asString()); } return true; } catch (JWTVerificationException exception) { logger.error("JWT validate failed ", exception); return false; } } ...
Enter fullscreen mode Exit fullscreen mode
暂无评论内容