<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Azure &#8211; Pauls Blog</title>
	<atom:link href="https://sterl.org/category/cloud/azure/feed/" rel="self" type="application/rss+xml" />
	<link>https://sterl.org</link>
	<description></description>
	<lastBuildDate>Thu, 01 Feb 2024 10:00:22 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>
	<item>
		<title>Setup Spring Boot Azure OAuth2 with CORS</title>
		<link>https://sterl.org/2024/02/setup-spring-boot-azure-oauth2-with-cors/</link>
					<comments>https://sterl.org/2024/02/setup-spring-boot-azure-oauth2-with-cors/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Thu, 01 Feb 2024 09:03:03 +0000</pubDate>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[CORS error]]></category>
		<category><![CDATA[oauth2Login]]></category>
		<category><![CDATA[OAuth2UserService]]></category>
		<category><![CDATA[strict-origin-when-cross-origin]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=993</guid>

					<description><![CDATA[What is needed Setup an Azure AAD Application First we need an Azure AAD application which gives us the access to our AD users. The important part are the client id and the tenant id here: Add the web URIs which are allowed to use the OAuth2 login In the next step we have to&#8230;]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">What is needed</h2>



<ol class="wp-block-list">
<li>Setup an Azure AAD Application</li>



<li>Add the web URIs which are allowed to use the OAuth2 login</li>



<li>Add a client secret for your application</li>



<li>Add API Permission to read the profile</li>



<li>Add needed Azure dependencies</li>



<li>Setup Spring OAuth config</li>



<li>Adjust the CORS settings in Spring to ensure token refreshes</li>



<li>Configure spring security</li>
</ol>



<h2 class="wp-block-heading">Setup an Azure AAD Application</h2>



<p>First we need an Azure AAD application which gives us the access to our AD users. The important part are the client id and the tenant id here:</p>



<figure class="wp-block-image size-full is-resized"><a href="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application.png"><img fetchpriority="high" decoding="async" width="810" height="243" src="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application.png" alt="" class="wp-image-1004" style="aspect-ratio:3.3333333333333335;width:840px;height:auto" srcset="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application.png 810w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-300x90.png 300w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-768x230.png 768w" sizes="(max-width: 810px) 100vw, 810px" /></a></figure>



<h2 class="wp-block-heading">Add the web URIs which are allowed to use the OAuth2 login</h2>



<p>In the next step we have to allow &#8222;applications&#8220; based on their &#8222;DNS&#8220; name to access and login through this AAD. Ensure to remember the yellow part, which is later needed in the configutation.</p>



<p>The URLs are basically the one you whitelist for a login. If you setup the &#8222;test&#8220; AAD application you may want also add sometimes the localhost for testing. Ensure to remove it again later on.</p>



<figure class="wp-block-image size-large"><a href="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-autthentication.png"><img decoding="async" width="1024" height="493" src="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-autthentication-1024x493.png" alt="" class="wp-image-1006" srcset="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-autthentication-1024x493.png 1024w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-autthentication-300x144.png 300w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-autthentication-768x369.png 768w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-autthentication.png 1368w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<h2 class="wp-block-heading">Add a client secret for your application</h2>



<p>Next we have to create a secret for our application, we only require later the value of it. Please make sure you provide a new one after the expiration period.</p>



<p>You can have multiple secrets for multiple apps here.</p>



<figure class="wp-block-image size-large"><a href="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-secret.png"><img decoding="async" width="1024" height="317" src="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-secret-1024x317.png" alt="" class="wp-image-1009" srcset="https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-secret-1024x317.png 1024w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-secret-300x93.png 300w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-secret-768x238.png 768w, https://sterl.org/wp-content/uploads/2024/02/azure-aad-application-secret.png 1439w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<h2 class="wp-block-heading">Setup Spring OAuth config</h2>



<p>In this configuration we have to enter all the collected data <strong>azure-dev</strong> as name is here the suffix provided in the authentication section of the Azure AAD application. You can choose what ever name you like.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;yaml&quot;,&quot;mime&quot;:&quot;text/x-yaml&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;YAML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;yaml&quot;}">spring:
  security:
    oauth2:
      client:
        provider:
          azure:
            issuer-uri: https://login.microsoftonline.com/&lt;Directory (tenant) ID&gt;/v2.0
            user-name-attribute: name
        registration:
          azure-dev:
            provider: azure
            client-id: &lt;Application (client) ID&gt;
            client-secret: &lt;the secret value you created for your app&gt;
            client-authentication-method: client_secret_post
            scope:
              - openid
              - email
              - profile</pre></div>



<h2 class="wp-block-heading">Spring Security</h2>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">  @Bean
  SecurityFilterChain filterChain(HttpSecurity http, OptionalYourUserService userService) throws Exception {
    // @formatter:off
    http
      .authorizeHttpRequests(authorizeHttpRequests -&gt;
        authorizeHttpRequests
          // public URLs
          .requestMatchers(antMatcher(&quot;/actuator/health/readiness&quot;)).permitAll()
          // secure actuator
          .requestMatchers(antMatcher(&quot;/actuator/**&quot;)).hasRole(UserGroup.ADMIN)
          // app urls
          .requestMatchers(&quot;/api/**&quot;).authenticated()
          // default; recommended to use .authenticated()
          .anyRequest().permitAll()
      ).headers(headers -&gt; headers.frameOptions(FrameOptionsConfig::sameOrigin))
      .oauth2Login( oauth2 -&gt; oauth2
          .userInfoEndpoint(userInfo -&gt; userInfo
            .oidcUserService(oidcUserService(userService)))
      )
      .headers(headers -&gt; headers.frameOptions(FrameOptionsConfig::sameOrigin));
    // @formatter:on
    return http.build();
  }

  private OAuth2UserService&lt;OidcUserRequest, OidcUser&gt; oidcUserService(
    OptionalYourUserService userService) {
    return userRequest -&gt; {
      var oidcUser = new OidcUserService().loadUser(userRequest); // Delegate to the default
                                                                  // implementation
      
      // add any custom user service integration here, if required.

      return oidcUser;
    };
  }</pre></div>



<h2 class="wp-block-heading">Add CORS Config</h2>



<p>To avoid any <code>CORS error</code> / <code>strict-origin-when-cross-origin</code> in your application we have to whitelist the OAuth2 provider for any redirect, in this example login.microsoft:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">  @Bean
  protected CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList(&quot;https://login.microsoftonline.com/**&quot;));
    configuration.addAllowedHeader(&quot;*&quot;);
    configuration.addAllowedMethod(&quot;*&quot;);
    configuration.setAllowCredentials(true);
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration(&quot;/**&quot;, configuration);
    return source;
  }</pre></div>



<h2 class="wp-block-heading">Links</h2>



<ul class="wp-block-list">
<li>https://learn.microsoft.com/en-us/azure/developer/java/spring-framework/spring-boot-starter-for-azure-active-directory-developer-guide</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2024/02/setup-spring-boot-azure-oauth2-with-cors/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Azure Bicep CLI and functions cheet sheet</title>
		<link>https://sterl.org/2023/03/azure-bicep-cli-functions-cheet-sheet/</link>
					<comments>https://sterl.org/2023/03/azure-bicep-cli-functions-cheet-sheet/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Fri, 31 Mar 2023 15:06:05 +0000</pubDate>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[CI/CD DevOps]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[arm]]></category>
		<category><![CDATA[bicep]]></category>
		<category><![CDATA[ci/cd]]></category>
		<category><![CDATA[IaC]]></category>
		<category><![CDATA[infrastructure-as-code]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=890</guid>

					<description><![CDATA[Overall Azure bicep is the best repalcement for AWS CDK currently available (2023) and the recommended way to express infrastructure-as-code in the aure universe. Bicep CLI All command require azure CLI and PowerShell 7.x.x Select subscription by name / set context Set default Run bicep deployment Read resource group List resource groups Bicep functions Random&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Overall Azure <code>bicep</code> is the best repalcement for <code>AWS CDK</code> currently available (2023) and the recommended way to express infrastructure-as-code in the aure universe.</p>



<h2 class="wp-block-heading">Bicep CLI</h2>



<p>All command require azure CLI and PowerShell 7.x.x</p>



<h3 class="wp-block-heading">Select subscription by name / set context</h3>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;file&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;powershell&quot;,&quot;mime&quot;:&quot;application/x-powershell&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;PowerShell&quot;,&quot;language&quot;:&quot;PowerShell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;powershell&quot;}">$context = Get-AzSubscription -SubscriptionName '&lt;name of the subscription&gt;'
Set-AzContext $context</pre></div>



<h3 class="wp-block-heading">Set default </h3>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;powershell&quot;,&quot;mime&quot;:&quot;application/x-powershell&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;PowerShell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;powershell&quot;}">Set-AzDefault -ResourceGroupName &lt;resource-group-name&gt;</pre></div>



<h3 class="wp-block-heading">Run bicep deployment</h3>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;powershell&quot;,&quot;mime&quot;:&quot;application/x-powershell&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;PowerShell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;powershell&quot;}">New-AzResourceGroupDeployment -TemplateFile main.bicep</pre></div>



<h3 class="wp-block-heading">Read resource group</h3>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;powershell&quot;,&quot;mime&quot;:&quot;application/x-powershell&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;PowerShell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;powershell&quot;}">Get-AzResourceGroupDeployment -ResourceGroupName &lt;resource-group-name&gt; | Format-Table</pre></div>



<h3 class="wp-block-heading">List resource groups</h3>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;powershell&quot;,&quot;mime&quot;:&quot;application/x-powershell&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;PowerShell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;powershell&quot;}">Get-AzResourceGroup</pre></div>



<h2 class="wp-block-heading">Bicep functions</h2>



<h3 class="wp-block-heading">Random unique name <a href="https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/bicep-functions-string#uniquestring" target="_blank" rel="noreferrer noopener">uniqueString</a></h3>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;text/javascript&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;JavaScript&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;js&quot;}">param fooUniceName string = 'fooo${uniqueString('constant-seed-value')}'</pre></div>



<h2 class="wp-block-heading">Create resource group with bicep</h2>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;yaml&quot;,&quot;mime&quot;:&quot;text/x-yaml&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;YAML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;yaml&quot;}">targetScope = 'subscription'
param location string = deployment().location

resource rg 'Microsoft.Resources/resourceGroups@2022-09-01' = {
    name: 'myName'
    location: location
}</pre></div>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;powershell&quot;,&quot;mime&quot;:&quot;application/x-powershell&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;PowerShell&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;powershell&quot;}">az deployment create --location westeurope  --template-file .\main.bicep</pre></div>



<h3 class="wp-block-heading">Links</h3>



<ul class="wp-block-list">
<li><a href="https://learn.microsoft.com/en-us/powershell/module/az.resources">https://learn.microsoft.com/en-us/powershell/module/az.resources</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2023/03/azure-bicep-cli-functions-cheet-sheet/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Azure Node Functions Apps and OpenAPI Swagger</title>
		<link>https://sterl.org/2023/03/azure-node-functions-apps-and-openapi-swagger/</link>
					<comments>https://sterl.org/2023/03/azure-node-functions-apps-and-openapi-swagger/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Sun, 12 Mar 2023 09:15:26 +0000</pubDate>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[OpenAPI]]></category>
		<category><![CDATA[swagger-ui]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=875</guid>

					<description><![CDATA[Sometimes we face the problem that we want to host a very simple web-service including a swagger-ui / OpenApi-UI. The question now is, what is the simplest solution, which works everywhere, even in a azure function app? Where are of course some libs etc. which on the other hand require us to run the web-server.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Sometimes we face the problem that we want to host a very simple web-service including a swagger-ui / <a rel="noreferrer noopener" href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/installation/" data-type="URL" data-id="https://swagger.io/docs/open-source-tools/swagger-ui/usage/installation/" target="_blank">OpenApi-UI</a>. The question now is, what is the simplest solution, which works everywhere, even in a azure function app?</p>



<p>Where are of course some libs etc. which on the other hand require us to run the web-server. If we look into the doc using the simple <strong>unpkg </strong>HTML files looks like to be the simplest solution.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;htmlmixed&quot;,&quot;mime&quot;:&quot;text/html&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;HTML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;html&quot;}">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;utf-8&quot; /&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot; /&gt;
  &lt;meta
    name=&quot;description&quot;
    content=&quot;SwaggerUI&quot;
  /&gt;
  &lt;title&gt;SwaggerUI&lt;/title&gt;
  &lt;link rel=&quot;stylesheet&quot; href=&quot;https://unpkg.com/swagger-ui-dist@4.5.0/swagger-ui.css&quot; /&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;swagger-ui&quot;&gt;&lt;/div&gt;
&lt;script src=&quot;https://unpkg.com/swagger-ui-dist@4.5.0/swagger-ui-bundle.js&quot; crossorigin&gt;&lt;/script&gt;
&lt;script&gt;
  window.onload = () =&gt; {
    window.ui = SwaggerUIBundle({
      url: 'https://petstore3.swagger.io/api/v3/openapi.json',
      dom_id: '#swagger-ui',
    });
  };
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></div>



<h3 class="wp-block-heading">What needs to be done</h3>



<ul class="wp-block-list">
<li>Get the HTML OpenAPI HTML file</li>



<li>Provide an OpenAPI YML or JSON</li>



<li>Create an endpoint which should host the doc</li>
</ul>



<p>This solution works also for a spring web app or a AWS function. We will go ahead and look into a Node JavaScript example to see how it may look like:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><a href="https://sterl.org/wp-content/uploads/2023/03/azure-function-app-open-api-doc.png"><img loading="lazy" decoding="async" width="271" height="200" src="https://sterl.org/wp-content/uploads/2023/03/azure-function-app-open-api-doc.png" alt="" class="wp-image-876"/></a></figure></div>


<p>Which means we have to create a new azure function endpoint where we want to host the OpenApi-UI:</p>



<h3 class="wp-block-heading">function.json</h3>



<p>We can set the function to &#8222;anonymous&#8220; if we like and only get is required:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/json&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;JSON&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;json&quot;}">{
  &quot;bindings&quot;: [
    {
      &quot;authLevel&quot;: &quot;anonymous&quot;,
      &quot;type&quot;: &quot;httpTrigger&quot;,
      &quot;direction&quot;: &quot;in&quot;,
      &quot;name&quot;: &quot;req&quot;,
      &quot;methods&quot;: [
        &quot;get&quot;
      ]
    },
    {
      &quot;type&quot;: &quot;http&quot;,
      &quot;direction&quot;: &quot;out&quot;,
      &quot;name&quot;: &quot;res&quot;
    }
  ]
}</pre></div>



<h3 class="wp-block-heading">openApi.html</h3>



<p>The only adjustment to the original HTML file is the source of the <code>yml</code> or <code>json</code> file. You could also adjust the JS and CSS url:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;htmlmixed&quot;,&quot;mime&quot;:&quot;text/html&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;HTML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;html&quot;}">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;utf-8&quot; /&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot; /&gt;
  &lt;meta name=&quot;description&quot; content=&quot;My SwaggerUI&quot; /&gt;
  &lt;title&gt;SwaggerUI&lt;/title&gt;
  &lt;link rel=&quot;stylesheet&quot; href=&quot;https://unpkg.com/swagger-ui-dist@4.5.0/swagger-ui.css&quot; /&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;swagger-ui&quot;&gt;&lt;/div&gt;
&lt;script src=&quot;https://unpkg.com/swagger-ui-dist@4.5.0/swagger-ui-bundle.js&quot; crossorigin&gt;&lt;/script&gt;
&lt;script&gt;
  window.onload = () =&gt; {
    window.ui = SwaggerUIBundle({
      url: './doc?file=openApi.yml',
      dom_id: '#swagger-ui',
    });
  };
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></div>



<h3 class="wp-block-heading">openApi.yml</h3>



<p>Just as an example here. Note here the <code>URL</code> which has a funny value of <code>_server.url_</code>, we will replace this value later.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;yaml&quot;,&quot;mime&quot;:&quot;text/x-yaml&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;YAML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;yaml&quot;}">openapi: 3.0.2
info:
  title: My OpenAPI
  version: v1
servers:
  - url: &quot;_server.url_&quot;
paths:
  /foo:
    get:
      summary: Som cool function
      responses:
        '200':
          description: Retrieved entities
          content:
            application/json:
              schema:
                type: string</pre></div>



<h3 class="wp-block-heading">index.js</h3>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;text/javascript&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;JavaScript&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;js&quot;}">&quot;use strict&quot;;
const fs = require('fs');
const util = require('util');
const readFileAsync = util.promisify(fs.readFile);

module.exports = async function (context, req) {
    switch(req.query.file) {
        case 'openApi.yml':
            // get the url and remove the doc suffix, azure specific
            const url = req.headers.referer.replace('/doc', '');
            let yml = await readFileAsync('doc/openApi.yml', 'UTF-8');
            yml = yml.replace('_server.url_', url);
            context.res = {
                body: yml,
                headers: {
                    &quot;Content-Type&quot;: &quot;application/yml; charset=utf-8&quot;
                }
            };
            break;
        default:
            context.res = {
                body: await readFileAsync('doc/openApi.html', 'UTF-8'),
                headers: {
                    &quot;Cache-Control&quot;: &quot;max-age=600&quot;, // optional cache header
                    &quot;Content-Type&quot;: &quot;text/html; charset=utf-8&quot;
                }
            };
            break;
    }
}</pre></div>



<p>The switch case is where to ensure we load only files we want to publish, as so you have to extend the case block if you want to host the JS files too. Of course they have to be added to your directory.</p>



<h2 class="wp-block-heading">Links</h2>



<ul class="wp-block-list">
<li><a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/installation/">https://swagger.io/docs/open-source-tools/swagger-ui/usage/installation/</a></li>



<li><a href="https://learn.microsoft.com/de-de/azure/azure-functions/functions-reference-node?t#use-async-and-await">https://learn.microsoft.com/de-de/azure/azure-functions/functions-reference-node?t#use-async-and-await</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2023/03/azure-node-functions-apps-and-openapi-swagger/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
