Technical Articles
Customize SAP Cloud Platform Identity Authentication (IAS) UI
In this article you will learn how to customize the SAP IAS UI and integrate it seamlessly into your corporate design. I will show you how to setup IAS with a custom theme, how to create the theme and what the layout looks like.
Getting Started
First of all you need to go to your IAS tenant administration page:
https://your-tenant.accounts.ondemand.com/admin/
Please replace “your-tenant” with the tenant identifier of your own tenant.
Then navigate to “Applications & Resources” – “Custom CSS”:
Initially there will be no style sheets and therefore an empty list.
Creating a Custom Style
Start by downloading the default style.
We want to transform the default style:
into our custom style:
Please note that the provided stylesheet is just a prototype and needs to be further refined. I leave that as an exercise for you š
Source Code Login Page
Keep in mind that the actual source code may vary depending on your IAS configuration (required fields etc.).
<html lang="en" class=" ids-js ids-flexbox ids-no-touch ids-svg">
<head>
...
</head>
<body data-page="ids-login/logon" data-pagetype="Login" data-spid="..."
data-spname="oac.accounts.sap.com" style="">
<main class="ids-main">
<div class="ids-main__content">
<div aria-labelledby="ids-heading-1" class="ids-container" role="dialog">
<div class="ids-login-container">
<div class="ids-login-sp">
<div class="ids-login-sp__sp-name">
<h1 class="ids-heading-2" id="test-service-provider-name">Administration Console</h1>
</div>
<div class="ids-login-sp__cta"></div>
</div>
<div class="ids-login-login ids-login-login--border">
<div class="ids-login-widget">
<h1 class="ids-heading-1 ids-heading-1--login" id="ids-heading-1">Log On</h1>
<form id="logOnForm" autocomplete="off" role="form" class="ids-form ids-form--login"
action="/saml2/idp/sso" accept-charset="UTF-8" method="post"><input name="utf8"
type="hidden" value="ā"><input type="hidden" name="authenticity_token"
value="...">
<div class="js-global-flashes-area" id="globalMessages"></div>
<fieldset class="ids-fieldset ids-fieldset--login"><input type="hidden"
id="hidden-xsrfProtection-field" name="xsrfProtection"
value="..."><input
type="hidden" name="method" value="GET"><input type="hidden"
name="idpSSOEndpoint"
value="https://....accounts.ondemand.com/saml2/idp/sso"><input
type="hidden" name="sp" value="oac.accounts.sap.com"><input type="hidden"
name="RelayState"
value="https://....accounts.ondemand.com/admin/#/cssDocs/Custom_Style"><input
id="targetUrl" name="targetUrl" type="hidden" value=""><input id="sourceUrl"
name="sourceUrl" type="hidden" value=""><input id="org" name="org" type="hidden"
value=""><input id="spId" name="spId" type="hidden"
value="..."><input id="spName" name="spName" type="hidden"
value="oac.accounts.sap.com"><input id="mobileSSOToken" name="mobileSSOToken"
type="hidden" value=""><input id="tfaToken" name="tfaToken" type="hidden"
value=""><input id="css" name="css" type="hidden" value="Custom_Style">
<div class="ids-input-group ids-input-group--text ids-input-group--login ids-input-group--user"
id="j_username-group">
<div class="ids-label-container"> <span class="ids-label-wrap"> <label
class="ids-label" for="j_username" id="j_username-label"> E-Mail
</label> </span> </div>
<div class="ids-control-container"> <input autocomplete="off"
class="ids-input ids-input--text ids-input--clear js-has-input-clear js-login-toggle-active-input-user"
id="j_username" name="j_username" placeholder="E-Mail" type="text"
value="">
<p class="ids-error-block" id="j_username.errors"> </p> <a
class="ids-input-clear js-input-clear" href="#" tabindex="-1"></a>
</div>
</div>
<div class="ids-input-group ids-input-group--text ids-input-group--login ids-input-group--password"
id="j_password-group">
<div class="ids-label-container"> <span class="ids-label-wrap"> <label
class="ids-label" for="j_password" id="j_password-label"> Password
</label> </span> </div>
<div class="ids-control-container"> <input autocomplete="off"
class="ids-input ids-input--text ids-input--clear js-has-input-clear js-login-toggle-active-input-password"
id="j_password" maxlength="255" name="j_password" placeholder="Password"
type="password">
<p class="ids-error-block" id="j_password.errors"> </p> <a
class="ids-input-clear js-input-clear" href="#" tabindex="-1"></a>
</div>
</div>
<div class="ids-input-group ids-input-group--checkbox ids-utils-centered"
id="rememberme-group">
<div class="ids-control-container">
<ul class="ids-input-group__items" role="group">
<li class="ids-input-group__item"> <span
class="ids-checkbox-container--option"> <input id="rememberme"
name="rememberme" type="checkbox"> </span> <span
class="ids-label-container--option"> <span
class="ids-label-wrap"> <label class="ids-label"
for="rememberme" id="rememberme-label"> Remember me
</label> </span> </span> </li>
</ul>
<p class="ids-error-block" id="rememberme.errors"> </p>
</div>
</div>
</fieldset>
<div class="ids-button-group ids-button-group--centered ids-button-group--login"><button
class="ids-button ids-button--primary ids-button--login js-button-login"
id="logOnFormSubmit" role="button" type="submit">Log On</button></div>
</form>
</div>
<ul class="ids-login-section">
<li class="ids-login__forgotpassword"><a alt="Forgot password?"
href="/ui/createForgottenPasswordMail?spId=...&targetUrl=&sourceUrl="
id="forgotPasswordLink" title="Forgot password?">Forgot password?</a></li>
</ul>
</div>
</div>
</div>
</div>
</main>
<footer class="ids-footer">
<div class="ids-footer__inner">
<div class="ids-footer__logo-container">
<div class="ids-footer__logo"><img style="height:38px; width:auto"
src="...."
alt="Tenant logo"></div>
</div>
</div>
</footer>
</body>
</html>
Source Code Registration Page
Keep in mind that the actual source code may vary depending on your IAS configuration (required fields etc.).
<html lang="en" class=" ids-js ids-flexbox ids-no-touch ids-svg">
<body data-page="ids-registration/new" data-pagetype="New User Registration" data-spid="..."
data-spname="https://..." style="">
<main class="ids-main">
<div class="ids-main__content">
<div aria-labelledby="ids-heading-1" class="ids-container" role="dialog">
<h1 class="ids-heading-1" id="ids-heading-1">Registration</h1>
<form id="sapStoreRegisterForm" class="ids-form ids-form--horizontal" role="form"
action="/ui/public/performRegistration" accept-charset="UTF-8" method="post"><input name="utf8"
type="hidden" value="ā"><input type="hidden" name="authenticity_token"
value="...">
<div class="js-global-flashes-area"></div>
<div class="ids-input-area"><input id="pdVersion" name="pdVersion" type="hidden" value="-1"><input
id="touVersion" name="touVersion" type="hidden" value="-1"><input id="spId" name="spId"
type="hidden" value="..."><input id="mailingAction"
name="mailingAction" type="hidden"><input id="targetUrl" name="targetUrl" type="hidden"
value=""><input id="enclosingPage" name="enclosingPage" type="hidden" value=""><input
id="spName" name="spName" type="hidden" value="https://..."><input
id="scenario" name="scenario" type="hidden" value="SP_USER"><input
id="use_dynamic_contact_preferences" name="use_dynamic_contact_preferences" type="hidden"
value="false"><input id="temp_forgotPasswordLink" name="forgotPasswordLink" type="hidden"
value="<a id="forgotPasswordLink" href="/ui/createForgottenPasswordMail?spId=...&targetUrl=">Forgot Password</a>"><input
id="temp_logOnLink" name="logOnLink" type="hidden"
value="<a id="logOnLink" href="https://...dispatcher.hana.ondemand.com/index.html">Log On</a>"><input
id="xsrfProtection" name="xsrfProtection" type="hidden"
value="...">
<fieldset class="ids-fieldset">
<h2 class="ids-heading-fieldset">Tell Us About Yourself</h2>
<div class="ids-input-group ids-input-group--text" id="firstName-group">
<div class="ids-label-container"> <span class="ids-label-wrap"> <label class="ids-label"
for="firstName" id="firstName-label"> First Name </label> <abbr
aria-hidden="true" class="ids-required-marker" role="presentation">*</abbr>
</span> </div>
<div class="ids-control-container"> <input aria-describedby="" aria-required="true"
class="ids-input ids-input--text ids-input--clear js-has-input-clear js-remove-error-on-keyup"
id="firstName" maxlength="64" name="firstName" type="text">
<p class="ids-error-block" id="firstName.errors"> </p> <a
class="ids-input-clear js-input-clear" href="#" tabindex="-1"></a>
</div>
</div>
<div class="ids-input-group ids-input-group--text" id="lastName-group">
<div class="ids-label-container"> <span class="ids-label-wrap"> <label class="ids-label"
for="lastName" id="lastName-label"> Last Name </label> <abbr
aria-hidden="true" class="ids-required-marker" role="presentation">*</abbr>
</span> </div>
<div class="ids-control-container"> <input aria-describedby="" aria-required="true"
class="ids-input ids-input--text ids-input--clear js-has-input-clear js-remove-error-on-keyup"
id="lastName" maxlength="64" name="lastName" type="text">
<p class="ids-error-block" id="lastName.errors"> </p> <a
class="ids-input-clear js-input-clear" href="#" tabindex="-1"></a>
</div>
</div>
<div class="js-registration-user-name"></div>
<div class="js-registration-mail">
<div class="ids-input-group ids-input-group--text" id="mail-group">
<div class="ids-label-container"> <span class="ids-label-wrap"> <label
class="ids-label" for="mail" id="mail-label"> E-Mail </label> <abbr
aria-hidden="true" class="ids-required-marker"
role="presentation">*</abbr> </span> </div>
<div class="ids-control-container"> <input aria-describedby="" aria-required="true"
class="ids-input ids-input--text ids-input--clear js-has-input-clear js-remove-error-on-keyup js-remove-error-on-keyup"
id="mail" maxlength="256" name="mail" type="email">
<p class="ids-error-block" id="mail.errors"> </p> <a
class="ids-input-clear js-input-clear" href="#" tabindex="-1"></a>
</div>
</div>
</div>
<div class="ids-input-group ids-input-group--select" id="country-group">
<div class="ids-label-container"> <span class="ids-label-wrap"> <label
class="ids-label ids-required" for="country" id="country-label"> Country
</label> <abbr aria-hidden="true" class="ids-required-marker"
role="presentation">*</abbr> </span> </div>
<div class="ids-control-container"> <select aria-required="true"
class="js-remove-error-on-change" id="country" name="country">
<option value="">Select...</option>
...
</select>
<p class="ids-error-block" id="country.errors"> </p>
</div>
</div>
<div class="js-registration-region"></div>
</fieldset>
<fieldset class="ids-fieldset">
<h2 class="ids-heading-fieldset">Set Password</h2>
<div class="ids-input-group ids-input-group--text js-input-group"
id="newPasswordInput-group">
<div class="ids-label-container"> <span class="ids-label-wrap"> <label class="ids-label"
for="newPasswordInput" id="newPasswordInput-label"> Password </label> <abbr
aria-hidden="true" class="ids-required-marker" role="presentation">*</abbr>
</span> </div>
<div class="ids-control-container"> <input aria-describedby="password-hint"
aria-required="true"
class="ids-input ids-input--text ids-input--clear js-has-input-clear js-input-has-hint js-remove-error-on-keyup tst_bb_hpv tst_bb_ihp"
data-password-min-length="8" data-passwordminage="0" id="newPasswordInput"
maxlength="255" name="password" type="password" value="">
<div class="ids-input-hint js-input-hint" id="password-hint" role="tooltip"> <a
class="ids-input-hint__close js-input-hint-close" href="" tabindex="-1"></a>
<div class="ids-input_hint__inner">
<ul id="input-hint-password-reqs">
<li class="ids-input-hint-check" id="check-length"> Your password must
be at least 8 characters long </li>
<li> and include three of the following: </li>
<li class="ids-input-hint-check" id="check-upper"> Uppercase letters
</li>
<li class="ids-input-hint-check" id="check-lower"> Lowercase letters
</li>
<li class="ids-input-hint-check" id="check-number"> Numbers </li>
<li class="ids-input-hint-check" id="check-symbol"> Symbols </li>
</ul>
</div>
</div>
<p class="ids-error-block" id="password.errors"> </p> <a
class="ids-input-clear js-input-clear" href="#" tabindex="-1"></a>
</div>
</div>
<div class="ids-input-group ids-input-group--text" id="retypeNewPasswordInput-group">
<div class="ids-label-container"> <span class="ids-label-wrap"> <label class="ids-label"
for="retypeNewPasswordInput" id="retypeNewPasswordInput-label"> Re-Enter
Password </label> <abbr aria-hidden="true" class="ids-required-marker"
role="presentation">*</abbr> </span> </div>
<div class="ids-control-container"> <input aria-describedby="" aria-required="true"
class="ids-input ids-input--text ids-input--clear js-has-input-clear js-remove-error-on-keyup"
id="retypeNewPasswordInput" maxlength="255" name="passwordConfirm"
type="password" value="">
<p class="ids-error-block" id="passwordConfirm.errors"> </p> <a
class="ids-input-clear js-input-clear" href="#" tabindex="-1"></a>
</div>
</div>
</fieldset>
</div>
<div class="ids-button-group"><button class="ids-button ids-button--primary"
id="sapStoreRegisterFormSubmit" role="button" title="Register"
type="submit">Register</button></div>
</form>
</div>
</div>
</main>
<footer class="ids-footer">
<div class="ids-footer__inner">
<div class="ids-footer__logo-container">
<div class="ids-footer__logo"><img style="height:38px; width:auto"
src="..."
alt="Tenant logo"></div>
</div>
</div>
</footer>
</body>
</html>
Checking the source code on your own
Just use Chrome or any other modern browser and open the “developer tools (F12)”. Then you can inspect the page source code and also play around with immediate changes to the design:
In case you are allowing users to register themselves, don’t forget to style that page as well!
Creating a style sheet
Create a new file locally on your PC and name it “corporate_style_v1.css”. Open it in your favourite editor and paste the following CSS:
.ids-main {
<PASTE IMAGE>
background-size: cover;
}
.ids-login-sp,
.ids-login-login {
float: none;
width: 100%;
border: 0;
padding: 0;
}
.ids-login-container {
background-color: rgba(255, 255, 255, 0.8);
padding: 20px;
border-radius: 4px;
}
.ids-footer {
display: none;
}
.ids-login-sp {
font-size: 2rem;
padding-top: 1.5rem;
}
.ids-heading-2 {
font-size: 2rem;
}
.ids-heading-1--login {
display: none;
}
.ids-login-widget {
margin-top: 3rem;
}
.ids-login-login {
text-align: center;
}
.ids-label {
display: none;
}
.ids-input-group--login input[type="text"],
.ids-input-group--login input[type="password"],
.ids-input-group--login input[type="email"] {
padding: 10px;
}
.ids-button-group .ids-button:first-child {
background-color: #000;
border-width: 2px;
}
Replace “<PASTE IMAGE>” with an image of your choice. Use e.g. https://websemantics.uk/tools/image-to-data-uri-converter/ to convert an image into a css data url image. Paste only the single line including “background-image:” into your css file.
Go to IAS and create a new style:
Now you can upload your custom css file “corporate_style_v1.css”:
Using the Custom Style
Go to the IAS tenant admin page and then select “Applications & Resources” and choose your application from the list. Go to “Branding and Layout”, then “Branding Style” and choose “Custom Advanced”. Select the previously created stylesheet in the list and hit “Save”.
Testing
You can just open your application (which you assigned the style to in IAS) in a new private window (Chrome: incognito) to trigger a new login process. Also IAS makes it now really easy and is offering a test link on the style sheet page:
Just right click the provided link and open in a private window.
Please also take care of testing your style on mobile devices. You can simulate these devices with most browser developer tools.
Conclusion and Links
You have learned how to configure IAS to use a custom stylesheet. Also you are now able to change the default style and apply any required corporate styling.
Thank you Simon. I am unable to download the Default Style zip file using my S user. I keep getting āWeāre sorry, but this content is not accessible.ā message.
Ā
Regards, Parag.
It should be available right at the bottom of this page:
https://help.sap.com/viewer/6d6d63354d1242d185ab4830fc04feb1/Cloud/en-US/faa2a33ff973409dafe136e4f748abda.html
Same error
Hello
from help.sap.com,, I got same error 'We're sorry, but this content is not accessible.'
regards and thanks
Dear Parag and Laura,
There was problem with accessing the zip file from the external network, but it is resolved now.
Please try to download again the Default.zip, it should work now.
Regards,
Zsuzsa
Hi Simon,
Great blog, thank you! This is a cool feature. But Iām still waiting for some more structuring options like having more parameters for e-mail templates⦠The documentation says that we only have those available:
"The text file can contain placeholders and HTML tags. The following placeholders can be used: ${user.sap_mailing_logo},Ā ${user.company_logo},Ā ${user.firstName},${user.lastName},Ā ${user.uid},Ā ${user.activate_account_link},Ā ${user.sp_name},Ā ${user.reset_password_link},Ā ${user.header},Ā ${user.inviter_name}, andĀ ${user.footer}."
Since we can choose āLogin Nameā to be the Subject Name Identifier, Iām really hoping that this parameter will be available some day to be filled in the On-Behalf Registration mail template.
Do you have any inside view about this possibility?
Thank you in advance!
Best regards,
Marco
Hi Simon,
Thanks for the useful blog.
Is it possible to add custom UI elements like a carousel or link to the login screen along with the CSS customization?
Hi,
Such a feature would require more customization options beyond CSS. For more customizations you usually look at a CIAM solution as this is more relevant for B2C scenarios: https://www.sap.com/products/customer-identity.html
In same subaccount with same IAS, can multiple projects use their own custom styles for login screens ?
Basically, I have a project already using one custom style for login.
Now, another project within same subaccount using same IAS is requesting a different custom style for login. Is this possible, and how ?
Hi,
Login screens are defined per application: https://help.sap.com/viewer/6d6d63354d1242d185ab4830fc04feb1/Cloud/en-US/32f8d337f0894d269f5f89956803efac.html
So you can have different styles for each application. In the context of BTP applications (e.g. a CF application) you would need a separate subaccount as the whole subaccount is configured as the "application" in IAS.
Hello SAP ,
Please suggest on how to put custom self registration link on SAP IAS login screen ,when enabling public access for users of an application is it supported ,i dont find any option to do that.
Thanks,
Siddharth
My company uses Custom CSS on SAP IAS.
Would it be possible to add a message on the login page so that all users can see the same message regardless of the preferred language in their browser?
This is NOT related to Custom Text Label setting in SAP IAS.
Hey Simon Kessler
Before you add the custom CSS (example CSS provided by SAP) login username label (j_username-label in the source) is set to "username or Email". After you add CSS, the username label only contains "Email". How can I update this field to Username or email and where can I update this?
Kind regards
Richie
Hi Simon,
Very informative blog.
In the activation email I want to grey out or remove First Name & Last Name options. I dont want users to edit the first name & Last name.
How to achieve this . Kindly let me know
Thanks & Regards,
Deepika B
Hi Simon,
The blog is very helpful, we have implemented the solution in our Test system. we are able to see check box also, but we are missing 'Remember me' option beside the check box.
any way to achieve this?
Regards,
Naren