{"componentChunkName":"component---src-templates-blog-list-template-js","path":"/engineering/30","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"excerpt":"PKCE is an OAuth 2.0 security extension for public clients on mobile devices intended to avoid a malicious programme creeping into the same…","fields":{"slug":"/engineering/pkce/"},"html":"<p>PKCE is an OAuth 2.0 security extension for public clients on mobile devices intended to avoid a malicious programme creeping into the same computer from intercepting the authorisation code. The <a href=\"https://oauth.net/2/pkce/\">RFC 7636</a> introduction discusses the mechanisms of such an attack.</p>\n<p>PKCE has a different specification of its own. It allows applications to use the most reliable OAuth 2.0 flows in public or untrusted clients - the Authorization Code flow. In order to efficiently use a dynamically generated password, it achieves this by doing some setup work before the flow and some verification at the end of the flow. </p>\n<p>This is important because getting a fixed secret in a public client is not safe.</p>\n<p>In this blog, we will see how PKCE is useful in authorization code flow for OAuth and OIDC and how you can use this with your OAuth and OpenID Connect providers.</p>\n<h2 id=\"what-is-pkce\" style=\"position:relative;\"><a href=\"#what-is-pkce\" aria-label=\"what is pkce permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is PKCE</h2>\n<p>Proof Key for Code Exchange as known as PKCE, is a key for preventing malicious attacks and securely performing code authorization flow.</p>\n<p>I would say, PKCE is used to provide one more security layer to the authorization code flow in <a href=\"/oauth2/\">OAuth</a> and OpenID Connect.</p>\n<p>PKCE is mainly useful for the client-side application or any web apps that are using the client secret key and used to replace the static secret used in the authorization flow.</p>\n<p>This flow basically works with two parameters <strong>Code Verifier</strong> and <strong>Code challenge</strong>. Let's see what are these parameters, how we use them, and generate them.</p>\n<h3 id=\"pkce-code-verifier-and-challenge\" style=\"position:relative;\"><a href=\"#pkce-code-verifier-and-challenge\" aria-label=\"pkce code verifier and challenge permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>PKCE code verifier and challenge</h3>\n<p><strong>The code verifier</strong> is a cryptographically random string using the characters A-Z, a-z, 0-9, and the punctuation characters -._~ (hyphen, period, underscore, and tilde), between 43 and 128 characters long.\nOnce the client has generated the code verifier, it uses that to create the <strong>code challenge</strong>.</p>\n<p>For devices that can perform a SHA256 hash, the code challenge is a BASE64-URL-encoded string of the SHA256 hash of the code verifier.</p>\n<h3 id=\"generate-code-verifier-and-code-challenge\" style=\"position:relative;\"><a href=\"#generate-code-verifier-and-code-challenge\" aria-label=\"generate code verifier and code challenge permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Generate code verifier and code challenge</h3>\n<p>Here you can see the examples to generate the Code verifier and code challenge in different languages. Either you <a href=\"/oAuth-implemenation-using-node/\">can find Node</a> and <a href=\"/golang-maps/\">Go Packages</a> for this but I would recommend you to not depend on any package for such small things.</p>\n<p><strong>NodeJs</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">crypto</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;crypto&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">base64URLEncode</span><span class=\"mtk1\">(</span><span class=\"mtk12\">str</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">str</span><span class=\"mtk1\">.</span><span class=\"mtk11\">toString</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;base64&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">replace</span><span class=\"mtk1\">(</span><span class=\"mtk5\">/</span><span class=\"mtk6\">\\+</span><span class=\"mtk5\">/</span><span class=\"mtk4\">g</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;-&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">replace</span><span class=\"mtk1\">(</span><span class=\"mtk5\">/</span><span class=\"mtk6\">\\/</span><span class=\"mtk5\">/</span><span class=\"mtk4\">g</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;_&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">replace</span><span class=\"mtk1\">(</span><span class=\"mtk5\">/=/</span><span class=\"mtk4\">g</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">verifier</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">base64URLEncode</span><span class=\"mtk1\">(</span><span class=\"mtk12\">crypto</span><span class=\"mtk1\">.</span><span class=\"mtk11\">randomBytes</span><span class=\"mtk1\">(</span><span class=\"mtk7\">32</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;code_verifier: &quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">verifier</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\">(</span><span class=\"mtk12\">verifier</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">challenge</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">base64URLEncode</span><span class=\"mtk1\">(</span><span class=\"mtk11\">sha256</span><span class=\"mtk1\">(</span><span class=\"mtk12\">verifier</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;code_challenge: &quot;</span><span class=\"mtk1\">,</span><span class=\"mtk12\">challenge</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">sha256</span><span class=\"mtk1\">(</span><span class=\"mtk12\">buffer</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">crypto</span><span class=\"mtk1\">.</span><span class=\"mtk11\">createHash</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;sha256&#39;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">update</span><span class=\"mtk1\">(</span><span class=\"mtk12\">buffer</span><span class=\"mtk1\">).</span><span class=\"mtk11\">digest</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p><strong>Golang</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"golang\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">package main</span>\n<span class=\"grvsc-line\"> </span>\n<span class=\"grvsc-line\">import (</span>\n<span class=\"grvsc-line\">    &quot;crypto/sha256&quot;</span>\n<span class=\"grvsc-line\">    &quot;encoding/base64&quot;</span>\n<span class=\"grvsc-line\">    &quot;fmt&quot;</span>\n<span class=\"grvsc-line\">    &quot;math/rand&quot;</span>\n<span class=\"grvsc-line\">    &quot;strings&quot;</span>\n<span class=\"grvsc-line\">    &quot;time&quot;</span>\n<span class=\"grvsc-line\">)</span>\n<span class=\"grvsc-line\"> </span>\n<span class=\"grvsc-line\">type CodeVerifier struct {</span>\n<span class=\"grvsc-line\">    Value string</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"> </span>\n<span class=\"grvsc-line\">const (</span>\n<span class=\"grvsc-line\">    length = 32</span>\n<span class=\"grvsc-line\">)</span>\n<span class=\"grvsc-line\"> </span>\n<span class=\"grvsc-line\">func base64URLEncode(str []byte) string {</span>\n<span class=\"grvsc-line\">    encoded := base64.StdEncoding.EncodeToString(str)</span>\n<span class=\"grvsc-line\">    encoded = strings.Replace(encoded, &quot;+&quot;, &quot;-&quot;, -1)</span>\n<span class=\"grvsc-line\">    encoded = strings.Replace(encoded, &quot;/&quot;, &quot;_&quot;, -1)</span>\n<span class=\"grvsc-line\">    encoded = strings.Replace(encoded, &quot;=&quot;, &quot;&quot;, -1)</span>\n<span class=\"grvsc-line\">    return encoded</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"> </span>\n<span class=\"grvsc-line\">func verifier() (*CodeVerifier, error) {</span>\n<span class=\"grvsc-line\">    r := rand.New(rand.NewSource(time.Now().UnixNano()))</span>\n<span class=\"grvsc-line\">    b := make([]byte, length, length)</span>\n<span class=\"grvsc-line\">    for i := 0; i &lt; length; i++ {</span>\n<span class=\"grvsc-line\">        b[i] = byte(r.Intn(255))</span>\n<span class=\"grvsc-line\">    }</span>\n<span class=\"grvsc-line\">    return CreateCodeVerifierFromBytes(b)</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"> </span>\n<span class=\"grvsc-line\">func CreateCodeVerifierFromBytes(b []byte) (*CodeVerifier, error) {</span>\n<span class=\"grvsc-line\">    return &CodeVerifier{</span>\n<span class=\"grvsc-line\">        Value: base64URLEncode(b),</span>\n<span class=\"grvsc-line\">    }, nil</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"> </span>\n<span class=\"grvsc-line\">func (v *CodeVerifier) CodeChallengeS256() string {</span>\n<span class=\"grvsc-line\">    h := sha256.New()</span>\n<span class=\"grvsc-line\">    h.Write([]byte(v.Value))</span>\n<span class=\"grvsc-line\">    return base64URLEncode(h.Sum(nil))</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"> </span>\n<span class=\"grvsc-line\">func main() {</span>\n<span class=\"grvsc-line\">    verifier, _ := verifier()</span>\n<span class=\"grvsc-line\">    fmt.Println(&quot;code_verifier: &quot;, verifier.Value)</span>\n<span class=\"grvsc-line\">    challenge := verifier.CodeChallengeS256()</span>\n<span class=\"grvsc-line\">    fmt.Println(&quot;code_challenge :&quot;, challenge)</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"> </span></code></pre>\n<h2 id=\"implement-the-oauth-20-authorization-code-with-pkce-flow\" style=\"position:relative;\"><a href=\"#implement-the-oauth-20-authorization-code-with-pkce-flow\" aria-label=\"implement the oauth 20 authorization code with pkce flow permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Implement the OAuth 2.0 Authorization Code with PKCE Flow</h2>\n<h3 id=\"get-the-authorization-code\" style=\"position:relative;\"><a href=\"#get-the-authorization-code\" aria-label=\"get the authorization code permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Get the Authorization code</h3>\n<p>In the OAuth Authorization flow, we need to have the code verifier and code challenge to start with the authentication and obviously an OAuth provider to connect.</p>\n<p> For the initial request, we need to pass the code<em>challenge and code</em>challenge_method to the OAuth or OIDC provider that supports PKCE based flow.</p>\n<p>The request will look like: </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">Provider + /oauth/redirect?</span>\n<span class=\"grvsc-line\">client_id={client_id}</span>\n<span class=\"grvsc-line\">&redirect_uri={Callback URL}</span>\n<span class=\"grvsc-line\">&scope={Scope}</span>\n<span class=\"grvsc-line\">&response_type=code</span>\n<span class=\"grvsc-line\">&state={random long string}</span>\n<span class=\"grvsc-line\">&code_challenge={code challenge}</span>\n<span class=\"grvsc-line\">&code_challenge_method=SHA256</span></code></pre>\n<p>The provider should redirect you to the authentication/login page and where you’ll get the code after successful authentication.</p>\n<h3 id=\"code-exchange\" style=\"position:relative;\"><a href=\"#code-exchange\" aria-label=\"code exchange permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Code Exchange</h3>\n<p>In the code exchange request, we need to pass the code we have received through the above request and the code verifier that we have generated in our first step.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">POST Provider + /oauth/access_token</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">Request body:</span>\n<span class=\"grvsc-line\">{</span>\n<span class=\"grvsc-line\">   client_id:{client_id},</span>\n<span class=\"grvsc-line\">   client_secret:{client_secret},</span>\n<span class=\"grvsc-line\">   redirect_uri:{redirect_uri},</span>\n<span class=\"grvsc-line\">   response_type:token,</span>\n<span class=\"grvsc-line\">   Code:{code} // That we have received in authorization request</span>\n<span class=\"grvsc-line\">   code_verifier: {code verifier // generated in the first step</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>Once the code<em>verificer hash matches with the code</em>challenge of the authorization request, You will get the token in the response with status code 200 OK.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">{</span>\n<span class=\"grvsc-line\">    &quot;access_token&quot;: &quot;c5a****b-****-4*7f-a********e4a&quot;,</span>\n<span class=\"grvsc-line\">    &quot;token_type&quot;: &quot;access_token&quot;,</span>\n<span class=\"grvsc-line\">    &quot;refresh_token&quot;: &quot;5*****82-b***-**82-8c*1-*******7ce&quot;,</span>\n<span class=\"grvsc-line\">    &quot;expires_in&quot;: 11972</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>That's it and you've implemented PKCE flow in your application.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk5 { color: #D16969; }\n  .dark-default-dark .mtk6 { color: #D7BA7D; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n</style>","frontmatter":{"date":"September 03, 2020","updated_date":null,"description":"If you are working with OAuth and OIDC authorization code flow and want to setup PKCE flow then this article will help you to understand everything about PKCE.","title":"PKCE: What it is and how to use it with OAuth 2.0","tags":["PKCE","Oauth","OIDC"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/7ba5011bcf44e895dd050e8766d4d005/2a4de/pkce.png","srcSet":"/static/7ba5011bcf44e895dd050e8766d4d005/69585/pkce.png 200w,\n/static/7ba5011bcf44e895dd050e8766d4d005/497c6/pkce.png 400w,\n/static/7ba5011bcf44e895dd050e8766d4d005/2a4de/pkce.png 600w","sizes":"(max-width: 600px) 100vw, 600px"}}},"author":{"id":"Narendra Pareek","github":"pareek-narendra","avatar":null}}}},{"node":{"excerpt":"Big Data - Introduction Earlier, we were only dealing with well-structured data, hosted in large data warehouses, and investing a cost in…","fields":{"slug":"/engineering/big-data-testing-strategy/"},"html":"<h2 id=\"big-data---introduction\" style=\"position:relative;\"><a href=\"#big-data---introduction\" aria-label=\"big data   introduction permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Big Data - Introduction</h2>\n<p>Earlier, we were only dealing with well-structured data, hosted in large data warehouses, and investing a cost in maintaining those data warehouses and hiring expert professional to maintain and secure information hosted in that data warehouse. Data was structured and can be queried anything as per the needs. But now, this exponential growth of data generates a new vision for data science along with some major challenges.</p>\n<p><strong>Big Data</strong> is something which is growing exponentially with time, and carry raw but very valuable information inside that can change the future of any enterprise. It is a collection, which represents a large dataset, may be collected from multiple sources, or stored in an organization.\nLet‟s understand a real-time example, Big companies like Ikea and Amazon are leveraging the benefit of big data by collecting data from customer‟s buying patterns at their stores, their internal stock information, and their inventory demand-supply relations and analyze all, in seconds even in real-time to add value to its customer experience. </p>\n<p>So, extracting information from a large dataset somewhat calls a concept of Data mining which is an analytic process originally designed to explore large datasets. The ultimate goal of data mining is to search for consistency in a pattern or systematic relationship between variables, which helps in predicting the next pattern or behavior. </p>\n<p>Now, if we take concepts of data mining forward along with large data set, to some extent it becomes a blocker for our existing approach, because big data may contain structured or unstructured data even it may contain data in multiple formats also.</p>\n<h2 id=\"big-data-testing\" style=\"position:relative;\"><a href=\"#big-data-testing\" aria-label=\"big data testing permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Big Data Testing</h2>\n<p>Testing is an art of achieving quality in your software product, in terms of perfection of functionality, performance, user experience, or usability. But for big data testing, you need to keep your focus more on the functional and performance aspects of an application. Performance is the key parameter in any big data application which is meant to process terabytes of data. Successful processing of terabytes of data using a commodity cluster with a number of other supportive components needs to be verified. Processing should be faster and accurate which demands a high level of testing. </p>\n<p>Processing may be of three types:– </p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 356px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 91.57303370786518%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAIAAADUsmlHAAAACXBIWXMAABYlAAAWJQFJUiTwAAADHklEQVQ4y52UWUwTQRjHBwM++qKEgPWKgkZfjAaNeIVD8URAESLQ0hbkaKEVGkHFyCHdtrSKtIAWCiSIomhijNEI0Qcf8EpMIKkxrXJ0W7cIPZbtJd3dcdtGJMYH9csvM18m+c/8vy8zA6AXhwtB0/8AhIA2DHnNeo/jG+klmIW/JyDG0U+4SU+RfrflI9YnsOoKrF1sa2+htTuYdHN/p4eHaXPtwwhNk8CJTQYNUxSErmEloc1w6U4TXafcd4uddXG2MmCviLCXhy/gEC2dKQLO20dJah7YLOOhahknroEyonkHcSNxDtlKKOLxmiincImzPHwxuGiprQjg/UExYcNwq4l02+36l8br6UYkxSBLMcoPGpBko+KQUXnsd1THDciBqUEJSc4D5kxmwk1G86vHMzh0kZQbQjcNQyPhZ1agm4IeGnrgL9x+iqJowFjGHW7MZCP9FD5D9FXr1HmyNraijRNAJ1Bri1o0bIUmT67OlYVoPYN05Ku+jqEBsWVymqboYMvgi84XnbzWwdr+x9IHV/dd6C5ue6Z69KjxnianuTQyX7y2ULymUMgquBRXYXkzGRCj45jfTzJ6Jn/a8kSyqVR++IryeENl7NnzWwSX4ysb9lRf3CYqicwVxLCFMZySqNzqdaXoyERA7HF5p82zvjnXLOYYkN65JbyhFalvlbd2VbXrJO2dYo22Qq0Va3SSjhBdko6eqptmvQkwhTtcHnTcgL196vEx7km4KGj45whdUYBiVtT6jST9esOXI1zl7syGw/mK1Dx5YrZ0f1ZTGk+192RjUo50V3pdQkb9T+oSMqUjH6aACbMyO5HBbgnr+tiVuhr5w6qm+7zq3lROi6h+gCEhEwHL85as5gMWL2wVH8RwIjYIh15PgEmzhZFRwW5lV9yM3H4uNvFSzE7JxuRaVsL5FdvEcUm1yzYLQDQnjMUFK7lhLB6IZoevFzxnGjaNfp4yjLm++9+N6nPKlGlcJJ0vS+fLT3BlGXxZZpEirQA5ebY5p0yVXfqLrOJr70fHATQ899lQwjvv83nhP0TgXQJ63vO/fwH8AabUCPldraOGAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Batch, Real Time, Interactive\"\n        title=\"Batch, Real Time, Interactive\"\n        src=\"/static/9458f354fd26eed7b520607d437ca40e/50ac3/BigDataTesting-2.png\"\n        srcset=\"/static/9458f354fd26eed7b520607d437ca40e/50ac3/BigDataTesting-2.png 356w\"\n        sizes=\"(max-width: 356px) 100vw, 356px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>And based on which, we need to integrate different components along with NoSQL data store as per the needs.</p>\n<h2 id=\"big-data-testing---test-data\" style=\"position:relative;\"><a href=\"#big-data-testing---test-data\" aria-label=\"big data testing   test data permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Big Data Testing - Test Data</h2>\n<p>Data plays a vital role in the testing of big data applications. Application is meant to process data and provide an expected output based on implemented logic. The logic needs to be verified before moving to production, as the implementation of logic is completely based on business requirements and data.</p>\n<p><strong>1. Test Data Quality</strong></p>\n<p>Good quality test data is as important as the test environment. In the big data world, data can have any format or size, it may be in the form of a document, XML, JSON, PDF, etc. at the same time data size may go up to terabytes of petabytes. Hence, test data should also have multiple formats and size should be large enough to ensure the handling of large data processing. In big data testing, it needs data with logical values as per the application requirement and format which is supported by the application. </p>\n<p>Along with it, data quality is another aspect of big data testing. Ensuring the quality of data before processing through application ensures the accuracy of the final output. Data quality testing itself is a huge domain and covers a lot of best practices which include – data completeness, conformity, accuracy, validity, duplication, and consistency, etc. It should be included in the big data testing and this ensures the level of accuracy application is supposed to provide.</p>\n<p><strong>2. Test Data Generation</strong></p>\n<p>The generation of test data is again a challenging job, there are multiple parameters, which have to be taken care of while generating test data. It needs a tool, which can help to generate data and should have functions or logic can also be applied over it. Tools like Talend (an open studio) is the best candidate to fulfill the requirements of data generation.</p>\n<p><strong>3. Data Storage</strong></p>\n<p>After the generation of test data along with quality, it needs to host on a file system. For testing big data applications, data should be stored in the system similar to the production environment. As we are working in big data space, there should have a different number of nodes, and data must be in a distributed environment.</p>\n<h2 id=\"big-data-testing---test-environment\" style=\"position:relative;\"><a href=\"#big-data-testing---test-environment\" aria-label=\"big data testing   test environment permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Big Data Testing - Test Environment</h2>\n<p>In Big data testing, the test environment should be efficient enough to process a large amount of data as done in the case of a production environment. Real-time production environment clusters generally have 30-40 nodes of cluster and data is distributed on the cluster nodes. There must have some minimum configuration for each node used in the cluster. A cluster may have two modes, in-premise or cloud. For testing in big data, it needs the same kind of environment with some minimum configuration of node.</p>\n<p>Scalability is also desired to be there in the test environment of big data testing, it helps to study the performance of application with the increase in the number of resources. That data can be used to define SLA (service level agreement) for that particular application.</p>\n<p><strong>Big Data Testing can be categorized into three stages:</strong></p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 88.92307692307693%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAIAAADUsmlHAAAACXBIWXMAABYlAAAWJQFJUiTwAAADVUlEQVQ4y0WRS4/jRBDH/a34BghxQ4ILFyRYARIfggMnJA4r7R5Wo0UsIA0SAi2CaBC7k0lmM8k8sgnJzMRJJrGdOG673W6/3X67TSWZZUul7upW/br+VS1M5yfi7MVg2Bj+2xiNjwbDv8Y3R/PFaRzH9c4sS5eU3q3Ymogn02l7Orv38fVLwcCXdX2XV1NNP8PkIq9EXs8sOmQs2sMYqwEbUucKk3NCLxyvb1rn1LmUV01hKbc3qKMbPQ2dgW/QmW72lvKrJLmvTIgG2N2iORo3BsM/Z/OXs/kLcfqPtGoLG9SDssBLyslCauq4V3ARGZcsZveVzU2YjCz7CgogowsPQQ51+gj3hJW6VbvROkjvYvNChcDoSkonfgMbxjqMx4Re6vjcsvvUfa2iju2+Bo0CyJDkprxqKavWenOqrNuy0pSU0/9lU4r8YAAdrdXTxfIYEgzcBSGACBOxZVoDhK+QsXVNv8TWYHrXURTZNE1KbVG8VjbnyOiL09Zg+Pfo+lhag4rBzeRYCMLIdj3X84Mg3HrEIhbLt7fiZNJoHL3qdCfja7SUWJJFLIGVeXagLwPfjyIm0Ch24pSyJEpzEFnlcagqzKGapsp3orKc6TpipsE0uS7h8zhPvMpe1kUCyYIVRpxzlmVenNaBVgVm6Wo8tmrw3KkTUkdmFZEiIHXmV4HB07B0VnwPEz+cTCY6sVwvKJ1NnBcZGFVzR4eZZQnLHFS6hiLLq5XKfSO1jdSS7mHddprHTWmtEmwybd7rdm/GoxTLoboYDQdz8SYxVxlZd9qtfv+KO8iWZpY8qst0C5uuL8sKwiSEnkOzrOqyLCqQGtscgiypIoszalPL9/w6sqrEfysbO55FCHHcIMlKd5MFNPPN3DdyT08tOTGXhY9zH5c+Knyj8HSeBm9hK9gNLM1cGFiRAJyHlO9UVWVZVSUEvAIFLGVhBZexV5AZz/c9O55KqErsKM32ebyssjRNYpanKThEcK7LAr4JEsosjh0EeVsYrkrosijgoBj4vW8P3n/40xfPnn/54x+fPP3t0+9/f/DD8w8eH77z9aOL6WIrp+L1GxP2W7V7VcXmR98dfPjw2WdPDr96+uuDJ4efH/wC68ePf373m0f92XIHQ817/j9I9cMvGRItTQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Big Data Testing - Phases\"\n        title=\"Big Data Testing - Phases\"\n        src=\"/static/8651aa9cd003c1bfdc5218e858b6dc5a/e5715/BigDataTesting-1.png\"\n        srcset=\"/static/8651aa9cd003c1bfdc5218e858b6dc5a/a6d36/BigDataTesting-1.png 650w,\n/static/8651aa9cd003c1bfdc5218e858b6dc5a/e5715/BigDataTesting-1.png 768w,\n/static/8651aa9cd003c1bfdc5218e858b6dc5a/d2a60/BigDataTesting-1.png 807w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p><strong>Step 1: Data Staging Validation</strong></p>\n<p>The first stage of big data testing, also known as a Pre-Hadoop stage, is comprised of process validation.</p>\n<ol>\n<li>Validation of data is very important so that the data collected from various source like RDBMS, weblogs, etc are verified and then added to the system.</li>\n<li>To ensure data match you should compare source data with the data added to the  <a href=\"https://en.wikipedia.org/wiki/Apache_Hadoop\">Hadoop</a>  system.</li>\n<li>Make sure that the right data is taken out and loaded into the accurate HDFS location</li>\n</ol>\n<p><strong>Step 2: “Map Reduce” Validation</strong></p>\n<p>Validation of “Map Reduce” is the second stage. Business logic validation on every node is performed by the tester. Post that authentication is done by running them against multiple nodes, to make sure that the:</p>\n<ul>\n<li>The process of Map Reduce works perfectly.</li>\n<li>On the data, the data aggregation or segregation rules are imposed.</li>\n<li>Creation of key-value pairs is there.</li>\n<li>After the Map-Reduce process, Data validation is done.</li>\n</ul>\n<p><strong>Step 3: Output Validation Phase</strong></p>\n<p>The output validation process is the final or third stage involved in big data testing. The output data files are created and they are ready to be moved to an  <strong>EDW (Enterprise Data Warehouse)</strong>  or any other such system as per requirements. The third stage consisted of:</p>\n<ul>\n<li>Checking on the transformation rules is accurately applied.</li>\n<li>In the target system, it needs to ensure that data is loaded successfully and the integrity of data is maintained.</li>\n<li>By comparing the target data with the  <strong>HDFS file system data</strong>, it is checked that there is no data corruption.</li>\n</ul>\n<h2 id=\"big-data---performance-testing\" style=\"position:relative;\"><a href=\"#big-data---performance-testing\" aria-label=\"big data   performance testing permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Big Data - Performance Testing</h2>\n<p>Big data applications are meant to process a large amount of data, and it is expected that it should take minimum time to process maximum data. Along with it, application jobs should consume a considerable amount of memory and CPU. In big data testing, performance parameter plays an important role and helps to define SLA's. It covers the performance of the base machine and cluster. Also, for example, In the case of Hadoop, map-reduce jobs should be written with proper coding guidelines, to perform better in the production environment. Profiling can also be done on map-reduce jobs before integration, to ensure their optimized execution.</p>\n<h2 id=\"tools-used-in-big-data-scenarios\" style=\"position:relative;\"><a href=\"#tools-used-in-big-data-scenarios\" aria-label=\"tools used in big data scenarios permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Tools used in Big Data Scenarios</h2>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 73.6923076923077%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAABYlAAAWJQFJUiTwAAABhklEQVQoz4WTzXaCMBCF8/4PV7tpVwoewcQYIBBAQP56MyNIy6Lf0ThJSObOHRQfxOHw+f39dVgIwkBKef0PcT6HQRAcj8cwDE+nU0CfOI611kqp2w5eUoTQ+p5lWd/3z+ezbdsHUVVVWZYV/VQ7ymVRQN1N667rcLgoCkVq8Y3jKxJcLtFVSqTCMmdDjC0lKfNMjOOIw8MwIJ7mFxPBwTryxugZRBRFKNWYBIs4D0GsvK5r1s8TDmpSi4DTCH4C1WKCMU1Tm+dFDlBEgWlO2NwWzuW0hfW+p8NcLW6CZ5Ay71jVjht6wrcKfUJOXIGLfXvJG2+bVOiZJBA4VyJTS3SEwAVIzZOmabYd2bYK7cFu9xtRV7CmZmNZ0jS9Z9P8ina7Hv+SAK7q8WgQQ3zmSa21GI25p1mKdWtz+LO1Q6yubG9dk4xLNFL4xzkBY85hiD6jeOhHWlcQ7vWLarlbzjlowfiuGdtJkqB5cBt+6ps2EOqLMb6eu0GrFb2NJknwh8DDi9ndD828U5pz6ajAAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Big Data Scenarios - Tools\"\n        title=\"Big Data Scenarios - Tools\"\n        src=\"/static/726542cf06d2ab94260b40278ec5c4ca/e5715/BigDataTesting-3.png\"\n        srcset=\"/static/726542cf06d2ab94260b40278ec5c4ca/a6d36/BigDataTesting-3.png 650w,\n/static/726542cf06d2ab94260b40278ec5c4ca/e5715/BigDataTesting-3.png 768w,\n/static/726542cf06d2ab94260b40278ec5c4ca/42de8/BigDataTesting-3.png 1033w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h2 id=\"big-data-testing---challenges\" style=\"position:relative;\"><a href=\"#big-data-testing---challenges\" aria-label=\"big data testing   challenges permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Big Data Testing - Challenges</h2>\n<p>In big data testing, certain challenges are involved which needs to be addressed by the big data testing approach.</p>\n<p><strong>1. Test Data</strong></p>\n<p>Exponential growth had been observed in the growth of data in the last few years. A huge amount of data are being generated daily and stored in large data centers or data marts. So, there is a demand for efficient storage and a way to process it in an optimized way. If we consider the telecom industry, it generates a large number of call logs daily and they need to be processed for better customer experience and compete in the market. The same goes with the test data, test data should be similar to production data and should contain all the logically acceptable fields in it. </p>\n<p>This becomes a challenge for testing big data application, generating test data similar to production data is a real challenge. Test data should also be large enough to verify proper working big data application.</p>\n<p><strong>2. Environment</strong></p>\n<p>The processing of data highly depends on the environment and its performance. An optimized environment setup gives high performance and fast data processing results. Distributed computing is used for the processing of big data which has data hosted in a distributed environment. The testing environment should have multiple numbers of nodes and data should be distributed over the nodes. At the same time, it also needs to monitor those nodes, to ensure the highest performance with minimum CPU and memory utilization. Nodes should be monitored and there should have a graphical presentation of node performance. So, the test environment has two aspects – distributed nodes and their monitoring, which should be covered in the testing approach.</p>\n<p><strong>3. Performance</strong></p>\n<p>Performance is the key requirement of any big data application, and of course because of which enterprises are moving towards NoSQL technologies, technologies that can handle their big data and process in the minimum time frame. A large dataset should be processed in a minimum considerable time frame. In big data testing, performance testing is a challenge, it requires monitoring of cluster nodes during execution and also time is taken for every iteration of execution.</p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>Big Data is the trend that is revolutionizing society and its organizations due to the capabilities it provides to take advantage of a wide variety of data, in large volumes and with speed. Keeping the challenges in mind we have defined the approach of testing big data applications. This approach of big data testing will make it easy for a test engineer to verify and certify the business requirement implementations and for stack holders, it saves a huge amount of cost, which has to be invested to get the expected business returns.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"September 02, 2020","updated_date":null,"description":"With the exponential growth in the number of big data applications in the world, Testing in big data applications is related to database, infrastructure and performance testing and functional testing. This blog guides what should be the strategy for testing Big Data applications.","title":"Big Data - Testing Strategy","tags":["Testing","Big Data","Big Data Testing"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/370acda0a8a364ef7098ce2df0537d12/ee604/big-data.png","srcSet":"/static/370acda0a8a364ef7098ce2df0537d12/69585/big-data.png 200w,\n/static/370acda0a8a364ef7098ce2df0537d12/497c6/big-data.png 400w,\n/static/370acda0a8a364ef7098ce2df0537d12/ee604/big-data.png 800w,\n/static/370acda0a8a364ef7098ce2df0537d12/f3583/big-data.png 1200w,\n/static/370acda0a8a364ef7098ce2df0537d12/5707d/big-data.png 1600w,\n/static/370acda0a8a364ef7098ce2df0537d12/eeb1b/big-data.png 1920w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Sudhey Sharma","github":"sudheysharma","avatar":null}}}},{"node":{"excerpt":"Introduction Authentication is the necessary implementation for secure and genuine access to resources of web and mobile applications. It…","fields":{"slug":"/engineering/email-verification-api/"},"html":"<h2 id=\"introduction\" style=\"position:relative;\"><a href=\"#introduction\" aria-label=\"introduction permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Introduction</h2>\n<p>Authentication is the necessary implementation for secure and genuine access to resources of web and mobile applications. It helps to authorize the user and provide access control for applications based on the user’s credentials. </p>\n<p>There are various authentication mechanisms like Email, Phone numbers, Biometrics, etc. However, Email is still considered the primary means of authentication because other mechanisms are not as optimized or in approach to everyone. </p>\n<p>So it is safe to say that most of your application users used email for creating their accounts. With that, some users tend to use disposable email services for fake account creation. These fake accounts result in additional liability to your application resources and servers.</p>\n<p>You can effectively reduce such spams for your applications by analyzing the user’s email address during registration for the following aspects:</p>\n<ul>\n<li>Email is valid or not.</li>\n<li>Email is disposable or not.</li>\n<li>Email is deliverable or not.</li>\n</ul>\n<p>There are some tools available that could help you analyze the above factors, and one such tool is <a href=\"https://eva.pingutil.com\">EVA</a>, an Email Verification API. It is a free API and analyzes the user’s email for all of the factors mentioned above. </p>\n<h3 id=\"api-details\" style=\"position:relative;\"><a href=\"#api-details\" aria-label=\"api details permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>API Details</h3>\n<p>The details of Email Verification API (API) is as follows:</p>\n<table>\n<thead>\n<tr>\n<th>Parameters</th>\n<th>Value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>URL</td>\n<td><code>https://api.eva.pingutil.com/email</code></td>\n</tr>\n<tr>\n<td>Query Param</td>\n<td><code>{ email: test@mail7.io }</code></td>\n</tr>\n<tr>\n<td>Response</td>\n<td><code>{ \"status\": \"success\", \"data\": { \"email_address\": \"test@mail7.io\", \"domain\": \"mail7.io\", \"valid_syntax\": true, \"disposable\": true, \"deliverable\": true }}</code></td>\n</tr>\n</tbody>\n</table>\n<p>Valid_syntax, disposable, and deliverable are three attributes of this API, let’s see how these works:</p>\n<h4 id=\"output-parameters\" style=\"position:relative;\"><a href=\"#output-parameters\" aria-label=\"output parameters permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Output Parameters:</h4>\n<p><code>valid_syntax</code>\nThis attribute verifies the syntax of the entered email address matches the standard email address format or not. It is useful in the cases where the end-user might misspell email addresses while typing.</p>\n<p><code>disposable</code>\nThis attribute verifies whether the entered email address domain belongs to the disposable email service. EVA checks the email address against a valid database of more than 4500 disposable email services. Thus, it can effectively help the developer to prevent users from registering using disposable email.</p>\n<p><code>deliverable</code>\nThis attribute verifies whether the email domain has valid MX records or not. The email address is considered deliverable if the valid MX record for the email domain is found.</p>\n<blockquote>\n<p><strong>Note</strong>: A mail exchanger record (MX record) specifies the mail server responsible for accepting email messages on behalf of a domain name. It is a resource record in the Domain Name System (DNS). </p>\n</blockquote>\n<p>The response received for the above three attributes of API can help you take further action. These attributes are not just limited to registration use cases, you can utilize them for other use cases like if you have an existing user base but would like to limit the spammers (who have registered using disposable emails) from commenting on the blog or accessing your application resources.</p>\n<p><em>This API tool has been developed and designed as a way of giving back to the developer community initiative by LoginRadius Developers. Your opinion is important to us. This way we can keep improving our product for the developer community. Please share your feedback <a href=\"https://docs.google.com/forms/d/e/1FAIpQLSfa76A9ES0wvIF0_I7ebLAFugVhhDKB7em-WPbMjHPj1w7mOw/viewform\">here</a></em></p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"August 31, 2020","updated_date":null,"description":"Email authentication, being the traditional way of authentication and used most widely. Increase in the spams has also increased the disposable email registrations. To reduce and identify such unwanted users, EVA(Email Verification API) is the tool, developed by LoginRadius developers.","title":"Email Verification API (EVA)","tags":["Free tool","Developer Resources ","Verification","Email"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/4991e427faf331bcbd24d1c66c1cad40/ee604/eva.png","srcSet":"/static/4991e427faf331bcbd24d1c66c1cad40/69585/eva.png 200w,\n/static/4991e427faf331bcbd24d1c66c1cad40/497c6/eva.png 400w,\n/static/4991e427faf331bcbd24d1c66c1cad40/ee604/eva.png 800w,\n/static/4991e427faf331bcbd24d1c66c1cad40/f3583/eva.png 1200w,\n/static/4991e427faf331bcbd24d1c66c1cad40/e4d72/eva.png 1280w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Aman Agrawal","github":"aman-agrwl","avatar":null}}}},{"node":{"excerpt":"In this blog, we learn how to implement the AntiXssMiddleware in .NET Core. First, we will understand about the cross-site scripting. Cross…","fields":{"slug":"/engineering/anti-xss-middleware-asp-core/"},"html":"<p>In this blog, we learn how to implement the <strong>AntiXssMiddleware</strong> in .NET Core. First, we will understand about the cross-site scripting.</p>\n<h2 id=\"cross-site-scriptingxss\" style=\"position:relative;\"><a href=\"#cross-site-scriptingxss\" aria-label=\"cross site scriptingxss permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Cross-Site Scripting(XSS)</h2>\n<p>Cross-site scripting is a security vulnerability and a client-side code injection attack. In this attack, the malicious script is injected into legitimate websites.\nCross-site scripting allows an attacker to act like a victim user and to carry out the actions that the user can perform. The attacker can access the user's data as well.</p>\n<h2 id=\"implement-antixssmiddleware-in-net-core\" style=\"position:relative;\"><a href=\"#implement-antixssmiddleware-in-net-core\" aria-label=\"implement antixssmiddleware in net core permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Implement AntiXssMiddleware in .NET Core</h2>\n<p><strong>Step 1:</strong> Create Asp.NET Core Web Application project in Visual Studio.</p>\n<p><strong>Step 2:</strong> Select type as API in the next step and create the project. You will find a default controller which is created in the controller folder named as <strong>WeatherForecastController.cs</strong></p>\n<p><strong>Step 3:</strong> Now create a new folder named Middleware in the root directory.</p>\n<p><strong>Step 4 :</strong> Create a new file <strong>AntiXssMiddleware.cs</strong> in that Middleware folder.</p>\n<p><strong>Step 5:</strong> Now add the Newtonsoft.json package into your solution</p>\n<p>By doing the above steps you will have below structure in your solution. </p>\n<p><span class=\"gatsby-resp-image-wrapper\" style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 545px; \">\n      <span class=\"gatsby-resp-image-background-image\" style=\"padding-bottom: 99.26605504587155%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAABJ0AAASdAHeZh94AAAC5klEQVQ4y42T2U7bQBSG/aSt1AC9QirLS/QCLtpCKfAelUpTKqAQCAkhwdm879uM7Sy243V6nFBUBaRW+jSyZ/TP+c8/M1Tr6y57ujuo7vS+vdevPuDGPrrdA5z6J6f+Ed3uu80D+MbNz7hRYt3s2bWd9snB2tYhdXqt1ju4eslVz7u1lvmraZ7VtZ816fsFc1qTftTEi4Z5cs6c1ZXb7qjRGwNtNqxe6Subh1SPUTUDyZqt6I6k2opqw69mYG8U+uOZN4oWuH7ojSMAJg0LN9vC6vYx9UDLHKeKsqFoNscrDCeyvCKImm5h0/YME4mSjv0giosgyoFJmCUpYQS0unlEKYrD6ui+0221WreNZu36pnXfNgwrzYo4yeI4jWZxkmRZVixIkpwQwkvozbsjaiAHmktoxrzvG/WOekdrzQe9w2DFyTVMNFQ8jn9QndzySavvrW4dUfVeeDeMOn25ejmo1pTqlVjv+n2V0GJBS4SWijnkiQexgNWLO28FbGM/TNPM9Sc8S6uqxvECeE7SHGy/SJyWtiXVLXs2URmGg8d0j+dFbcCIFhqHMQGCWRE+YxrmWU4GnFPZOKYsFCQZcf1AlPUHejDkJEW1VM02LFc3HAgctv6bcFaKBcVbg55B7I9DKCorRn8oqAaC5SDK4FTgA1gSByAuIG13deuYsnE4mkQetnXLZnkZThVcLPCAcQQbLYnzojznChwViKdh6rmubOgML3GCopvYtFxzbhvMw+qSbYhMVP232/PKcBNHHi7FnDRgBBAjd4K9YJaUDv/RM+wkSIasm2Cbnet7fbY/4OGSIjyZJeTFnisbXx7TZlhpyIpDVoLisIU/b3U0nS15fhKzEq5sQGVcpq27jqjo8CR0A0dxHqeLasueF8+jIKTLWK/Wy8DKVA0PMZxAdxl4W64/hQcI9+G5ciGGK9Zjrdfrh6XtIEr9IDQdDxK20QgSdtDoReULYugZZsFqnJFynPM/4t/yJDQqMYy44AAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"></span>\n  <img class=\"gatsby-resp-image-image\" alt=\"Solution Structure\" title=\"Solution Structure\" src=\"/static/187a28fdf9137d82de1c19e817bd8e99/3ddad/SolutionArch.png\" srcset=\"/static/187a28fdf9137d82de1c19e817bd8e99/3ddad/SolutionArch.png 545w\" sizes=\"(max-width: 545px) 100vw, 545px\" style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\" loading=\"lazy\">\n    </span></p>\n<p><strong>Step 6:</strong> Now edit the AntiXssMiddlewars.cs file and paste below code.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">System</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">System</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Collections</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Generic</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">System</span><span class=\"mtk1\">.</span><span class=\"mtk10\">IO</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">System</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Linq</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">System</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Net</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">System</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Text</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">System</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Text</span><span class=\"mtk1\">.</span><span class=\"mtk10\">RegularExpressions</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">System</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Threading</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Tasks</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Microsoft</span><span class=\"mtk1\">.</span><span class=\"mtk10\">AspNetCore</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Builder</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Microsoft</span><span class=\"mtk1\">.</span><span class=\"mtk10\">AspNetCore</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Http</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Newtonsoft</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Json</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">namespace</span><span class=\"mtk1\"> </span><span class=\"mtk10\">AntiXssMiddleware</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Middleware</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">AntiXssMiddleware</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk4\">readonly</span><span class=\"mtk1\"> </span><span class=\"mtk10\">RequestDelegate</span><span class=\"mtk1\"> </span><span class=\"mtk12\">_next</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk10\">ErrorResponse</span><span class=\"mtk1\"> </span><span class=\"mtk12\">_error</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk4\">readonly</span><span class=\"mtk1\"> </span><span class=\"mtk4\">int</span><span class=\"mtk1\"> </span><span class=\"mtk12\">_statusCode</span><span class=\"mtk1\"> = (</span><span class=\"mtk4\">int</span><span class=\"mtk1\">)</span><span class=\"mtk12\">HttpStatusCode</span><span class=\"mtk1\">.</span><span class=\"mtk12\">BadRequest</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk11\">AntiXssMiddleware</span><span class=\"mtk1\">(</span><span class=\"mtk10\">RequestDelegate</span><span class=\"mtk1\"> </span><span class=\"mtk12\">next</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">_next</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">next</span><span class=\"mtk1\"> ?? </span><span class=\"mtk15\">throw</span><span class=\"mtk1\"> </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">ArgumentNullException</span><span class=\"mtk1\">(</span><span class=\"mtk4\">nameof</span><span class=\"mtk1\">(</span><span class=\"mtk12\">next</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Task</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Invoke</span><span class=\"mtk1\">(</span><span class=\"mtk10\">HttpContext</span><span class=\"mtk1\"> </span><span class=\"mtk12\">context</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk3\">// Check XSS in URL</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (!</span><span class=\"mtk12\">string</span><span class=\"mtk1\">.</span><span class=\"mtk11\">IsNullOrWhiteSpace</span><span class=\"mtk1\">(</span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Request</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Path</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Value</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">url</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Request</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Path</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Value</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">CrossSiteScriptingValidation</span><span class=\"mtk1\">.</span><span class=\"mtk11\">IsDangerousString</span><span class=\"mtk1\">(</span><span class=\"mtk12\">url</span><span class=\"mtk1\">, </span><span class=\"mtk4\">out</span><span class=\"mtk1\"> </span><span class=\"mtk7\">_</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk4\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">RespondWithAnError</span><span class=\"mtk1\">(</span><span class=\"mtk12\">context</span><span class=\"mtk1\">).</span><span class=\"mtk11\">ConfigureAwait</span><span class=\"mtk1\">(</span><span class=\"mtk4\">false</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk15\">return</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk3\">// Check XSS in query string</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (!</span><span class=\"mtk12\">string</span><span class=\"mtk1\">.</span><span class=\"mtk11\">IsNullOrWhiteSpace</span><span class=\"mtk1\">(</span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Request</span><span class=\"mtk1\">.</span><span class=\"mtk12\">QueryString</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Value</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">queryString</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">WebUtility</span><span class=\"mtk1\">.</span><span class=\"mtk11\">UrlDecode</span><span class=\"mtk1\">(</span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Request</span><span class=\"mtk1\">.</span><span class=\"mtk12\">QueryString</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Value</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">CrossSiteScriptingValidation</span><span class=\"mtk1\">.</span><span class=\"mtk11\">IsDangerousString</span><span class=\"mtk1\">(</span><span class=\"mtk12\">queryString</span><span class=\"mtk1\">, </span><span class=\"mtk4\">out</span><span class=\"mtk1\"> </span><span class=\"mtk7\">_</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk4\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">RespondWithAnError</span><span class=\"mtk1\">(</span><span class=\"mtk12\">context</span><span class=\"mtk1\">).</span><span class=\"mtk11\">ConfigureAwait</span><span class=\"mtk1\">(</span><span class=\"mtk4\">false</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk15\">return</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk3\">// Check XSS in request content</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">originalBody</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Request</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Body</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">try</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">ReadRequestBody</span><span class=\"mtk1\">(</span><span class=\"mtk12\">context</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">CrossSiteScriptingValidation</span><span class=\"mtk1\">.</span><span class=\"mtk11\">IsDangerousString</span><span class=\"mtk1\">(</span><span class=\"mtk12\">content</span><span class=\"mtk1\">, </span><span class=\"mtk4\">out</span><span class=\"mtk1\"> </span><span class=\"mtk7\">_</span><span class=\"mtk1\">)) </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk4\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">RespondWithAnError</span><span class=\"mtk1\">(</span><span class=\"mtk12\">context</span><span class=\"mtk1\">).</span><span class=\"mtk11\">ConfigureAwait</span><span class=\"mtk1\">(</span><span class=\"mtk4\">false</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk15\">return</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk4\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">_next</span><span class=\"mtk1\">(</span><span class=\"mtk12\">context</span><span class=\"mtk1\">).</span><span class=\"mtk11\">ConfigureAwait</span><span class=\"mtk1\">(</span><span class=\"mtk4\">false</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">finally</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Request</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Body</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">originalBody</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk4\">static</span><span class=\"mtk1\"> </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Task</span><span class=\"mtk1\">&lt;</span><span class=\"mtk4\">string</span><span class=\"mtk1\">&gt; </span><span class=\"mtk11\">ReadRequestBody</span><span class=\"mtk1\">(</span><span class=\"mtk10\">HttpContext</span><span class=\"mtk1\"> </span><span class=\"mtk12\">context</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">buffer</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">MemoryStream</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Request</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Body</span><span class=\"mtk1\">.</span><span class=\"mtk11\">CopyToAsync</span><span class=\"mtk1\">(</span><span class=\"mtk12\">buffer</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Request</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Body</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">buffer</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">buffer</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Position</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">0</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">encoding</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">Encoding</span><span class=\"mtk1\">.</span><span class=\"mtk12\">UTF8</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">requestContent</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">await</span><span class=\"mtk1\"> </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">StreamReader</span><span class=\"mtk1\">(</span><span class=\"mtk12\">buffer</span><span class=\"mtk1\">, </span><span class=\"mtk12\">encoding</span><span class=\"mtk1\">).</span><span class=\"mtk11\">ReadToEndAsync</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Request</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Body</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Position</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">0</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">requestContent</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk4\">async</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Task</span><span class=\"mtk1\"> </span><span class=\"mtk11\">RespondWithAnError</span><span class=\"mtk1\">(</span><span class=\"mtk10\">HttpContext</span><span class=\"mtk1\"> </span><span class=\"mtk12\">context</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Response</span><span class=\"mtk1\">.</span><span class=\"mtk11\">Clear</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Headers</span><span class=\"mtk1\">.</span><span class=\"mtk11\">AddHeaders</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">ContentType</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;application/json; charset=utf-8&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">StatusCode</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">_statusCode</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">_error</span><span class=\"mtk1\"> == </span><span class=\"mtk4\">null</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">_error</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">ErrorResponse</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">Description</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;Error from AntiXssMiddleware&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">ErrorCode</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">500</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">context</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Response</span><span class=\"mtk1\">.</span><span class=\"mtk11\">WriteAsync</span><span class=\"mtk1\">(</span><span class=\"mtk12\">_error</span><span class=\"mtk1\">.</span><span class=\"mtk11\">ToJSON</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">static</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">AntiXssMiddlewareExtension</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">static</span><span class=\"mtk1\"> </span><span class=\"mtk10\">IApplicationBuilder</span><span class=\"mtk1\"> </span><span class=\"mtk11\">UseAntiXssMiddleware</span><span class=\"mtk1\">(</span><span class=\"mtk4\">this</span><span class=\"mtk1\"> </span><span class=\"mtk10\">IApplicationBuilder</span><span class=\"mtk1\"> </span><span class=\"mtk12\">builder</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">builder</span><span class=\"mtk1\">.</span><span class=\"mtk11\">UseMiddleware</span><span class=\"mtk1\">&lt;</span><span class=\"mtk10\">AntiXssMiddleware</span><span class=\"mtk1\">&gt;();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">/// </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">summary</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">/// Imported from System.Web.CrossSiteScriptingValidation Class</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">/// </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">summary</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">static</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">CrossSiteScriptingValidation</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk4\">static</span><span class=\"mtk1\"> </span><span class=\"mtk4\">readonly</span><span class=\"mtk1\"> </span><span class=\"mtk4\">char</span><span class=\"mtk1\">[] </span><span class=\"mtk12\">StartingChars</span><span class=\"mtk1\"> = { </span><span class=\"mtk8\">&#39;&lt;&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;&&#39;</span><span class=\"mtk1\"> };</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">        #region </span><span class=\"mtk8\">Public methods</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">static</span><span class=\"mtk1\"> </span><span class=\"mtk4\">bool</span><span class=\"mtk1\"> </span><span class=\"mtk11\">IsDangerousString</span><span class=\"mtk1\">(</span><span class=\"mtk4\">string</span><span class=\"mtk1\"> </span><span class=\"mtk12\">s</span><span class=\"mtk1\">, </span><span class=\"mtk4\">out</span><span class=\"mtk1\"> </span><span class=\"mtk4\">int</span><span class=\"mtk1\"> </span><span class=\"mtk12\">matchIndex</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk3\">//bool inComment = false;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">matchIndex</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">0</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">for</span><span class=\"mtk1\"> (</span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">0</span><span class=\"mtk1\">; ;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            {</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk3\">// Look for the start of one of our patterns </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">n</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">s</span><span class=\"mtk1\">.</span><span class=\"mtk11\">IndexOfAny</span><span class=\"mtk1\">(</span><span class=\"mtk12\">StartingChars</span><span class=\"mtk1\">, </span><span class=\"mtk12\">i</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk3\">// If not found, the string is safe</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">n</span><span class=\"mtk1\"> &lt; </span><span class=\"mtk7\">0</span><span class=\"mtk1\">) </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">false</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk3\">// If it&#39;s the last char, it&#39;s safe </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">n</span><span class=\"mtk1\"> == </span><span class=\"mtk12\">s</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Length</span><span class=\"mtk1\"> - </span><span class=\"mtk7\">1</span><span class=\"mtk1\">) </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">false</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">matchIndex</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">n</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">switch</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">s</span><span class=\"mtk1\">[</span><span class=\"mtk12\">n</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk15\">case</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;&lt;&#39;</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk3\">// If the &lt; is followed by a letter or &#39;!&#39;, it&#39;s unsafe (looks like a tag or HTML comment)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk11\">IsAtoZ</span><span class=\"mtk1\">(</span><span class=\"mtk12\">s</span><span class=\"mtk1\">[</span><span class=\"mtk12\">n</span><span class=\"mtk1\"> + </span><span class=\"mtk7\">1</span><span class=\"mtk1\">]) || </span><span class=\"mtk12\">s</span><span class=\"mtk1\">[</span><span class=\"mtk12\">n</span><span class=\"mtk1\"> + </span><span class=\"mtk7\">1</span><span class=\"mtk1\">] == </span><span class=\"mtk8\">&#39;!&#39;</span><span class=\"mtk1\"> || </span><span class=\"mtk12\">s</span><span class=\"mtk1\">[</span><span class=\"mtk12\">n</span><span class=\"mtk1\"> + </span><span class=\"mtk7\">1</span><span class=\"mtk1\">] == </span><span class=\"mtk8\">&#39;/&#39;</span><span class=\"mtk1\"> || </span><span class=\"mtk12\">s</span><span class=\"mtk1\">[</span><span class=\"mtk12\">n</span><span class=\"mtk1\"> + </span><span class=\"mtk7\">1</span><span class=\"mtk1\">] == </span><span class=\"mtk8\">&#39;?&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk15\">break</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk15\">case</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;&&#39;</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk3\">// If the & is followed by a #, it&#39;s unsafe (e.g. S) </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">s</span><span class=\"mtk1\">[</span><span class=\"mtk12\">n</span><span class=\"mtk1\"> + </span><span class=\"mtk7\">1</span><span class=\"mtk1\">] == </span><span class=\"mtk8\">&#39;#&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk15\">break</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk3\">// Continue searching</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">n</span><span class=\"mtk1\"> + </span><span class=\"mtk7\">1</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">        #endregion</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">        #region </span><span class=\"mtk8\">Private methods</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk4\">static</span><span class=\"mtk1\"> </span><span class=\"mtk4\">bool</span><span class=\"mtk1\"> </span><span class=\"mtk11\">IsAtoZ</span><span class=\"mtk1\">(</span><span class=\"mtk4\">char</span><span class=\"mtk1\"> </span><span class=\"mtk12\">c</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">c</span><span class=\"mtk1\"> &gt;= </span><span class=\"mtk8\">&#39;a&#39;</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">c</span><span class=\"mtk1\"> &lt;= </span><span class=\"mtk8\">&#39;z&#39;</span><span class=\"mtk1\">) || (</span><span class=\"mtk12\">c</span><span class=\"mtk1\"> &gt;= </span><span class=\"mtk8\">&#39;A&#39;</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">c</span><span class=\"mtk1\"> &lt;= </span><span class=\"mtk8\">&#39;Z&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">        #endregion</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">static</span><span class=\"mtk1\"> </span><span class=\"mtk4\">void</span><span class=\"mtk1\"> </span><span class=\"mtk11\">AddHeaders</span><span class=\"mtk1\">(</span><span class=\"mtk4\">this</span><span class=\"mtk1\"> </span><span class=\"mtk10\">IHeaderDictionary</span><span class=\"mtk1\"> </span><span class=\"mtk12\">headers</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">headers</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&quot;P3P&quot;</span><span class=\"mtk1\">].</span><span class=\"mtk11\">IsNullOrEmpty</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">headers</span><span class=\"mtk1\">.</span><span class=\"mtk11\">Add</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;P3P&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;CP=</span><span class=\"mtk6\">\\&quot;</span><span class=\"mtk8\">IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT</span><span class=\"mtk6\">\\&quot;</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">static</span><span class=\"mtk1\"> </span><span class=\"mtk4\">bool</span><span class=\"mtk1\"> </span><span class=\"mtk11\">IsNullOrEmpty</span><span class=\"mtk1\">&lt;</span><span class=\"mtk10\">T</span><span class=\"mtk1\">&gt;(</span><span class=\"mtk4\">this</span><span class=\"mtk1\"> </span><span class=\"mtk10\">IEnumerable</span><span class=\"mtk1\">&lt;</span><span class=\"mtk10\">T</span><span class=\"mtk1\">&gt; </span><span class=\"mtk12\">source</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">source</span><span class=\"mtk1\"> == </span><span class=\"mtk4\">null</span><span class=\"mtk1\"> || !</span><span class=\"mtk12\">source</span><span class=\"mtk1\">.</span><span class=\"mtk11\">Any</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">static</span><span class=\"mtk1\"> </span><span class=\"mtk4\">string</span><span class=\"mtk1\"> </span><span class=\"mtk11\">ToJSON</span><span class=\"mtk1\">(</span><span class=\"mtk4\">this</span><span class=\"mtk1\"> </span><span class=\"mtk4\">object</span><span class=\"mtk1\"> </span><span class=\"mtk12\">value</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">JsonConvert</span><span class=\"mtk1\">.</span><span class=\"mtk11\">SerializeObject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">value</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">ErrorResponse</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">int</span><span class=\"mtk1\"> </span><span class=\"mtk12\">ErrorCode</span><span class=\"mtk1\"> { </span><span class=\"mtk4\">get</span><span class=\"mtk1\">; </span><span class=\"mtk4\">set</span><span class=\"mtk1\">; }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">string</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Description</span><span class=\"mtk1\"> { </span><span class=\"mtk4\">get</span><span class=\"mtk1\">; </span><span class=\"mtk4\">set</span><span class=\"mtk1\">; }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>In the above file we have created the method for checking the Xss in QueryParam, RequestUri and RequestBody. </p>\n<p>Here we have different methods which are as follows:-</p>\n<p><strong>ReadRequestBody</strong> which is used for reading the RequestBody.</p>\n<p><strong>RespondWithAnError</strong> which is used for returning the error.</p>\n<p><strong>IsDangerousString</strong> which is checking if there is any dangerous string like any script in the given string.</p>\n<p><strong>Step 7:</strong> Edit the Startup.cs file and add below line in <strong>Configure</strong> method.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">UseAntiXssMiddleware</span><span class=\"mtk1\">();</span></span></code></pre>\n<p><strong>Step 8 :</strong> After editing the Startup.cs file will look like below</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">System</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">System</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Collections</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Generic</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">System</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Linq</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">System</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Threading</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Tasks</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">AntiXssMiddleware</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Middleware</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Microsoft</span><span class=\"mtk1\">.</span><span class=\"mtk10\">AspNetCore</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Builder</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Microsoft</span><span class=\"mtk1\">.</span><span class=\"mtk10\">AspNetCore</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Hosting</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Microsoft</span><span class=\"mtk1\">.</span><span class=\"mtk10\">AspNetCore</span><span class=\"mtk1\">.</span><span class=\"mtk10\">HttpsPolicy</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Microsoft</span><span class=\"mtk1\">.</span><span class=\"mtk10\">AspNetCore</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Mvc</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Microsoft</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Extensions</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Configuration</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Microsoft</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Extensions</span><span class=\"mtk1\">.</span><span class=\"mtk10\">DependencyInjection</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Microsoft</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Extensions</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Hosting</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">using</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Microsoft</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Extensions</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Logging</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">namespace</span><span class=\"mtk1\"> </span><span class=\"mtk10\">AntiXssMiddleware</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Startup</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Startup</span><span class=\"mtk1\">(</span><span class=\"mtk10\">IConfiguration</span><span class=\"mtk1\"> </span><span class=\"mtk12\">configuration</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">Configuration</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">configuration</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk10\">IConfiguration</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Configuration</span><span class=\"mtk1\"> { </span><span class=\"mtk4\">get</span><span class=\"mtk1\">; }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\">// This method gets called by the runtime. Use this method to add services to the container.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">void</span><span class=\"mtk1\"> </span><span class=\"mtk11\">ConfigureServices</span><span class=\"mtk1\">(</span><span class=\"mtk10\">IServiceCollection</span><span class=\"mtk1\"> </span><span class=\"mtk12\">services</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">services</span><span class=\"mtk1\">.</span><span class=\"mtk11\">AddControllers</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\">// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">void</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Configure</span><span class=\"mtk1\">(</span><span class=\"mtk10\">IApplicationBuilder</span><span class=\"mtk1\"> </span><span class=\"mtk12\">app</span><span class=\"mtk1\">, </span><span class=\"mtk10\">IWebHostEnvironment</span><span class=\"mtk1\"> </span><span class=\"mtk12\">env</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">env</span><span class=\"mtk1\">.</span><span class=\"mtk11\">IsDevelopment</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">UseDeveloperExceptionPage</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">UseHttpsRedirection</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">UseAntiXssMiddleware</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">UseRouting</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">UseAuthorization</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">app</span><span class=\"mtk1\">.</span><span class=\"mtk11\">UseEndpoints</span><span class=\"mtk1\">(</span><span class=\"mtk12\">endpoints</span><span class=\"mtk1\"> =&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">endpoints</span><span class=\"mtk1\">.</span><span class=\"mtk11\">MapControllers</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p><strong>Step 9:</strong> Now build and run the solution.</p>\n<p>As we run the default API which is <code>https://localhost:44369/weatherforecast</code> we will get the below response.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"json\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">[</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;date&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;2020-08-21T11:58:40.0289718+05:30&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;temperatureC&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk7\">27</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;temperatureF&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk7\">80</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;summary&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Sweltering&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;date&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;2020-08-22T11:58:40.0289896+05:30&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;temperatureC&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk7\">21</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;temperatureF&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk7\">69</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;summary&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Cool&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;date&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;2020-08-23T11:58:40.0289899+05:30&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;temperatureC&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk7\">-20</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;temperatureF&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk7\">-3</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;summary&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Hot&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;date&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;2020-08-24T11:58:40.0289901+05:30&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;temperatureC&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk7\">21</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;temperatureF&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk7\">69</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;summary&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Sweltering&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;date&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;2020-08-25T11:58:40.0289902+05:30&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;temperatureC&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk7\">2</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;temperatureF&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk7\">35</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">&quot;summary&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Balmy&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">]</span></span></code></pre>\n<p>Now if we inject any script in the above url like <code>https://localhost:44369/weatherforecast&#x3C;script>&#x3C;/script></code> we will get the response as </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"json\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">&quot;ErrorCode&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk7\">500</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">&quot;Description&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;Error from AntiXssMiddleware&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p><strong>Note:</strong> </p>\n<ol>\n<li>The default port may be different when you run the project. So change the port accordingly.</li>\n<li>You can customize the error message according to your need.</li>\n</ol>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>In this blog, we learnt about how to implement AntiXssMiddlware in ASP.NET Core Web Application Project. We have implemented the AntiXssMiddleware in API's QueryParam, ReuqestUri and RequestBody. So if any script is injected in QueryParam, RequestUri or RequestBody then it will give the error.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk17 { color: #808080; }\n  .dark-default-dark .mtk6 { color: #D7BA7D; }\n</style>","frontmatter":{"date":"August 26, 2020","updated_date":null,"description":null,"title":"Implement AntiXssMiddleware in .NET Core Web","tags":["C#","ASP.NET"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/813c7a5a008113481ac2c05836830d14/ee604/antixss.png","srcSet":"/static/813c7a5a008113481ac2c05836830d14/69585/antixss.png 200w,\n/static/813c7a5a008113481ac2c05836830d14/497c6/antixss.png 400w,\n/static/813c7a5a008113481ac2c05836830d14/ee604/antixss.png 800w,\n/static/813c7a5a008113481ac2c05836830d14/f3583/antixss.png 1200w,\n/static/813c7a5a008113481ac2c05836830d14/5707d/antixss.png 1600w,\n/static/813c7a5a008113481ac2c05836830d14/eeb1b/antixss.png 1920w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Hemant Manwani","github":"hemant404","avatar":null}}}},{"node":{"excerpt":"In this post, we will look at the step-by-step process for Kafka Installation on Windows. Kafka is an open-source stream-processing software…","fields":{"slug":"/engineering/quick-kafka-installation/"},"html":"<p>In this post, we will look at the step-by-step process for Kafka Installation on Windows. Kafka is an open-source stream-processing software platform and comes under the Apache software foundation.</p>\n<h2 id=\"what-is-kafka\" style=\"position:relative;\"><a href=\"#what-is-kafka\" aria-label=\"what is kafka permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>What is Kafka?</strong></h2>\n<p>Kafka is used for real-time streams of data, to collect big data, or to do real-time analysis (or both). Kafka is used with in-memory microservices to provide durability and it can be used to feed events to complex event streaming systems and IoT/IFTTT-style automation systems. </p>\n<h2 id=\"installation-\" style=\"position:relative;\"><a href=\"#installation-\" aria-label=\"installation  permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>Installation :</strong></h2>\n<h3 id=\"1-java-setup\" style=\"position:relative;\"><a href=\"#1-java-setup\" aria-label=\"1 java setup permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. Java Setup:</h3>\n<p>Kafka requires Java 8 for running. And hence, this is the first step that we should do to install Kafka. To install Java, there are a couple of options. We can go for the Oracle JDK version 8 from the <a href=\"https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html\">Official Oracle Website</a>.</p>\n<h3 id=\"2-kafka--zookeeper-configuration\" style=\"position:relative;\"><a href=\"#2-kafka--zookeeper-configuration\" aria-label=\"2 kafka  zookeeper configuration permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. Kafka &#x26; Zookeeper Configuration:</h3>\n<p><strong>Step 1:</strong> Download Apache Kafka from its <a href=\"https://kafka.apache.org/downloads\">Official Site</a>.</p>\n<p><strong>Step 2:</strong> Extract tgz via cmd or from the available tool  to a location of your choice:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">tar -xvzf kafka_2.12-2.4.1.tgz</span></code></pre>\n<p><strong>Step 3:</strong> Copy the path of the Kafka folder. Now go to <em>config</em> inside Kafka folder and open <em>zookeeper.properties</em> file. Copy the path against the field <em>dataDir</em> and add <em>/zookeeper-data</em> to the path.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 636px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 41.35220125786164%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABZklEQVQoz21Ria6cMAzk/3+xYoHcB0sSjsCy6k7tvPekqmqkkZ0hNmNP93g8MOkJfndQWSFsAVMaMSwj3OoQ9wi/OYgsoYvCfMywq6VcwxHP4DvXiSzQ9X2PUY3wh2+ELJIeWUjKzWrajxxhTAMM8df7wnqtWI4F27Wh3hXnfeIknvNuYIVygo0WPmg8nxZmtlCOFEUNaQXs7CA9RfpW32crLGfG/jrw7+l4ZCFJTTQQVDxTjNTcJY+0Z8QcKSaEErDWguM+SFHFUpem6r8NRzGSQoPRTXCkUpsJMzWq79qw3zvu33dTxmPyHs/32ZBqQia1zG+v/bvhNLRxRBBwiyO1GiEqpCujXIV2xtiaqnIWKl7bHpnnhgc1Yp7ffpkiBuinhkmGooIi2ESu+wG9/QWTTXM77oEcdaSQnfeNY7WB+J979+jJFBpZ06is0lAUfmqGBC+hgsTrvr8W9PkOn0/Dz/k7/wPAdV3BuDwGNAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"zookeeper\"\n        title=\"zookeeper\"\n        src=\"/static/726644262b05de677792b4af683311e0/9be90/zookeeper.png\"\n        srcset=\"/static/726644262b05de677792b4af683311e0/9be90/zookeeper.png 636w\"\n        sizes=\"(max-width: 636px) 100vw, 636px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span>\n<strong>Step 4:</strong> we have to modify the config/server.properties file. Below is the change:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">fileslog.dirs=C:\\kafka\\kafka-logs</span></code></pre>\n<p>Basically, we are pointing the log.dirs to the new folder /data/kafka.</p>\n<h2 id=\"run-kafka-server\" style=\"position:relative;\"><a href=\"#run-kafka-server\" aria-label=\"run kafka server permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>Run Kafka Server:</strong></h2>\n<p><strong>Step 1:</strong> Kafka requires Zookeeper to run. Basically, Kafka uses Zookeeper to manage the entire cluster and various brokers. Therefore, a running instance of Zookeeper is a prerequisite to Kafka.</p>\n<p>To start Zookeeper, we can open a PowerShell prompt and execute the below command:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">.\\bin\\windows\\zookeeper-server-start.bat .\\config\\zookeeper.properties</span></code></pre>\n<p>If the command is successful, Zookeeper will start on port 2181.</p>\n<p><strong>Step 2:</strong> Now open another command prompt and change the directory to the kafka folder. Run kafka server using the command: </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">.\\bin\\windows\\kafka-server-start.bat .\\config\\server.properties</span></code></pre>\n<p><strong>Now your Kafka Server is up and running</strong>, you can create topics to store messages. Also, we can produce or consume data directly from the command prompt.</p>\n<h2 id=\"create-a-kafka-topic\" style=\"position:relative;\"><a href=\"#create-a-kafka-topic\" aria-label=\"create a kafka topic permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>Create a Kafka Topic:</strong></h2>\n<ol>\n<li>Open a new command prompt in the location C:\\kafka\\bin\\windows.</li>\n<li>Run the following command:</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">kafka-topics.bat --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test</span></code></pre>\n<h2 id=\"creating-kafka-producer\" style=\"position:relative;\"><a href=\"#creating-kafka-producer\" aria-label=\"creating kafka producer permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>Creating Kafka Producer:</strong></h2>\n<ol>\n<li>Open a new command prompt in the location C:\\kafka\\bin\\windows</li>\n<li>Run the following command:</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">kafka-console-producer.bat --broker-list localhost:9092 --topic test</span></code></pre>\n<h2 id=\"creating-kafka-consumer\" style=\"position:relative;\"><a href=\"#creating-kafka-consumer\" aria-label=\"creating kafka consumer permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><strong>Creating Kafka Consumer:</strong></h2>\n<ol>\n<li>Open a new command prompt in the location C:\\kafka\\bin\\windows.</li>\n<li>Run the following command:</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">kafka-console-consumer.bat --bootstrap-server localhost:9092 --topic test --from-beginning</span></code></pre>\n<p>If you see these messages on consumer console,<em>Congratulations!!!</em> you all done. Then you can play with producer and consumer terminal bypassing some Kafka messages.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n</style>","frontmatter":{"date":"August 25, 2020","updated_date":null,"description":null,"title":"Setting Up and Running Apache Kafka on Windows OS","tags":["Kafka","Windows"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/cf0f7f91117e9c259a3ad57b67a89c15/ee604/messagelog.png","srcSet":"/static/cf0f7f91117e9c259a3ad57b67a89c15/69585/messagelog.png 200w,\n/static/cf0f7f91117e9c259a3ad57b67a89c15/497c6/messagelog.png 400w,\n/static/cf0f7f91117e9c259a3ad57b67a89c15/ee604/messagelog.png 800w,\n/static/cf0f7f91117e9c259a3ad57b67a89c15/f3583/messagelog.png 1200w,\n/static/cf0f7f91117e9c259a3ad57b67a89c15/5707d/messagelog.png 1600w,\n/static/cf0f7f91117e9c259a3ad57b67a89c15/7ddcb/messagelog.png 2700w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Ashish Sharma","github":"ashish8947","avatar":null}}}},{"node":{"excerpt":"Getting Started with OAuth 2.0 OAuth has been a jargon for quite some time now and it is difficult for a beginner to learn it, not because…","fields":{"slug":"/engineering/oauth2/"},"html":"<h1 id=\"getting-started-with-oauth-20\" style=\"position:relative;\"><a href=\"#getting-started-with-oauth-20\" aria-label=\"getting started with oauth 20 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Getting Started with OAuth 2.0</h1>\n<p>OAuth has been a jargon for quite some time now and it is difficult for a beginner to learn it, not because OAuth is hard, but because of the confusing facts found about OAuth on the web. So I wrote this article to explain why and how OAuth is used in very simple terms.</p>\n<p>Let’s start with the basics: OAuth stands for Open Authorization. It’s a process through which an application or website can access private data from another website.\nIt provides applications the ability for “secure designated access.” For example, you can tell Google that it’s OK for abc.com to access your google account or contact without having to give abc.com your google password. </p>\n<p>OAuth never share password data but instead uses authorization tokens to prove an identity between consumers and service providers. OAuth is an authentication protocol that allows you to approve one application interacting with another on your behalf without giving away your password.</p>\n<h3 id=\"now-lets-have-a-look-at-oauth-20-terminology\" style=\"position:relative;\"><a href=\"#now-lets-have-a-look-at-oauth-20-terminology\" aria-label=\"now lets have a look at oauth 20 terminology permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Now Let’s have a look at OAuth 2.0 Terminology.</h3>\n<ul>\n<li><strong>Resource Owner:</strong> The resource owner is the user who authorizes an application to access their account. The application's access to the user's account is limited to the “scope” of the authorization granted (e.g., read or write access).</li>\n<li><strong>Client:</strong> The client is the application that’s trying to access the user's account. It needs to get permission from the user before accessing the account. For example, a client application can present the user with the login page to get an access token for access to a particular resource.</li>\n<li><strong>Authorization Server:</strong> The authorization server validates the user credentials and redirects the user back to the client with an authorization code. The client communicates with the authorization server to confirm its identity and exchanges the code for an access token.</li>\n<li><strong>Resource Server:</strong> A resource server is a server for access-protected resources. It handles authenticated requests from an app that has an access token. </li>\n<li><strong>Scope:</strong> It specifies the level of access that the application is requesting from the client.</li>\n<li><strong>Consent:</strong> The consent screen tells your users who is requesting access to their data and what kind of data you're asking to access. </li>\n</ul>\n<p>We have a pretty good understanding of OAuth 2.0 and Terminology, let’s move further and discuss the OAuth grant type that is widely used in this protocol.</p>\n<p>In total, there are five different grant type flows defined and described to perform authorizations tasks. Those are</p>\n<ul>\n<li>Authorization Code Grant</li>\n<li>Implicit Grant</li>\n<li>Resource Owner Credentials Grant</li>\n<li>Client Credentials Grant</li>\n<li>Refresh Token Grant</li>\n</ul>\n<h3 id=\"authorization-code-grant\" style=\"position:relative;\"><a href=\"#authorization-code-grant\" aria-label=\"authorization code grant permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Authorization Code Grant</h3>\n<p>The Authorization Code Grant Type is the most commonly used grant type.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 56.30769230769231%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABP0lEQVQoz6VSy27DIBD0/39VD1WkSJHaWw7Oo41xEhw/sF1YMI90AokVVZV66EhGZtnZnR3Irv9Ahs+GIEcRtJyjIeJXgo1Ipzeydo73wljjnpJwPEX8YFZVxTkfhuFOpq69LF7k21Keysl5EKSURVGUZTmOI7bGGKzOOaVUvtnuPj77B9kT23XL12G1GI9MINuYtm3zPO/7fhbvvUdbKdWZV0XB6rrRWmdh6NTqPQluOrHdbBhjaHVTRCSEwIr+0IKg8x7lbBwH8ZvsS90cGQvW8vN5vV6jJ1JRuItomgbkWQJpzcoTkX4YRoRhIAxTJTPBRPxwOOz3e/wj8mxkcaznma/JIYolAKT6KA8RjJ2sSkAcO/u4gjtZk7LR1cTEimnBxJVA80wOwZO245ckpYMPWXJyLvznq0qZNRcTTd8fTX5uA9GrbgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Authorization Code Grant\"\n        title=\"Authorization Code Grant\"\n        src=\"/static/c45e678b01cae83852178c3e0fd38eda/e5715/image4.png\"\n        srcset=\"/static/c45e678b01cae83852178c3e0fd38eda/a6d36/image4.png 650w,\n/static/c45e678b01cae83852178c3e0fd38eda/e5715/image4.png 768w,\n/static/c45e678b01cae83852178c3e0fd38eda/d9199/image4.png 960w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p><strong>The Story:</strong> A user tries to log in on  abc.com  but he can’t remember his password and he discovers an option to sign in with google, by clicking on this, the user will easily get logged using google account.</p>\n<p><strong>Flow</strong></p>\n<p>The client redirects the user to the authorization server having the following parameters in the query string.</p>\n<p><strong>Step 1</strong></p>\n<ul>\n<li><strong>response_type</strong> having the value code</li>\n<li><strong>client_id</strong> having the client identifier</li>\n<li><strong>redirect_uri</strong> having the client redirect URI. </li>\n<li><strong>scope</strong> a space-delimited list of scopes</li>\n<li><strong>state</strong> having a random string </li>\n</ul>\n<p>After successful authentication, the user will be redirected to the Consent screen where he needs to provide consent to abc.com to access the account detail.\nAuthorization code is generated by the authorization server and sent back to the client with redirect Uri.</p>\n<p><strong>Step 2</strong>\nThe client will now send a POST request to the authorization server with the following parameters:</p>\n<ul>\n<li><strong>grant_type</strong> having the value of authorization_code</li>\n<li><strong>client_id</strong> having the client identifier</li>\n<li><strong>client_secret</strong> having the client secret</li>\n<li><strong>redirect_uri</strong> having the same redirect URI the user redirected back.</li>\n<li><strong>code</strong> having the authorization code from the query string</li>\n</ul>\n<p>In the entire flow, the access token is never exposed to a web browser.</p>\n<h3 id=\"implicit-grant\" style=\"position:relative;\"><a href=\"#implicit-grant\" aria-label=\"implicit grant permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Implicit Grant</h3>\n<p>The Implicit flow was a simplified OAuth flow previously recommended for client-side applications like JavaScript apps where the access token was returned immediately without an extra authorization code exchange step.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 56.30769230769231%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABHklEQVQoz6WRW0+EMBCF+f//ShOzGk185EEQDQW2UFwKlBl6wwHEXS8bN/EkTQqZr3PmTDD9QwEd473qGo/qEsAs8t5/wGgtl81oRntS5JyjImtP/030WZYl57xt2w0+vIndlXq8U0WmrRsRiazrOkmSqqrGcdSL6C2l1FMUPb+8yg12wGKxu27vb9oslV03qNl/nucE933/pbNznJdpyoSoETGYuqa9fZB6tlcfDnEcM8ao27mZaVqzGAGA2XYp6iJjnibf78MwjKNohf2ibzAgsqwAwG1mgGEYKIyfpb92TnMhj4EhUnqrE+ppz4uC1NqS7eOeCUMYrDFEUqTrkqSUzSK6rDtbrDlA0/UKBvTOB6uTz4f/tL1WCt5o0O8PqYFDZ9VclAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Implicit Grant\"\n        title=\"Implicit Grant\"\n        src=\"/static/e3f47393896df6a6eaa11af651d2d857/e5715/image2.png\"\n        srcset=\"/static/e3f47393896df6a6eaa11af651d2d857/a6d36/image2.png 650w,\n/static/e3f47393896df6a6eaa11af651d2d857/e5715/image2.png 768w,\n/static/e3f47393896df6a6eaa11af651d2d857/d9199/image2.png 960w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>The Story: In this flow abc.com directly get access token without an extra authorization code exchange steps and able to access resources on a resource server</p>\n<p><strong>Flow</strong></p>\n<p>The client will redirect the user to the authorization server with the following parameters in the query string:</p>\n<ul>\n<li><strong>response_type</strong> having the value token</li>\n<li><strong>client_id</strong> having the client identifier</li>\n<li><strong>redirect_uri</strong> having the client redirect URI. </li>\n<li><strong>scope</strong> a space-delimited list of scopes</li>\n<li><strong>state</strong> having the random string</li>\n</ul>\n<p>It is not recommended to use the implicit flow (and some servers prohibit this flow entirely) due to the inherent risks of returning access tokens in an HTTP redirect without any confirmation that it has been received by the client.</p>\n<h3 id=\"resource-owner-credentials-grant\" style=\"position:relative;\"><a href=\"#resource-owner-credentials-grant\" aria-label=\"resource owner credentials grant permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Resource Owner Credentials Grant</h3>\n<p>The resource owner password credentials grant type is suitable in cases where the resource owner has a trust relationship with the client, such as a highly privileged application. The authorization server should take special care when enabling this grant type and only allow it when other flows are not viable.</p>\n<p>This grant type is suitable for clients capable of obtaining the resource owner’s credentials (username and password, typically using an interactive form). It is also used to migrate existing clients using direct authentication schemes such as HTTP Basic or Digest authentication to OAuth by converting the stored credentials to an access token.</p>\n<p><strong>Flow</strong></p>\n<p>The client will ask the user for their authorization credentials (usually a username and password).\nThe client then sends a POST request with following body parameters to the authorization server:</p>\n<ul>\n<li><strong>grant_type</strong> having the value password</li>\n<li><strong>client_id</strong> having the client’s ID</li>\n<li><strong>client_secret</strong> having the client’s secret</li>\n<li><strong>scope</strong> having a space-delimited list of requested scope permissions.</li>\n<li><strong>username</strong> having  a user’s username</li>\n<li><strong>password</strong> having a user’s password</li>\n</ul>\n<h3 id=\"client-credentials-grant\" style=\"position:relative;\"><a href=\"#client-credentials-grant\" aria-label=\"client credentials grant permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Client Credentials Grant</h3>\n<p>Using this flow the client can request an access token using only its client credentials (or other supported means of authentication).</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 56.30769230769231%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAh0lEQVQoz8WQTQvCMBBE+///oHgqgocKASGGdLObzDrGr+KxBfsguWzezpDBNzDwGJDn5Cpr5XxzndfIG2u7XE4yTdbgwHOQUgohxBiXr82slKKqIgKAMqp7PB7yeGb/arwetA4WUKZz7XD1K5lCqdVa41a8Qzj+iSVcp51Pcgffwn/8sH3kO1t0jcbKdW8qAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Client Credentials Grant\"\n        title=\"Client Credentials Grant\"\n        src=\"/static/50e12cb65c96fbbf7e1d502e6dacc539/e5715/image3.png\"\n        srcset=\"/static/50e12cb65c96fbbf7e1d502e6dacc539/a6d36/image3.png 650w,\n/static/50e12cb65c96fbbf7e1d502e6dacc539/e5715/image3.png 768w,\n/static/50e12cb65c96fbbf7e1d502e6dacc539/d9199/image3.png 960w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p><strong>The Story:</strong> The client application presents its client credentials (client identifier and client secret) to the authorization server requesting approval to access the protected resource (owned by the client application) on the resource server.\nThe authorization server authenticates the client credential and issues an access token.</p>\n<p><strong>Flow</strong></p>\n<p>The client sends a POST request with following body parameters to the authorization server:</p>\n<ul>\n<li><strong>grant_type</strong> having the value client_credentials</li>\n<li><strong>client_id</strong> having the client’s ID</li>\n<li><strong>client_secret</strong> having the client’s secret</li>\n<li><strong>scope</strong> having a space-delimited list of requested scope permissions.</li>\n</ul>\n<h3 id=\"refresh-token-grant\" style=\"position:relative;\"><a href=\"#refresh-token-grant\" aria-label=\"refresh token grant permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Refresh Token Grant</h3>\n<p>Access tokens eventually expire, however, some grants respond with a refresh token which enables the client to refresh the access token.</p>\n<p><strong>Flow</strong></p>\n<p>The client sends a POST request with following body parameters to the authorization server:</p>\n<ul>\n<li><strong>grant_type</strong> having the value refresh_token</li>\n<li><strong>refresh_token</strong> having the refresh token</li>\n<li><strong>client_id</strong> having the client’s ID</li>\n<li><strong>client_secret</strong> having the client’s secret</li>\n<li><strong>scope</strong> having a space-delimited list of requested scope permissions. </li>\n</ul>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>I hope you got an idea of how OAuth works and why it is needed. Now it’s time for you to go explore, find out more about the OAuth flow and implement it into your application.\nGood Luck and have fun! Thank you for following this article and hope it helped you! Please do buzz me if you want any help: indrasen.kumar@loginradius.com</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"August 24, 2020","updated_date":null,"description":"Using this blog one can easily understand the basic concept of Oauth 2.0","title":"Getting Started with OAuth 2.0","tags":["Engineering","Oauth","Authentication"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/e6413c80a3d38d63b14543319d3c54dd/ee604/oauth2.png","srcSet":"/static/e6413c80a3d38d63b14543319d3c54dd/69585/oauth2.png 200w,\n/static/e6413c80a3d38d63b14543319d3c54dd/497c6/oauth2.png 400w,\n/static/e6413c80a3d38d63b14543319d3c54dd/ee604/oauth2.png 800w,\n/static/e6413c80a3d38d63b14543319d3c54dd/40ffe/oauth2.png 960w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Indrasen Kumar","github":"indrasen715","avatar":null}}}}]},"markdownRemark":{"excerpt":"Google has prepared a roadmap to restrict third-party cookies in Chrome. Since 04 January 2024, Chrome has rolled out third-party cookie…","fields":{"slug":"/engineering/identity-impact-of-google-chrome-thirdparty-cookie-restrictions/"},"html":"<p>Google has prepared a roadmap to restrict third-party cookies in Chrome. Since 04 January 2024, Chrome has rolled out third-party cookie restrictions for 1% of stable clients and 20% of Canary, Dev, and Beta clients.</p>\n<p><strong>What does it mean for user authentication?</strong></p>\n<p>On one hand, Google believes third-party cookies are widely used for cross-site tracking, greatly affecting user privacy. Hence, Google wants to phase out (or restrict) supporting third-party cookies in Chrome by early Q2 2025 (subject to regulatory processes).</p>\n<p>On the other hand, Google introduced Privacy Sandbox to support the use cases (other than cross-site tracking and advertising) previously implemented using third-party cookies.</p>\n<p>In this article, we’ll discuss:</p>\n<ul>\n<li>How is user authentication (identity) affected?</li>\n<li>What is Google offering as part of Privacy Sandbox to support various identity use cases when third-party cookies are phased out?</li>\n</ul>\n<h2 id=\"how-is-user-authentication-affected\" style=\"position:relative;\"><a href=\"#how-is-user-authentication-affected\" aria-label=\"how is user authentication affected permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How is User Authentication Affected?</h2>\n<p>Third-party cookie restrictions affect user authentication in three ways, as follows.</p>\n<h3 id=\"external-identity-providers\" style=\"position:relative;\"><a href=\"#external-identity-providers\" aria-label=\"external identity providers permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>External Identity Providers</h3>\n<p>If your website or app uses an external Identity Provider (IdP) — like LoginRadius, the IdP sets a third-party cookie when the user authenticates on your app.</p>\n<h3 id=\"web-sso\" style=\"position:relative;\"><a href=\"#web-sso\" aria-label=\"web sso permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Web SSO</h3>\n<p>If you have multiple apps across domains within your organization and authentication is handled using an IdP (internal or external) with web SSO, you already use third-party cookies to facilitate seamless access for each user using a single set of credentials.</p>\n<p>If you have implemented web SSO with one primary domain and multiple sub-domains of the primary domain, third-party cookie restrictions may not apply. For now, Google doesn’t consider the cookies set by sub-domains as third-party cookies, although this stance may change in the future.</p>\n<p>For example, you have apps at <code>example.com</code>, <code>travel.example.com</code>, <code>stay.example.com</code>, and web SSO is handled by <code>auth.example.com</code>. In this case, third-party cookie restrictions don’t apply.</p>\n<h3 id=\"federated-sso\" style=\"position:relative;\"><a href=\"#federated-sso\" aria-label=\"federated sso permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Federated SSO</h3>\n<p>Federated SSO is similar to, albeit different from, web SSO. It can handle multiple IdPs and applications—aka., Service Providers (SPs)—spanning multiple organizations. It can also implement authentication scenarios that are usually implemented through web SSO.</p>\n<p>Usually, authentication is handled on a separate pop-up or page when the user wants to authenticate rather than on the application or website a user visits. </p>\n<p>For example, you already use federated SSO if you facilitate authentication for a set of apps through multiple social identity providers as well as traditional usernames and passwords.</p>\n<blockquote>\n<p><strong>Note</strong>: It is also possible to store tokens locally, not within cookies. In this case, third-party cookie restrictions won’t affect token-based authentication. However, the restrictions still affect authentication where tokens are stored within third-party cookies (a common and secure method).</p>\n</blockquote>\n<h2 id=\"chromes-alternatives-for-third-party-cookies\" style=\"position:relative;\"><a href=\"#chromes-alternatives-for-third-party-cookies\" aria-label=\"chromes alternatives for third party cookies permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Chrome’s Alternatives for Third-Party Cookies</h2>\n<p>Google has been developing alternative features and capabilities for Chrome to replace third-party cookies as part of its Privacy Sandbox for Web initiative.</p>\n<p>Specific to authentication, Google recommends the following:</p>\n<ol>\n<li>Cookies Having Independent Partitioned State (CHIPS)</li>\n<li>Storage Access API</li>\n<li>Related Website Sets</li>\n<li>Federated Credential Management (FedCM) API</li>\n</ol>\n<h3 id=\"cookies-having-independent-partitioned-state-chips\" style=\"position:relative;\"><a href=\"#cookies-having-independent-partitioned-state-chips\" aria-label=\"cookies having independent partitioned state chips permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Cookies Having Independent Partitioned State (CHIPS)</h3>\n<p><a href=\"https://developers.google.com/privacy-sandbox/3pcd/chips\">CHIPS</a> are a restricted way of setting third-party cookies on a top-level site without making them accessible on other top-level sites. Thus, they limit cross-site tracking and enable specific cross-site functionalities, such as maps, chat, and payment embeds.</p>\n<p>For example, a user visits <code>a.com</code> with a map embed from <code>map-example.com</code>, which can set a partitioned cookie that is only accessible on a.com. </p>\n<p>If the user visits <code>b.com</code> with a map embed from <code>map-example.com</code>, it cannot access the partitioned cookie set on <code>a.com</code>. It has to create a separate partitioned cookie specific to <code>b.com</code>, thus blocking cross-site tracking yet allowing limited cross-site functionality.</p>\n<p>You should specifically opt for partitioned cookies (CHIPS), which are set with partitioned and secure cookie attributes.</p>\n<p>If you’re using an external identity provider for your application, CHIPS is a good option to supplant third-party cookie restrictions. </p>\n<p>However, CHIPS may not be ideal if you have a web SSO or federated SSO implementation. It creates separate partitioned cookies for each application with a separate domain, which can increase complexity and create compatibility issues.</p>\n<h3 id=\"storage-access-api\" style=\"position:relative;\"><a href=\"#storage-access-api\" aria-label=\"storage access api permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Storage Access API</h3>\n<p>With <a href=\"https://developers.google.com/privacy-sandbox/3pcd/storage-access-api\">Storage Access API</a>, you can access the local storage in a third-party context through iframes, similar to when users visit it as a top-level site in a first-party context. That is, it gives access to unpartitioned cookies and storage.</p>\n<p>Storage Access API requires explicit user approval to grant access, similar to locations, camera, and microphone permissions. If the user denies access, unpartitioned cookies and storage won’t be accessible in a third-party context.</p>\n<p>It is most suitable when loading cross-site resources and interactions, such as:</p>\n<p>Verifying user sessions when allowing interactions on an embedded social post or providing personalization for an embedded video.\nEmbedded documents requiring user verification status to be accessible.</p>\n<p>As it requires explicit user approval, it is advisable to use Storage Access API when you can’t implement an identity use case with the other options.</p>\n<h3 id=\"related-website-sets\" style=\"position:relative;\"><a href=\"#related-website-sets\" aria-label=\"related website sets permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Related Website Sets</h3>\n<p>With <a href=\"https://developers.google.com/privacy-sandbox/3pcd/related-website-sets\">Related Website Sets</a>, you can declare a <code>primary</code> website and <code>associatedSites</code> for limited purposes to grant third-party cookie access and local storage for a limited number of sites.</p>\n<p>Chrome automatically recognizes related website sets declared, accepted, and maintained in this open-source GitHub repository: <a href=\"https://github.com/GoogleChrome/related-website-sets\">Related Website Sets</a></p>\n<p>It provides access through Storage Access API directly without prompting for user approval, but only after the user interacts with the relevant iframe.</p>\n<p>It is important to declare a limited number of domains in related website sets that are meaningful and used for specific purposes. Google may block or suspend any exploitative use of this feature.</p>\n<p>The top-level site can also request approval for specific cross-site resources and scripts to Storage Access API using <code>resuestStorageAccessFor()</code> API.</p>\n<p>If you’re using an external identity provider for your web application, you can declare the domain of the identity provider in the related set to ensure limited third-party cookies and storage access to the identity provider, thus ensuring seamless user authentication.</p>\n<p>Related Website Sets can also work to supplement third-party cookie restrictions in web SSO and federated SSO if the number of web applications (or domains) is limited.</p>\n<h3 id=\"federated-credential-management-fedcm-api\" style=\"position:relative;\"><a href=\"#federated-credential-management-fedcm-api\" aria-label=\"federated credential management fedcm api permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Federated Credential Management (FedCM) API</h3>\n<p>FedCM API enables federated SSO without third-party cookies.</p>\n<p>With FedCM API, a user follows these steps for authentication:</p>\n<ol>\n<li>The User navigates to a Service Provider (SP) — aka., Relying Party (RP)</li>\n<li>As the user requests to authenticate, the SP requests the browser through FedCM API to initiate authentication.</li>\n<li>The browser displays a list of available identity providers (supported by the RP), such as social IdPs like Google, Apple, LinkedIn, and Facebook, or other OAuth IdPs like LoginRadius.</li>\n<li>Once the user selects an IdP, the browser communicates with the IdP. Upon valid authentication, the IdP generates a secure token.\nThe browser delivers this secure token to the RP to facilitate user authorization.</li>\n</ol>\n<p>You can access a user demo of FedCM here: <a href=\"https://fedcm-rp-demo.glitch.me/\">FedCM</a>. </p>\n<p>For more information about implementing federated SSO with FedCM API, go through the <a href=\"https://developers.google.com/privacy-sandbox/3pcd/fedcm-developer-guide\">FedCM developer guide</a>.</p>\n<h2 id=\"how-is-loginradius-preparing-for-the-third-party-cookie-phase-out\" style=\"position:relative;\"><a href=\"#how-is-loginradius-preparing-for-the-third-party-cookie-phase-out\" aria-label=\"how is loginradius preparing for the third party cookie phase out permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How is LoginRadius Preparing for the Third-party Cookie Phase-out?</h2>\n<p>Firstly, we’re committed to solving our customers' user identity pain points — and preparing for the third-party cookies phase-out is no different.</p>\n<p>We’ll implement the most relevant and widely useful solutions to facilitate a smooth transition for our customers.</p>\n<p>Please subscribe to our blog for more information. We’ll update you on how we help with the third-party cookie phase-out.</p>\n<h2 id=\"in-conclusion\" style=\"position:relative;\"><a href=\"#in-conclusion\" aria-label=\"in conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>In Conclusion</h2>\n<p>The proposed changes to phase out third-party cookies and suggested alternatives are evolving as Google has been actively collaborating and discussing changes with the border community.</p>\n<p>Moreover, browsers like Firefox, Safari, and Edge may approach restricting third-party cookies differently than Google does.</p>\n<p>From LoginRadius, we’ll keep you updated on what we’re doing as a leading Customer Identity and Access Management (CIAM) vendor to prepare for the third-party cookie phase-out.</p>\n<h2 id=\"glossary\" style=\"position:relative;\"><a href=\"#glossary\" aria-label=\"glossary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Glossary</h2>\n<p><strong>Top-level site</strong>: It is the primary site a user has visited.</p>\n<p><strong>First-party cookie</strong>: A cookie set by the top-level site.</p>\n<p><strong>Third-party cookie</strong>: A cookie set by a domain other than the top-level site. For example, let’s assume that a user has visited <code>a.com</code>, which might use an embed from <code>loginradius.com</code> to facilitate authentication. If <code>loginradius.com</code> sets a cookie when the user visits <code>a.com</code>, it is called a third-party cookie as the user hasn’t directly visited <code>loginradius.com</code>.</p>\n<h2 id=\"references\" style=\"position:relative;\"><a href=\"#references\" aria-label=\"references permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>References</h2>\n<ul>\n<li><a href=\"https://developers.google.com/privacy-sandbox/3pcd/prepare/prepare-for-phaseout\">Changes to Chrome's treatment of third-party cookies</a></li>\n<li><a href=\"https://developers.google.com/privacy-sandbox/3pcd/guides/identity\">Check the impact of the third-party cookie changes on your sign-in workflows</a></li>\n</ul>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"July 08, 2024","updated_date":null,"description":"Google Chrome has planned to phase out third-party cookies, which will affect different website functionalities depending on third-party cookies. This blog focuses on how this phase-out affects identity and user authentication and discusses alternatives for overcoming challenges.","title":"How Chrome’s Third-Party Cookie Restrictions Affect User Authentication?","tags":["Identity","Cookies","Chrome"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/eb7396060c0adc430dbed2d04b63d431/ee604/third-party-cookies-phaseout-chrome.png","srcSet":"/static/eb7396060c0adc430dbed2d04b63d431/69585/third-party-cookies-phaseout-chrome.png 200w,\n/static/eb7396060c0adc430dbed2d04b63d431/497c6/third-party-cookies-phaseout-chrome.png 400w,\n/static/eb7396060c0adc430dbed2d04b63d431/ee604/third-party-cookies-phaseout-chrome.png 800w,\n/static/eb7396060c0adc430dbed2d04b63d431/f3583/third-party-cookies-phaseout-chrome.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Raghunath Reddy","github":"raghunath-r-a","avatar":null}}}},"pageContext":{"limit":6,"skip":174,"currentPage":30,"type":"//engineering//","numPages":52,"pinned":"17fa0d7b-34c8-51c4-b047-df5e2bbaeedb"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}