<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Andrea Zagarella on Medium]]></title>
        <description><![CDATA[Stories by Andrea Zagarella on Medium]]></description>
        <link>https://medium.com/@a.zagarella?source=rss-d6f1c90a0934------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*gLLfoL_J8O6EY7HKA7IYJw.png</url>
            <title>Stories by Andrea Zagarella on Medium</title>
            <link>https://medium.com/@a.zagarella?source=rss-d6f1c90a0934------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 22 May 2026 13:51:02 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@a.zagarella/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Microservice Architecture | a real business-world example with API Gateway and OAuth2/OIDC Login]]></title>
            <link>https://medium.com/@a.zagarella/microservices-architecture-a-real-business-world-scenario-c77c31a957fb?source=rss-d6f1c90a0934------2</link>
            <guid isPermaLink="false">https://medium.com/p/c77c31a957fb</guid>
            <category><![CDATA[spring-boot]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[microservices]]></category>
            <category><![CDATA[software-engineering]]></category>
            <dc:creator><![CDATA[Andrea Zagarella]]></dc:creator>
            <pubDate>Mon, 26 Feb 2024 17:25:12 GMT</pubDate>
            <atom:updated>2024-02-29T18:43:56.813Z</atom:updated>
            <content:encoded><![CDATA[<p>Applications with <strong>Microservice Architecture</strong> can be developed in many different ways, using different technologies, with different architectural choices and patterns. In this article, we will look at an high-level example of a possible microservices architecture — without considering several other elements that are generally present — with a particular focus on the <strong>Authentication </strong>and <strong>Authorization </strong>part. A typical example is one that involves an API Gateway as the entry point and an Identity Provider for the authentication part. The following is just one example that can be given of microservice architecture but is part of a <strong>real business world </strong>scenario.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0_vDm5pFfMK2xR6KBslGgw.png" /><figcaption>Part of a possible microservice architecture with API Gateway and Identity Provider</figcaption></figure><h3>Part of a possible Microservice Architecture</h3><h4>API Gateway — Spring Cloud Gateway</h4><p>In microservice applications (in this case Spring Boot microservices), a common choice is to use an API gateway as the entry point to the outside world. All (or almost all) calls from the browser — or from an external service — pass through the gateway before going to an API of a microservice. This layer typically includes various security controls, authentication, caching and so on.</p><p>The current standard de facto promoted by Spring for implementing an API gateway is <a href="https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/"><strong>Spring Cloud Gateway</strong></a><strong> </strong>which is a great choice because integrate many features out of the box (as always with few lines of configuration) and it’s also ready to be used as a <strong>Reactive Application</strong> (instead that the typical MVC application as Spring Boot). As spring says:</p><blockquote>Spring Cloud Gateway requires the Netty runtime provided by Spring Boot and Spring Webflux. It does not work in a traditional Servlet Container or when built as a WAR.</blockquote><p>With an API Gateway there are basically two patterns that can be used for authentication:</p><ol><li><strong>API Gateway acts as an</strong> <strong>OAuth2 Client: </strong>in this case, any unauthenticated incoming request will initiate a flow to obtain a valid Token. Once the token is acquired by the gateway, it is then used when sending requests to a backend service. The API Gateway interacts with the authorization server to obtain access and refresh tokens and stores them securely.</li><li><strong>API Gateway acts as an OAuth 2.0 Resource Server: </strong>here the gateway enforcing that each request has a valid access token before it is sent to a back-end service. Typically, the token is sent from the backend to the frontend and then the frontend sends the token provided for each call</li></ol><p>In this example we are in the first scenario where the <strong>API Gateway acts as an OAuth2 Client </strong>and the Frontend (can we say the external world) never talk with microservices but every request pass from the API Gateway to the others microservices.</p><h4>Type of authentication — OIDC</h4><p>With microservice architectures, one of the most used authentication type is <strong>OIDC (OpenID Connect)</strong>, which adds authentication functionality to the <strong>OAuth2</strong> <strong>protocol </strong>used for the authorization part with <strong>JWT Token</strong>. An open source popular identity provider used for this purpose is <a href="https://www.keycloak.org/"><strong>Keycloak</strong></a>. Other commercial OIDC alternatives include <strong>Okta</strong>, <strong>AUth0</strong>, <strong>Microsoft Azure Active Directory (AD), AWS Cognito</strong> and so on.</p><h4>How protect microservices from outside — JWT</h4><p>In business scenarios, security is always a key concept. It’s important to have different layers of security and one of them implies protect microservices with authentication. At microservice level, authentication is not intended as the authentication used for identify users of an application. Authentication for a microservice means receive request authenticated and in this example means that all calls received from the gateway must be authenticated. A common example of authentication on microservices is <strong>JWT tokens</strong>. Endpoints exposed by microservices will only be accessible if a valid JWT token is provided.</p><h4>The role of Keycloak — Identity Provider and Authorization Server</h4><p>In this example Keycloak have an important role because at API Gateway level acts as <strong>Identity Provider</strong> managing User’s Authentication (In this way, no user credentials will be stored in the application DB), while at microservice level acts as <strong>Authorization Server</strong> authenticating the incoming request from the gateway. In other word, in microservices is Keycloak that determine if the JWT token is valid or not and make APIs reachable.</p><h4>Security, Authentication and Authorization — Spring Security</h4><p>It is challenging to imagine an application like this without <a href="https://docs.spring.io/spring-security/reference/servlet/oauth2/login/index.html"><strong>Spring Security</strong></a>, which is the standard for managing authentication and authorization in Spring Boot applications and handling security aspects in general. In this case it is Spring Security that will take care of the configuration to manage what has been said so far.</p><h3>Authentication</h3><p>In this example, the authentication part is handled at the API Gateway level using Spring Security and Keycloak as Identity Provider. All user management can be delegated to Keycloak. In this way, it’s possible to not persist Users on the application and no user information is stored on the application DB.</p><h4>OIDC Authentication with OAuth2 Authorization Code Flow</h4><p>As mentioned, it’s possible use <a href="https://openid.net/specs/openid-connect-core-1_0.html"><strong>OpenID Connect</strong></a> for the authentication part. OpenID Connect 1.0 is an identity layer on top of the OAuth 2.0 protocol which is typically used for the authorization part. In the case of <strong>Authorization Code Grant Flow</strong> (which is our case), OpenID Connect 1.0 provides a special token called the <strong>id_token </strong>which is designed to provide an OAuth2 Client with the ability to perform user identity verification and log users in. In certain cases, OAuth2 can be used directly to log users in (as is the case with popular social login providers that do not implement OpenID Connect such as GitHub and Facebook).</p><p><strong>Spring Security OAuth 2.0</strong> Login feature lets an application have users log in to the application by using their existing account at an OpenID Connect 1.0 Provider (such as Keycloak). One of the flow of OAuth 2.0 Login is the <strong>Authorization Code Grant.</strong> The authorization code grant type is used to obtain both <strong>Access Tokens</strong> and <strong>Refresh Tokens</strong> and is optimized for confidential clients.</p><p>Following is an example of an authentication flow in this scenario</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vheBYj-l0Gih14ZKIc1-9A.png" /><figcaption>OIDC Authentication with OAuth2 Authorization Code Flow</figcaption></figure><blockquote>It’s important to notice that, in this scenario, using in particularly Spring Cloud Gateway, once the user has authenticated via Keycloak, it provides tokens for the user, including <strong>ID, Access</strong> and <strong>Refresh tokens,</strong> which are JWTs. <strong>These are not shared with the frontend</strong>, but are stored on the gateway and associated with the user’s session.</blockquote><blockquote>When the user logs in via Keycloak, Spring set a <strong>Session Cookie</strong> (with Spring Cloud Gateway is <strong>SESSIONID</strong>, not the classic JSESSIONID) on the browser. This session cookie is then sent from the browser to the API gateway for each request (the typical session cookie).</blockquote><blockquote><strong>When a request arrives at the gateway with the session cookie, Spring Cloud Gateway is able to retrieve in automatic user’s access token in user’s session and passed — always automatically — to the underlying services</strong>. And this is the magic of Spring Cloud Gateway! No JWT token is shared with the frontend. In addition, it can also use the <strong>Refresh Token</strong> provided by Keycloak to obtain a new Access Token when this one expires, all automatically! By automatically we mean with few lines of configuration.</blockquote><blockquote>Of course, as can you imagine, is an example of <strong>Stateful authentication.</strong></blockquote><h3>Authorization and Access Control</h3><p>As mentioned above, the APIs (endpoints) exposed by the microservices should also be protected. They are generally protected with JWT tokens, in the sense that it is generally only possible to call the APIs of a microservice if a valid JWT token is included in the request, usually with an Authorization Bearer Token Header. In the example application, <strong><em>Keycloak and Spring Security will take care of validating incoming JWT tokens</em></strong> to microservices. As mentioned, in this example the JWT tokens are never shared with the frontend but these can be retrieved automatically by Spring Cloud Gateway and passed to the underlying microservices.</p><h4>Protect microservices APIs — OAuth2 Resource Server</h4><p>All APIs of services in our example are protected by <strong>JWT Token </strong>with OAuth2 protocol. OAuth 2.0 provides a standardized way for applications to secure access to APIs. Services delegate authority management to an <strong>Authorization Service</strong> (in our case <strong>Keycloak).</strong> In OAuth2 protocol we have:</p><ul><li><strong>Resource Server</strong>: the server hosting the protected resources that the client wants to access. It validates the access token and provides the requested resources if the token is valid;</li><li><strong>Authorization Server</strong>: is the component in the OAuth 2.0 protocol which is responsible for managing access rights to protected resources.</li></ul><p>With Spring Security, by specifying the authorization server’s <strong>issuer-uri</strong> of the authorization server (something like follow), the resource server will discover the authorization server’s public keys, and then validate incoming JWTs.</p><pre>&lt;keycloak_uri&gt;/realms/&lt;realm_id&gt;)</pre><p>Below is a simple flow example of a request for access to protected resources on a Resource Server:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xlekhf-gco-ajD7bnq96gA.png" /><figcaption>Simple flow showing a request for a Protected Resource of an API</figcaption></figure><p>When a request arrives at the gateway, as explained above, it will retrieve the access token linked to the user’s session and call the API of the underlying services by passing the Authentication Bearer token.<br>If user’s access token has expired, Spring Security on the gateway retrieve a new Access Token for the user using the Refresh Token provided by Keycloak at authentication time.</p><h4>RBAC — Role Based Access Controls with Spring Security</h4><p>Another layer of security that is usually added to applications is one that checks the role of the user who is logged in and making a request. Several application roles are generally defined. Each new user created in the application is assigned one or more roles, and checks are then performed on the endpoints. At the API level, it is defined which user role can call a specific endpoint.</p><p>With Keycloak and Spring Security, access tokens are also used by the underlying services for the role-based user authorization part. Roles are defined on Keycloak, assigned to users and included in the access tokens. Roles are used by Spring Security for the authorization part. For example, we can say that a specific endpoint can be called only from user’s that have “Admin” role:</p><pre>@PreAuthorize(&quot;hasRole(&#39;ADMIN&#39;)&quot;)</pre><h4>Validation JWTs</h4><p>Resource Server will automatically configure itself to validate JWT Bearer Tokens. It achieves this through a deterministic startup process:</p><ul><li>Query the Provider Configuration or Authorization Server Metadata endpoint for the <strong>jwks_url</strong> property</li><li>Query the <strong>jwks_url </strong>endpoint for supported algorithms</li><li>Configure the validation strategy to query <strong>jwks_url </strong>for valid public keys of the algorithms found</li><li>Configure the validation strategy to validate each JWTs <strong>iss </strong>claim against the one specified in the configuration</li></ul><p>Once the application is started up, Resource Server will attempt to process any request containing an Authorization Bearer header:</p><pre>GET / HTTP/1.1 Authorization: Bearer some-token-value</pre><p>So long as this scheme is indicated, Resource Server will attempt to process the request according to the Bearer Token specification.</p><p>Given a well-formed JWT, Resource Server will:</p><ol><li>Validate its signature against a public key obtained from the jwks_url endpoint during startup and matched against the JWT</li><li>Validate the JWT’s exp and nbf timestamps and the JWT’s iss claim</li><li>Map each scope to an authority with the prefix SCOPE_.</li></ol><h3>Conclusions</h3><p>As mentioned, this is only one of many examples that can be given of a microservice architecture. Several other elements are generally present in business applications. What I like most is that I have never seen two identical application. Every time we design a new solution there be always new elements e new things to consider. So the legitimate question to ask when reading this article is: is this the right example to use for my application? And of course the answer is always the same… It depends.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c77c31a957fb" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Spring Security Basic Authentication and Authorization]]></title>
            <link>https://medium.com/@a.zagarella/spring-security-basic-authentication-and-role-based-authorization-04fa626f961a?source=rss-d6f1c90a0934------2</link>
            <guid isPermaLink="false">https://medium.com/p/04fa626f961a</guid>
            <category><![CDATA[microservices]]></category>
            <category><![CDATA[spring-boot]]></category>
            <category><![CDATA[spring]]></category>
            <category><![CDATA[authentication]]></category>
            <category><![CDATA[spring-security]]></category>
            <dc:creator><![CDATA[Andrea Zagarella]]></dc:creator>
            <pubDate>Wed, 31 Jan 2024 18:48:54 GMT</pubDate>
            <atom:updated>2024-02-28T11:43:05.810Z</atom:updated>
            <content:encoded><![CDATA[<p>In this article, we will look at how enable <strong>Basic Authentication </strong>and add <strong>Role-Based Authorization </strong>controls in a <strong>Spring Boot</strong> application using <strong>Spring Security, Spring Data JPA </strong>with <strong><em>Users and Roles persisted in a DB</em></strong>.</p><p>It’s not a comprehensive article that starts with the basics of creating a Spring Boot project and other such things. As title said, we will go straight to the practical implementation of the most important parts, taking some things for granted. You will definitely need a basic understanding of Spring Security.</p><figure><img alt="Simple flow diagram for Basic Authentication and role-based Authorization" src="https://cdn-images-1.medium.com/max/997/1*B3Tg1Q8huCyM_lvYJA4pLw.png" /><figcaption>Simple flow diagram for Basic Authentication and role-based Authorization</figcaption></figure><h3>Spring Security dependency</h3><p>First thing first: add the <a href="https://docs.spring.io/spring-security/reference/index.html">Spring Security</a> dependency to your classpath</p><pre>&lt;dependency&gt;<br>  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;<br>  &lt;artifactId&gt;spring-boot-starter-security&lt;/artifactId&gt;<br>&lt;/dependency&gt;</pre><h3>Create Role JPA Entity</h3><p>For role’s management of a specif user we create a JPA entity:</p><pre>@Data<br>@Entity<br>@Table(name = &quot;roles&quot;)<br>public class Role implements GrantedAuthority {<br>    @Id<br>    @GeneratedValue(strategy = GenerationType.IDENTITY)<br>    @Column(name = &quot;role_id&quot;)<br>    private Long id;<br><br>    @Column(name = &quot;authority&quot;)<br>    private String authority;<br>}</pre><h3>Customer Entity: personal and Authentication data</h3><p>Customer Entity is the model for managing User in our application. In Customer Entity add the implementation of the <strong>UserDetails</strong> interface (an interface provided by Spring Security) and a field to manage the role(s) of the specific user. This field on the Customer must be related to the Role table with a M<strong>any-To-Many relationship</strong>:</p><pre>@Data<br>@Entity<br>@Table(name = &quot;customers&quot;)<br>public class Customer implements UserDetails {<br><br>    @Id<br>    @GeneratedValue(strategy = GenerationType.IDENTITY)<br>    @Column(name = &quot;id&quot;, nullable = false)<br>    private Long id;<br><br>    @Column(name = &quot;password&quot;, nullable = false, length = 255)<br>    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)<br>    private String password;<br><br>    @ManyToMany(fetch = FetchType.EAGER)<br>    @JoinTable(<br>            name = &quot;customer_role&quot;,<br>            joinColumns = {@JoinColumn(name = &quot;customer_id&quot;)},<br>            inverseJoinColumns = {@JoinColumn(name = &quot;role_id&quot;)}<br>    )<br>    private Set&lt;Role&gt; authorities;<br><br>    @Column(name = &quot;email&quot;, nullable = false, unique = true, length = 100)<br>    private String email;<br><br>    @Column(name = &quot;phone&quot;, nullable = true, length = 15)<br>    private String phone;<br><br>    @Column(name = &quot;firstname&quot;, nullable = true, length = 45)<br>    private String firstname;<br><br>    @Column(name = &quot;surname&quot;, nullable = true, length = 45)<br>    private String surname;<br><br>    // #############################################<br>    // overrides part for UserDetails implementation<br>    @Override<br>    public String getUsername() {<br>        return getEmail();<br>    }<br>    @Override<br>    public boolean isAccountNonExpired() {<br>        return true;<br>    }<br>    @Override<br>    public boolean isAccountNonLocked() {<br>        return true;<br>    }<br>    @Override<br>    public boolean isCredentialsNonExpired() {<br>        return true;<br>    }<br>    @Override<br>    public boolean isEnabled() {<br>        return true;<br>    }<br><br>}</pre><h3>Role-Customer Joining table</h3><p>We let <a href="https://hibernate.org/orm/documentation/6.4/">Hibernate</a> and JPA create the joining table for us. We will be responsible for correctly initializing the roles of a new user created by the application.</p><p>This are the new two tables:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/211/1*c6kS9Nto1x0ligQQQKDizQ.png" /><figcaption>Joining table customer_role</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/261/1*C_hWVdKHzELQGo6lNWgOFw.png" /><figcaption>Roles table</figcaption></figure><h4>Some SQL INSERTs to populate the roles table and the customer_role Joining Table</h4><pre>INSERT INTO roles (role_id, authority) VALUES (1, &#39;ROLE_ADMIN&#39;);<br>INSERT INTO roles (role_id, authority) VALUES (2, &#39;ROLE_USER&#39;);<br><br>INSERT INTO customer_role (customer_id, role_id) VALUES (1, 1);<br>INSERT INTO customer_role (customer_id, role_id) VALUES (1, 2);<br>INSERT INTO customer_role (customer_id, role_id) VALUES (2, 1);<br>INSERT INTO customer_role (customer_id, role_id) VALUES (3, 2);</pre><h3>CustomerRepository JPA repository</h3><p>We need to create a <a href="https://spring.io/projects/spring-data-jpa">Spring Data JPA</a> repository for managing Customers in which we declare the findByEmail(String email) method used in the next step.</p><pre>@Repository<br>public interface CustomerRepository extends JpaRepository&lt;Customer, Long&gt; {<br>    Optional&lt;Customer&gt; findByEmail(String email);<br>}</pre><h3>UserDetailService implementation</h3><p>Create a new Service as follow which is responsible to retrieve user-related data. This Service which implement a Spring Security class (<strong>UserDetailService</strong>) has one method named <em>loadUserByUsername()</em> which can be overridden to customize the process of finding the user. It is used to load details about the user during authentication.</p><pre>@Service<br>@RequiredArgsConstructor<br>public class UserService implements UserDetailsService {<br><br>    private final CustomerRepository customerRepository;<br><br>    @Override<br>    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {<br>        return customerRepository.findByEmail(username)<br>                .orElseThrow(() -&gt; new UsernameNotFoundException(&quot;User not found&quot;));<br>    }<br>}</pre><h3>SecurityConfig class: Spring Security core with Basic Authentication</h3><p>After the previous steps, we must to create the configuration class that will be the core of the security managed by Spring Security.</p><pre>@Configuration<br>@EnableWebSecurity<br>@EnableMethodSecurity<br>public class SecurityConfig {<br><br>    @Bean<br>    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {<br>        http<br>                .csrf(AbstractHttpConfigurer::disable)<br>                .authorizeHttpRequests(authorize -&gt; authorize<br>                        .requestMatchers(getOpenedResources()).permitAll()<br>                        .requestMatchers(&quot;*/customers/register&quot;).permitAll()<br>                        .anyRequest().authenticated())<br>                .httpBasic(Customizer.withDefaults());<br>        return http.build();<br>    }<br><br>    @Bean<br>    public PasswordEncoder passwordEncoder() {<br>        return new BCryptPasswordEncoder();<br>    }<br><br>    @Bean<br>    public AuthenticationManager authenticationManager(UserDetailsService userDetailsService) {<br>        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();<br>        daoAuthenticationProvider.setUserDetailsService(userDetailsService);<br>        return new ProviderManager(daoAuthenticationProvider);<br>    }<br><br>    // some opened endpoints without authentication<br>    private String[] getOpenedResources() {<br>        return new String[]{<br>                &quot;/swagger-ui/**&quot;,<br>                &quot;/swagger-resources&quot;,<br>                &quot;/swagger-resources/**&quot;,<br>                &quot;/v3/api-docs&quot;,<br>                &quot;/v3/api-docs/**&quot;<br>        };<br>    }<br>}</pre><h3><em>Tips</em></h3><blockquote>To make your life easier, it is best to define roles with names like this in the DB:<br>- <strong>ROLE_ADMIN<br>- ROLE_USER</strong></blockquote><blockquote>If we don’t put a “ROLE_” prefix, we’ll need some code to manage that, because Spring Security manages roles with prefixes.</blockquote><h3>Authorization</h3><p>With everything configured correctly, we can now add Authorization layer of protection on the various endpoints to check the permissions of the connected user based on their role. To do this, simply add <strong>@PreAuthorize</strong> annotation like this to the various endpoints.</p><p>In the snippet above you can also see one way to retrieve current user from session (after of course user is authenticated with user and password):</p><pre>@GetMapping(&quot;/customer&quot;)<br>@PreAuthorize(&quot;hasAnyRole(&#39;ADMIN&#39;, &#39;USER&#39;)&quot;)<br>public ResponseEntity&lt;List&lt;OrderDTO&gt;&gt; getOrdersCustomer() {<br>  // one way to get the current Customer from session<br>  Customer currentCustomer = (Customer) SecurityContextHolder.getContext().getAuthentication().getPrincipal();<br>  Long idCustomer = currentCustomer.getId();<br>  List&lt;OrderDTO&gt; orders = orderService.getOrdersCustomer(idCustomer);<br>  return new ResponseEntity&lt;&gt;(orders, HttpStatus.OK);<br>}</pre><p>An even simpler way to get the user in session is to add <strong>@AuthenticationPrincipal</strong> as a method parameter:</p><pre>public ResponseEntity&lt;List&lt;OrderDTO&gt;&gt; getOrdersCustomer(@AuthenticationPrincipal Customer customer) {</pre><h3>Authentication</h3><p>If everything went well, from now on, every time you try to call any API from your browser for the first time you should see a popup requesting the username (email in our case) and password pair. By entering the correct credentials you will log into the application and from this moment the user session will be established:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/490/1*s73rY8O8qi6cAiZNKojbcQ.png" /><figcaption>Login</figcaption></figure><h3>Authentication with Postman</h3><p>If you use <a href="https://www.postman.com/downloads/">Postman</a> to test your API, for call any endpoints you should add the Authentication simply going in Authorization tab, click on Basic Auth and put the right credentials:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/987/1*je1eLmf_wgaN5CHBVtFkuw.png" /><figcaption>Postman login to API with Basi Auth</figcaption></figure><h3>Bonus</h3><p>As a bonus (let’s say bonus because it is not strictly related to the topics of the article) I will show you an example of a way to create a Customer with roles:</p><pre>public record CustomerRegistrationDTO(<br>        String email,<br>        String password,<br>        String firstname,<br>        String surname,<br>        String phone,<br>        boolean isUserAdmin<br>) {}</pre><pre>@PostMapping(&quot;/register&quot;)<br>public Customer registerCustomer(@RequestBody CustomerRegistrationDTO customerRegistrationDTO) {<br>  return authenticationService.registerCustomer(customerRegistrationDTO);<br>}</pre><pre>@Service<br>@Transactional<br>@RequiredArgsConstructor<br>public class AuthenticationService {<br><br>    private final CustomerRepository customerRepository;<br>    private final RoleRepository roleRepository;<br>    private final PasswordEncoder passwordEncoder;<br><br>    public Customer registerCustomer(CustomerRegistrationDTO customerRegistrationDTO) {<br>        String role = Boolean.TRUE.equals(customerRegistrationDTO.isUserAdmin()) ? &quot;ROLE_ADMIN&quot; : &quot;ROLE_USER&quot;;<br>        Role userRole = roleRepository.findByAuthority(role).orElseThrow(() -&gt; new NoSuchElementException(&quot;Authority not present&quot;));<br><br>        Set&lt;Role&gt; authorities = new HashSet&lt;&gt;();<br>        authorities.add(userRole);<br><br>        Customer newCustomer = new Customer();<br>        newCustomer.setEmail(customerRegistrationDTO.email());<br>        newCustomer.setPassword(passwordEncoder.encode(customerRegistrationDTO.password()));<br>        newCustomer.setAuthorities(authorities);<br>        newCustomer.setFirstname(customerRegistrationDTO.firstname());<br>        newCustomer.setSurname(customerRegistrationDTO.surname());<br>        newCustomer.setPhone(customerRegistrationDTO.phone());<br><br>        return customerRepository.save(newCustomer);<br>    }<br>}</pre><p>This is a very simple guide to Basic Authentication (probably the easiest type of Authentication to integrate on Spring Security but also one of the least secure) with Spring Security and Role-Based Authorization. In a real world scenario probably you don’t want to use this type of authentication.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=04fa626f961a" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>