j_spring_security_check are now legacy patterns; new projects more commonly use SAP Composable Storefront and external identity providers, while the security principles still apply.

When it comes to your overall website usability and providing a good user experience to your site visitors, the login component plays a very important role. This article explains how it should be built to provide the best customer experience.
The topic is purposely narrow. I focus on how to implement login forms and the authentication process in e-commerce systems built on top of SAP Commerce Cloud. In fact, the general recommendations and findings are applicable to other platforms too.
What makes a good sign-in experience for your customers? There are two pillars: good security and good user experience. Backed by the platform and Accelerator built-in features, many developers and product owners prefer to minimize the number of customizations and stick with out-of-the-box functionality. This strategy works well only if you need to release your product in the shortest possible time.
From the authentication perspective, best practices recommend offering users the ability to check out as a guest and/or forcing or inviting them to register before completing the purchase or after it. Fundamentally, customer authentication is important for the next visits of a customer. Very often, customers don’t see any benefits of being authenticated. Many of them prefer to check out as guests and minimize the information they share about themselves. That is why it is becoming more and more important for merchants to respect and protect customer data.
For B2C websites, forcing users to register first may lead to a decrease in conversion rates because it breaks the buying process. In B2B solutions, it is a primary and widely used option because guest users are normally not involved in the B2B process at all.
The login form is a very important piece of the interface, and implementing it properly is crucial for success.
You may ask: how can one make a mistake in such a simple thing? In this research, I analyzed different implementations and technologies, common mistakes, and strategies.
- Overview
- Implementation
- Login Form in SAP Commerce
- Authentication Flow in SAP Commerce Cloud
- Remaining Logged In / Remember Me
- More details on j_spring_security_check implementation in hybris
- Importance of HTTPS
- Feedback Messages
- Password Strength
- Brute Force Attack Protection
- Storing Passwords
- Third-party Identity Providers and Identity Federation
- Browser APIs for authentication
This article is the third in a series. Please find the other two if you are interested in the broader area:
- Autocomplete, Live Search Suggestions, and Autocorrection: Best Practice Design Patterns
/2019/01/08/autocomplete-live-search-suggestions-autocorrection-best-practice-design-patterns/ - Facet Search: The Most Comprehensive Guide. Best Practices, Design Patterns, Hidden Caveats, And Workarounds
/2019/02/13/facet-search-the-most-comprehensible-guide-best-practices-design-patterns/
Overview {#Overview}
Session Handling Methods Used with Authentication {#SessionHandling}
Let’s start with a short overview of authentication methods from the perspective of session handling methods on the Web.
Session-based authentication (stateful) {#SessionBased}
A session is defined as the time during which a user is actively logged onto a server with a cookie. So, session-based authentication is one in which the user state is stored in the server’s memory. That is why it is also called stateful.
The typical flow is the following:
- User enters the login and password.
- Server authenticates the user, generates a random token, and sends it to the browser/client app.
- Server saves the token in the database or memory.
- Browser/ClientApp receives the token and stores it in cookies/local storage. Browser/ClientApp sends this token with each subsequent request along with other relevant cookies.
- Server uses the token to authenticate the user and return the requested data back to the Browser/ClientApp.
- When the User logs out, the token is removed from cookies/local storage, and subsequent requests won’t have it. The server won’t return the protected information to the user until the user is authenticated again.

The advantages of this approach are:
- The session can be revoked anytime.
- Session parameters, such as user permissions, can be changed anytime.
- The solution is easy to implement, especially for a single-server setup.
However, this approach doesn’t work well for a very large number of concurrent sessions. As the number of logged-in users increases, you need more and more server resources. Scaling and distributing the sessions over a cluster introduce new challenges, such as supporting sticky or distributed session management. This type of authentication has been elaborated well, and there is a solution for every case, but every complication creates a bunch of new challenges.
SAP Commerce Cloud uses session-based authentication for customer sign-in and session management.
Token-based authentication (stateless) {#TokenBased}
Token-based authentication is used to address the disadvantages of session-based authentication. In brief, in token-based authentication, the user session data is stored on the client side, in the browser. This data is signed by the key of the IdP to ensure the integrity and authority of the session data.
The process is the following:
- User enters the login and password.
- Server authenticates the user, generates a signed token, usually JWT, pronounced “jot,” and sends it to the browser/ClientApp. Unlike session-based authentication, the token does contain additional information, such as
user_idand permissions. It is important that the token is cryptographically signed and that changes in the token made by a third party are easily discoverable. - Browser/ClientApp receives the token and stores it in cookies/local storage. Browser/ClientApp sends this token with each subsequent request as an
Authorizationheader in the form ofBearer {JWT}. - Server decodes the token and uses the information from the token to authenticate the user and return the requested data back to the client application.
- When the User logs out, the token is removed from the browser/ClientApp.

The session data is effectively distributed in this option. It allows storing more information about the user on the client side. Token generation is decoupled from token verification. It allows you to handle the signing of tokens on a separate server or service.
However, you can’t revoke the session easily in token-based authentication. Changing user data is challenging too. For example, you may want to add a new user session property. All new sessions will take this property, but existing sessions will keep sending the obsolete set until the session is re-established.
In SAP Commerce Cloud, token-based authentication is not used.
Authentication methods {#AuthMethods}
The methods explained below can be used in different combinations. When the user is authenticated, the server initiates a session using the approaches explained above.
Certificate-Based Authentication {#CertificateBased}
This authentication method is based on SSL certificates.
- User enters the private-key password.
- Browser signs the request with a digital signature.
- Browser sends the certificate and digital signature across the network.
- Server uses the certificate and digital signature to authenticate the user’s identity.
- Server authorizes access if the signature is correct and the certificate is valid.

Password-based authentication {#PasswordBased}
This authentication method is based on the “secret” pair of the login and password.
- Browser’s dialog box requests the user’s name and password from the user.
- User provides a name and password.
- Browser sends the name and password across the network.
- Server looks up the name and password in its local password database and, if they match, accepts them as evidence authenticating the user’s identity.
- Server allows the user to access it if the identified user is permitted to access the requested resource.

Passwordless authentication {#Passwordless}
In passwordless authentication, the user’s identity is verified without asking the user to provide a password. For this method, it is implied that only the user has access to a personal physical device that is uniquely addressable and can communicate securely with the server over a distinct communications channel, referred to as the secondary channel.
- User enters the email, phone number, or ID in the authentication app.
- Server sends them a one-time-use link with the code to that email, texts a code to the phone number, or sends a code to the authentication app. The user clicks the link or enters the code received from the system. Basically, the trigger is the code returned back to the app. This operation can be done only if the User confirms the authentication intent on the personal device or mail client. The system assumes that you will get the login link from your inbox or a code from the text message only if the email provided is indeed yours.
- User is automatically logged in to your website/application.

Authentication stacking methods {#AuthStaking}
Single Factor Authentication (SFA) {#SingleFactor}
The most common form of this authentication is the password-based authentication explained above.
Two Factor Authentication (2FA) {#TwoFactor}
Two-factor authentication, also called two-step verification, is an upgrade to password-based authentication by adding an extra step to the sign-in process: the second factor.
The most common form of two-factor authentication is mixing password-based authentication with a passwordless approach using SMS services. This assumes that the user has a personal device, a mobile phone, nearby each time the system requests a second verification.
Multi-Factor Authentication {#MultiFactor}
With this method, the authentication credentials are combined from:
- Something the user knows: a password or PIN.
- Something the user has: the customer’s device.
- Something the user is: biometric verification.
Authentication in distributed systems {#AuthDistributed}
Single Sign-On (SSO) {#SSO}
The idea of Single Sign-On describes the ability to use single authentication to gain access to a number of websites. The products authenticate users in a single location and then create tokens that can be used by downstream web applications for authorization.
In this method, there is a central service that orchestrates the single sign-on between multiple clients. When a user first logs in, the central service creates a token, which persists with the user as they navigate to the various websites integrated with the same SSO service.
- User enters the login and password.
- Server authenticates the user and generates a token, but the token is stored on the SSO domain, which is different from the app domain.
- Server uses the token from the SSO domain to authenticate the user trying to access the particular app.
Social Sign-in is a form of SSO using existing account information from social networks such as Facebook, Twitter, or Google+ to sign in to a third-party website instead of creating a new account specifically for that website.
There is no SSO implementation for customers in the default SAP Commerce Cloud. The OOTB support of SAML-based SSO was designed for Backoffice users. The extension for that is provided with Commerce Cloud.
By the way, I published an article on Okta/hybris integration to support customer SSO: /2016/06/15/hybrisokta-sso-integration/
Implementation {#Implementation}
Login Form in SAP Commerce {#LoginForm}
The default login form is very basic in the default SAP Commerce. It contains three essential form controls:
- Input box j_username for a customer ID, which is a customer’s email.
- Input box j_password for a password.
- A submit button.
The form action is /j_spring_security_check. This login processing URL is specified in the configuration.
There is also a link to “Forgotten password.” The form doesn’t contain a “Remember Me” link.
Recommendations:
- Consider adding a required attribute to the input fields. This way, a customer won’t be able to submit the form if the value of an input is empty.
- Consider adding a minlength attribute to the password field to improve in-browser validation.
- Consider adding an aria-describedby attribute to provide an accessible description for the username and password fields.
- Consider adding
type="email"if the login is supposed to be an email. With this type, the on-screen keyboard will be automatically adjusted for entering the email address. - Consider adding an autocomplete attribute for both fields so the password manager will offer autocomplete.
- If the username is an email address, tell that to a customer in a label next to the input.
- Make sure a focused element is always highlighted somehow. Although browsers outline focusable elements by default, you might want to apply your own custom CSS style using
selector:focus {}. - Keep the keyboard navigation order logical and intuitive. It should follow the visual flow of the page: left to right, top to bottom.
- Use only elements that can receive keyboard focus. See https://www.w3.org/TR/wai-aria-practices/#keyboard and https://webaim.org/techniques/keyboard/ for details.
- To avoid mistyping:
- Tell users if Caps Lock is on.
- Let users see their password by providing a show-password checkbox.
- Show password constraints upfront and update them in real time.
Authentication Flow in SAP Commerce Cloud {#AuthFlow}
The default SAP Commerce storefront is built on top of JavaServer Pages and the Spring Framework. Almost everything the developer should care about in login forms, authentication, and system activity authorization involves Spring Security. SAP Commerce comes as a preconfigured solution implementing a common scenario of customer authentication.
For the sake of consistency, let’s review the basic authentication flow.
In the SAP Accelerator, /login is configured as a login page URL. The website has a number of protected pages, listed in the configuration. When an anonymous user attempts to access the protected page, and Spring Security finds the user is not authenticated, the system redirects them to the login page to be logged in. Of course, the login page can be accessed directly by visiting /login, a link behind the “Sign in” button.
With the first request to the server, the system initiates a session. The session is stored on the application server level. The application server, Apache Tomcat, sends the unique identifier of the session back to the browser. This unique identifier is a 26-character hash key into the server’s map of active sessions. This key is stored in JSESSIONID.
On the login page, the user is challenged to provide login credentials. When the form is submitted, the server verifies the login and hashed password against the database. If a match is found, the system saves the information into the HTTP session and returns an acceleratorSecureGUID cookie with a random value. This cookie carries the information that the customer is logged in.
Next time the user requests a page, the browser will send JSESSIONID and acceleratorSecureGUID in the request header, so the server will be able to identify the session, extract acceleratorSecureGUID from the session, and compare the value with the one received with the request. If there is a match, the system will check whether the logged-in user from the session has enough permissions to get to the page. Session parameters, such as session variables, are used to store the session user parameters.
The login processing URL is specified in the configuration. By default, it is /j_spring_security_check. This URL is mapped to UsernamePasswordAuthenticationFilter to serve the requests. There are two parameters for the filter used from the form. In the SAP Commerce configuration, these are j_username and j_password. Depending on the authentication status, the Spring Framework executes one of two methods:
- Failure:
…yacceleratorstorefront.security.LoginAuthenticationFailureHandler.onAuthenticationFailure(req, resp, exception)
- Success:
…acceleratorstorefrontcommons.security.GUIDAuthenticationSuccessHandler.onAuthenticationSuccess(req, resp, authentication)- Sets up an
acceleratorSecureGUIDcookie with a random GUID. - Calls the default
StorefrontAuthenticationSuccessHandler, which sets up a session customer, merges the carts and session parameters, and publishes the login event. The user is redirected to the target URL, or to the default if none is present.
- Sets up an
For logging out, there is a dedicated URL, /logout. It is mapped to StorefrontLogoutSuccessHandler. When logging out from a restricted page, the user is returned to a home page.
Read more on Spring Security in SAP Commerce: https://help.sap.com/viewer/4c33bf189ab9409e84e589295c36d96e/1811/en-US/8aef3efe8669101481a0ffe871a2f84c.html
Remaining Logged In / Remember Me {#RememberMe}
The concept of the “remember me” feature is that the authenticated state is persisted beyond the immediate scope of use. Customers can close the browser, turn off their PC, then come back later, and the web shop still knows who they are and offers them all the same features they had when they left it. In the login form, this functionality is represented by the “Keep me logged in” checkbox.
In SAP Commerce Cloud, the default login form doesn’t have a “remember me” checkbox, but the functionality is present and on by default. The Accelerator storefronts support the “Soft Login” concept, which automatically logs a customer into the storefront based on a *rememberMe cookie, for example, yb2bacceleratorstorefrontRememberMe for the OOTB B2B. It uses the Spring TokenBasedRememberMeServices implementation.
After the user is logged in, the system sends this *rememberMe cookie to the browser, and the value of the cookie contains a username along with the hashed password and some other information. When the session is over, the authentication mechanism will use the rememberMe cookie to re-authenticate the customer automatically. The rememberMe cookie is Base64-encoded, so the username is extracted easily using a Base64 decoder.
The rememberMe cookie-based authentication is called “soft” to distinguish it from hard authentication based on the password. A softly authenticated customer needs to provide a password and log in fully to access account-related functionality or proceed through checkout.
Signing out removes the rememberMe cookie completely from the browser.
More details on j_spring_security_check implementation in hybris {#MoreDetails}
The login and password are sent as POST to:
/<storefrontcontext>/powertools/en/USD/j_spring_security_check
The SAP Commerce Cloud Spring configuration tells us that /j_spring_security_check is mapped to springSecurityFilterChain.
There are tens of standard storefront filters processed. I would like to feature some of them that are important in our context:
- CSRF token check filter (
CsrfFilter) - Logout Filter
- Authentication Processing filter (
UsernamePasswordAuthenticationFilter, which extendsAbstractAuthenticationProcessingFilter) - RememberMe Authentication Filter
- Anonymous Authentication Filter
Csrf Filter {#CsrfFilter}
The filter checks if the URL is in the list of URLs where the CSRF check shouldn’t be involved. The property names csrf.allowed.url.patterns and csrfAllowedUrlPatternsList specify URL patterns that allow you to bypass CSRF token validation. These URLs are the ones ending with …sop/response, …merchant_callback, …hop/response, …language, and …currency. Since /j_spring_security_check is not in the list, the system compares the value from the HTTP session and a value from the form. If they are different or the CSRF token is not present, the system stops the request processing with the corresponding exception.
Logout Filter {#LogoutFilter}
This filter performs logout for the user if the request URL matches the particular pattern, /logout by default.
Authentication Processing filter {#AuthProcFilter}
This filter intercepts the authentication URL processing. By default, it is j_spring_security_check. For username and password mode, it retrieves the credentials from the form data and passes them through the authentication provider, which performs the following checks:
- Admin authority? Reject if yes.
- Outside the allowed user types? Reject if yes.
- B2B: Outside the authorized groups for B2B? Reject if yes.
- B2C: Outside the customer group? Reject if yes.
- User is disabled? Reject if yes.
- Username doesn’t exist? Reject if yes.
- Credentials are not valid? Reject if yes.
These checks are provided by the B2B Accelerator Authentication Provider, the B2B Accelerator add-on, and the Core Authentication Provider, the platform core.
Abstract Accelerator Authentication Provider increments the counter of failed attempts and disables the account after the configured number of attempts, providing brute-force attack protection.
RememberMe Authentication Filter {#RememberMeFilter}
The concept of RememberMe has been explained above. The filter is responsible for activating the feature in the solution.
This filter is part of the Spring Framework. SAP Commerce uses it as is but configures the filter with a custom RememberMe Services class, AcceleratorRememberMeServices.
When a registered user logs in to the storefront, a <storefront>RememberMe cookie is created by the Remember Me services to identify the user. When the user logs out, this cookie is cleared out. However, if an authenticated user closes their browser without logging out, and the user attempts to visit a specific page in the storefront again, when the request is made for this secure resource, the RememberMe Authentication Filter injects the RememberMe authentication token into the session when loading the storefront.
Anonymous Authentication Filter {#AnonymousFilter}
This is a Spring Framework filter. It creates a filter with a principal named anonymousUser and the single authority ROLE_ANONYMOUS. SAP Commerce uses it as is.
Importance of HTTPS {#https}
Possibly, this topic may seem trivial, but when you start scratching the surface, there are a lot of important details to learn.
For the login form, HTTPS is a must. Otherwise, your password will be sent in clear text. It means that anyone eavesdropping on the line between you and the server will be able to intercept and read your password. This technology is called wiretapping or packet sniffing. So, if the line between the user and server is unencrypted, everything you do is vulnerable to man-in-the-middle attacks. The only protection is using a certificate-based secure connection.
It’s not enough to submit the login form over HTTPS. It is very important to deliver the form itself over HTTPS too. If the login form is delivered over a non-secure channel, someone “in the middle” between you and the server can inject JavaScript code, such as a keylogger, to steal the credentials by sending everything you type in the form or changing the form submission location. There is no easy way to protect against keyloggers, so it is better to follow the recommendations and encrypt the login form to make this attack impossible.
Additionally, Google Chrome and Firefox have already marked non-secure pages containing password input fields as Not Secure in the URL bar. Additionally, HTTPS is a confirmed Google ranking factor: secure websites are higher in the search results.
That is why SAP Commerce Cloud default settings include preconfigured HTTPS. By default, SAP Commerce Accelerator secures all storefront pages using HTTPS. Previous versions of the Accelerator only secured the Checkout and My Account pages using HTTPS.
In production setups, SSL is highly recommended to terminate at the load balancer level. It is not only convenient, because you can manage certificates centrally, but also offers a centralized place to correct SSL attacks, such as CRIME (https://en.wikipedia.org/wiki/CRIME). Terminating SSL at a variety of web servers running on different operating systems will likely run you into problems due to the additional complexity. So, the best practice is having an SSL-enabled load balancer and a non-HTTPS SAP Commerce app.
- https://help.sap.com/viewer/4c33bf189ab9409e84e589295c36d96e/1811/en-US/8aef3efe8669101481a0ffe871a2f84c.html for how to disable HTTPS everywhere.
Feedback Messages {#FeedbackMessages}
If the user enters all data correctly and gets logged in, the redirect happens on the server side to the requested page or a default after-login page. It is a good practice to show a success message at the top of the page so the customer knows immediately that the login was successful.
As for form validation during input, it is a good practice to show an error message if:
- username fails to match the required pattern, such as email; or
- password is shorter than required, for example, an 8-character minimum for the password; or
- password or username is empty.
For the failed login attempt, the application might respond with the reason, such as an incorrect password or unrecognized username. This behavior might look like a good intention to help users understand what was wrong. However, it is not recommended: an attacker can use it to iterate through a list of common usernames to find valid ones. This list can be used for various attacks, including password guessing, attacks on user data or sessions, or social engineering. That brings us to brute-force attack protection.
If the account is locked or the validity period is over, show the relevant message with instructions on what to do to make it live again.
Password Strength {#Passwords}
Although checking password strength is a little bit off topic, because it is related to the registration form rather than to the sign-in process, I’ve decided to add it to my overview because it is rather important.
Implementing a good authentication mechanism based on passwords is challenging. Users’ safety heavily relies on how they create their passwords. Their passwords could be weak, forgotten, reused, or stolen. According to Google, during a period of just one year, the data breach exposed a total of 1.9 billion usernames and passwords.
If minimum strength requirements are not part of your password policy, you will have about 2% of users who use one of the top 20 most common passwords. It means that if an attacker gets just 20 attempts, one in fifty accounts on your website will be crackable.
Recommendations:
- Use Java and JavaScript libraries for checking password strength, such as ZCXVBN, a multi-platform library for checking password strength: https://github.com/dropbox/zxcvbn.
- Showing a visual strength meter to a user is insufficient. If it is not enforced, many customers will most likely ignore it.
- If the password doesn’t meet the minimum password length requirements, show the error while the password is being typed. It will reduce the number of failed attempts.
- Don’t use third-party password strength meters. In many cases, this is a potential security breach.
- Require passwords to contain at least 8 characters and a combination of upper/lower-case letters, numbers, and symbols. However, don’t use too many security rules.
- Show the requirements next to the password field in the registration form.
More information:
- https://nakedsecurity.sophos.com/2015/03/02/why-you-cant-trust-password-strength-meters/
- https://en.wikipedia.org/wiki/List_of_the_most_common_passwords
- https://github.com/dropbox/zxcvbn.
Brute Force Attack Protection {#BruteForceProtection}
A brute-force attack is an attempt to discover user credentials by automatically and systematically trying different combinations of usernames and passwords with the intent to discover the one correct combination that works. This attack uses dictionary words or lists of common combinations. Besides putting your users at risk, this attack floods the website with unnecessary traffic.
So there are two sides to the problem:
- How to stop brute-force attacks.
- How to protect customers from the attacks if they happen.
For the second goal, first and foremost, enforce strong passwords for all users, and a brute-force attack will not succeed. Brute-force attacks can be stopped before the requests reach the application server. The solutions for that are often provided by cloud hosting providers.
There are a number of techniques for preventing brute-force attacks.
The simplest and most obvious way to block such attacks is locking out accounts after a defined number of incorrect password attempts. This is exactly how it is implemented in the default SAP Commerce. Such a policy can give rise to further vulnerabilities. An attacker is able to lock out real accounts. It will deny access to a system for many accounts and flood the help desk with support calls. Additionally, an attacker can use this fact to harvest usernames from the website, depending on the error responses. Once the account is unblocked, the attacker can block it again, effectively disabling the account. Marking the accounts as blocked repeatedly can result in a lot of write processes, which can be another performance bottleneck. User lockout is ineffective against slow attacks when only a few combinations are tried every hour. It is also ineffective for attacks when the same password is tried with a combination of thousands of usernames. So, account locking is bad and not a practical solution at all, but it can be efficient for simple cases only.
Another protection, or rather a sort of complication for the attacker, that SAP Commerce Cloud has is Anti Cross-Site Request Forgery, or anti-CSRF, tokens, also called request verification tokens. SAP Commerce Cloud protects the login form with an anti-CSRF token out of the box. The server includes two tokens in the response for the form. One token is sent as a cookie. The other is placed in a hidden form field named CSRFToken in SAP Commerce. The tokens are generated randomly. When the customer submits the login form, it sends these tokens back to the server. The client sends the cookie token as a cookie, and it sends the form token inside the form data. The server validates the pair, and if they don’t match, it throws a CSRF error. So, there is nothing preventing the attacker from repeatedly visiting the login page and getting a new, valid anti-CSRF token each time.
There are different solutions for that, but all of them have the same problem: during design and development, stakeholders often don’t consider the risks of brute-force attacks important.
Another problem is that many known solutions are efficient only against simple attacks and non-dedicated attackers.
Identifying and locking IP addresses with multiple failed logins may look efficient at first glance, but in fact, it has its flaws too: you can inadvertently block large corporations that use the same proxy server for all their employees, your customers. Even a simple CAPTCHA is effective, but bear in mind that CAPTCHAs slow down the customer experience and affect conversion negatively. Additionally, attackers use automated and semi-automated CAPTCHA solvers, which are getting cheaper year over year.
Not all CAPTCHAs slow down the customer experience. Google has recently updated its reCAPTCHA verification tool to its third version. You don’t need to waste time and frustration solving a puzzle to prove you are a real human each time. The new mechanism allows you to weed out harmful traffic generated by bots silently and transparently. “reCAPTCHA v3 returns a score for each request without user friction,” Google said of the update on its developer page. “The score is based on interactions with your site and enables you to take appropriate action for your site.”
I recommend using the following strategies:
- Force secure passwords. Use zxcvbn.
- Present a CAPTCHA after N failed attempts.
- Lock the account and require email verification after M failed attempts, where M > N. Make this feature disableable by the administrator in minutes.
- Warn users before their account is locked.
- Use login throttling: set a time delay of K seconds between attempts after K failed attempts, where K < N.
- Have a quick way to add additional validation to the form or change it through configuration without redeploying the system. It will make the attacker reconfigure the attacking software on their side, which is generally more expensive than your quick change in the admin panel. For example, changing the name of the form field or login URL will efficiently fool the automated software used by attackers.
Consider a third-party authentication provider, such as Okta, and Web Application Firewall solutions, such as WAF from Imperva. Both have a range of security measures and constantly improve them.
Storing Passwords {#StoringPasswords}
Of course, there is no need to explain that passwords must be stored encrypted.
There are only four password hashing algorithms that are currently trusted by professional cryptographers and security researchers to protect users’ passwords: Argon2, winner of the Password Hashing Competition; bcrypt; scrypt; and PBKDF2, Password-Based Key Derivation Function #2. OWASP recommends the use of Argon2 as your first choice for new applications. If this is not available, PBKDF2 or scrypt should be used instead. Finally, if none of the above are available, use bcrypt. Among these, SAP Commerce Cloud supports PBKDF2, and this is the default strategy. All others are not supported out of the box but can be added easily if needed.
However, hashes by themselves are also insecure. For example, for the same passwords you will have identical hashes. To address this issue, the system can use a salted hash where a salt, a string appended to the password prior to hashing, is different or random per user. SAP Commerce uses the SHA1PRNG algorithm for generating a salt for passwords.
Third-party Identity Providers and Identity Federation {#3rdidp}
Identity Federation is a way for users to sign in using an account hosted on a third-party website, which is called an identity provider. You can delegate the security challenges to the identity provider, and you can receive profile information from it.
There are a number of services offering authentication services via APIs. This option works great if a large number of your customers have an account in such services, especially if they have already logged in there. It’s believed that the vast majority of typical internet users have an account in at least one of the three services: Facebook, Google, and Twitter.
For example, the authentication flow for Facebook based on OAuth2 works as follows:
- User clicks the Facebook login button. The system redirects to Facebook.com’s login page:
https://www.facebook.com/dialog/oauth?client_id={client_id}&redirect_uri=mysite.com/fblogin&response_type=code - User enters the login and password.
- Facebook authenticates the user, generates a random token, and sends it back to the user through the callback URL.
- User is redirected to the Server’s callback URL.
- Server requests the access token from Facebook using the code provided:
https://graph.facebook.com/oauth/access_token?client_id={client_id}&redirect_uri=http://mysite.com/fblogin&client_secret={client_secret}&code={code} - Server requests the user profile details from Facebook using the access token:
https://graph.facebook.com/me?access_token={access_token}
However, if you use more than one provider, or you plan to use password-based authentication with third-party identity providers, we have a problem: how to merge different authentications if there is no single key. The data the social networks provide is provider-specific, and almost everything is optional.
Your app may need to handle more complex situations, such as:
- A customer signs up using their email and password but later chooses to use a third-party auth provider or social login for signing in.
- A customer signs up using a third-party identity provider or social login and later wants to log in to this account using an email address and password assigned by the e-shop.
It is possible that the customer used a different email to create their existing account than the one they have associated with their auth provider or social account or accounts. In this case, you should offer an “Account merging” option in the My Account area and allow the customer to manually specify the accounts that they wish to merge.
The system should also have the ability to unlink a third-party identity provider or social account or accounts from their normal in-store login account. The external account should be automatically unlinked from the login account when it gets associated with a new login account.
Third-party identity providers and social networks don’t always share the most merge-friendly data with apps. For example, Twitter doesn’t share the user’s email. Even if the email is technically provided, there is a case where users use different emails for different accounts. They can also decide to remove or hide the email associated with the account, as in Facebook or LinkedIn. Each provider limits access to user data from the application side. This is presented in the form of scopes, such as profile data, email addresses, age ranges, etc. In other words, the defined scope gives the application access to a specific set of data.
For this problem, there are three solutions:
- Let customers merge their accounts via My Account.
- Ignore the problem and let customers have multiple accounts.
- Have the system identify duplicate accounts and prompt the user to connect them.
So the truth is that it’s impossible to effectively merge social account data. Often, customer service is not capable of linking or merging the accounts either because there is no simple way to validate over the phone if a caller and the social account holder are the same person.
The last option cannot be implemented reliably. The profile data provided by the social network does not always have a reliable key for merging. The email address is not shared by some social networks, and all other information can be faked easily.
So the best option is to let customers link their social accounts to the profile.
Many websites require you to link the accounts after you sign in using the third-party identity provider. For example, if you log in using Google Account, the system will ask you to log in with the native Best Buy account to link them together.
Social logins are not supported by SAP Commerce Cloud out of the box, nor are third-party authentication provider integrations.
List of OAuth providers:
- https://en.wikipedia.org/wiki/List_of_OAuth_providers
- https://en.wikipedia.org/wiki/List_of_single_sign-on_implementations
- https://github.com/zapier/google-yolo-inline
Browser APIs for authentication {#browserapi}
There are a number of initiatives to standardize an interface for authenticating users to web-based applications and services using public-key cryptography. The new approach is not only to bypass the need for passwords but also to keep login data local to protect it from server hacks or interception.
The most interesting topic in this area is WebAuthn, Web Authentication, a new web standard published by the W3C. The technology is already supported in developer preview versions of Safari, as well as Chrome, Firefox, and Edge. Android and Windows 10 have the technology built in.
This cutting-edge topic deserves a separate article to review. Currently, we are experimenting with it and will share the details soon. Stay tuned!