Securing your web applications with SAML 2.0 using WSO2 Identity Server
This article will guide you on how to integrate SAML 2.0 into your web application with the SAML SDK in WSO2 Identity Server which allows developers to configure existing webapps in an easily configurable manner. By following this guide, you can enable authentication, logout and user attribute retrieval flows in your web application with SAML2 using wso2 Identity server.
To get started, this is the structure of the sample web app we would be configuring throughout this guide.
Here, we have a landing page (index.html) and another page which we want to secure (home.jsp). In the landing page, there is a button which would forward the user to the secured page. Upon clicking on the button on the landing page, we want to authenitcate the user before granting access to the secured page.
This guide outlines the steps needed to use the SAML SDK which is readily available with WSO2 Identity Server, and configure the webapp to use the SDK for the purpose of securing the home.jsp page.
For clarity, the rest of the guide is structured into two sections.
- Configuring the web application
- Configuring the WSO2 Identity Server
Prerequisites
- Download and install the latest WSO2 Identity Server.
- Apache Tomcat 8.x or higher
1. Configuring the web application
- Download the
lib.zip
from the latest release. - Extract the downloaded
lib.zip
file to the<APP_HOME>/WEB-INF
directory. (If you already have alib
folder in your web app, merge the content of the downloadedlib.zip
file into the existinglib
folder.) - You have to configure a properties file in the <APP_HOME>/WEB-INF/classes directory. In the sample-app, create a file named sample-app.properties in the
<APP_HOME>/WEB-INF/classes
directory. The sample-app.properties file contains properties similar to the following:
# The URL of the SAML 2.0 Assertion Consumer
SAML2.AssertionConsumerURL=http://localhost.com:8080/sample-app/home.jsp# A unique identifier for this SAML 2.0 application
SAML2.SPEntityId=sample-app# A unique identifier for this SAML 2.0 Identity Provider
SAML2.IdPEntityId=localhost# The URL of the SAML 2.0 Identity Provider
SAML2.IdPURL=https://localhost:9443/samlsso# Adanced Properties - Only need to be changed for advanced use cases.# Url to do send SAML2 SSO AuthnRequest
SAML2SSOURL=samlsso# URIs to skip SSOAgentFilter; comma separated values
SkipURIs=/sample-app/index.htmlIndexPage=index.html# Specify if Single Sign on is enabled/disabled
EnableSAML2SSOLogin=true# Specify if SingleLogout is enabled/disabled
SAML2.EnableSLO=true# This is the URL that is used for SLO
SAML2.SLOURL=logout# Specify if SAMLResponse element is signed
SAML2.EnableResponseSigning=true# Specify if SAMLAssertion element is signed
SAML2.EnableAssertionSigning=true# Specify if SAMLAssertion element is encrypted
SAML2.EnableAssertionEncryption=false# Specify if AuthnRequests and LogoutRequests should be signed
SAML2.EnableRequestSigning=true# Specify if SAML request is a passive
SAML2.IsPassiveAuthn=false# Pem content of the IDP public certificate
IdPPublicCert=<CERTIFICATE_PEM_CONTENT># Password of the KeyStore for SAML and OpenID
KeyStorePassword=wso2carbon# Alias of the IdP's public certificate
IdPPublicCertAlias=wso2carbon# Alias of the SP's private key
PrivateKeyAlias=wso2carbon# Private key password to retrieve the private key used to sign AuthnRequest and LogoutRequest messages
PrivateKeyPassword=wso2carbon
You can extract the IdPPublicCert
from the SAML2 matadata file which can be downloaded by following this guide. You can find the detailed description of the other configuration by following this link.
4. Next, generate keystore file and copy it to the APP_HOME/WEB-INF/classes
directory. For simplicity, we are using the wso2carbon.jks keystore file of the WSO2 Identity Server which resides in <IS_HOME>/repository/resources/security/
directory. You may need to update the certificate-file
property in the<APP_HOME/WEB-INF/web.xml
file if you are using different keystore than wso2carbon.jks
.
5. Finally, copy and paste the following configurations to the <APP_HOME>/WEB-INF/web.xml
file.
<?xml version="1.0" encoding="UTF-8"?><!--
~ Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
--><web-app id="io.asgardio.tomcat.saml.agent.sample" version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><display-name>io.asgardio.tomcat.saml.agent.sample</display-name><filter>
<filter-name>SAML2SSOAgentFilter</filter-name>
<filter-class>io.asgardio.tomcat.saml.agent.SAML2SSOAgentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SAML2SSOAgentFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>SAML2SSOAgentFilter</filter-name>
<url-pattern>*.html</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>SAML2SSOAgentFilter</filter-name>
<url-pattern>/samlsso</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>SAML2SSOAgentFilter</filter-name>
<url-pattern>/logout</url-pattern>
</filter-mapping><listener>
<listener-class>io.asgardio.tomcat.saml.agent.SSOAgentContextEventListener</listener-class>
</listener>
<context-param>
<param-name>property-file</param-name>
<param-value>sample-app.properties</param-value>
</context-param>
<context-param>
<param-name>certificate-file</param-name>
<param-value>wso2carbon.jks</param-value>
</context-param>
</web-app>
Enable login
Next, the webapp itself has two pages, index.html and home.jsp, and a web.xml file. The index.html contains a login button which we would use to forward the user to the secured page.
<form method="post" action="home.jsp">
Now we need to update the form action to trigger a SAML authentication request as follows,
<form method="post" action="samlsso?SAML2.HTTPBinding=HTTP-POST">
Enable logout
The home.jsp page is a page which we want to secure i.e. in case there are no active sessions, the http://localhost.com:8080/sample-app/home.jsp should not be accessible. In the sample we are using, if there is no active session in place, we would redirect the user for authentication. In the home.jsp, there is a logout link which will be used to create a SLO request.
<a href="logout?SAML2.HTTPBinding=HTTP-POST">Logout</a>
Retrieving user attributes
The web app needs to be configured to read the attributes sent from the Identity Server upon successful authentication. In the sample-app, we would customize the home.jsp file as follows to retrieve the user attributes.
First, we would need the following imports to be added to the home.jsp file.
<%@ page import="io.asgardeo.java.saml.sdk.util.SSOAgentConstants" %><%@ page import="io.asgardeo.java.saml.sdk.bean.LoggedInSessionBean" %><%@ page import="io.asgardeo.java.saml.sdk.bean.LoggedInSessionBean.SAML2SSO" %><%@ page import="java.util.Map" %>
Next, by adding the following snippets, we would be able to retrieve the user claims as provided by the Identity Provider.
<%// Retrieve the session bean.LoggedInSessionBean sessionBean = (LoggedInSessionBean) session.getAttribute(SSOAgentConstants.SESSION_BEAN_NAME);// SAML responseSAML2SSO samlResponse = sessionBean.getSAML2SSO();// Autheticated usernameString subjectId = samlResponse.getSubjectId();// Authenticated user's attributesMap<String, String> saml2SSOAttributes = samlResponse.getSubjectAttributes();%>
Then, we would use the saml2SSOAttributes
in the <APP_HOME>/home.jsp to display the user attributes via a table:
<table>
<%
if (saml2SSOAttributes != null) {
for (Map.Entry<String, String> entry : saml2SSOAttributes.entrySet()) {
%>
<tr>
<td><%=entry.getKey()%>
</td>
<td><%=entry.getValue()%>
</td>
</tr>
<%
}
}
%>
</table>
After the above configurations, create the .war file again and deploy it on the tomcat. Your app would be able to try out the authentication, logout and attribute retrieval flows with SAML 2.0.
2. Configuring the WSO2 Identity Server
This section of the guide will explain how to create a service provider in WSO2 Identity Server which would be utilized to handle the web app requests.
To register the sample app as a service provider,
- Start the WSO2 Identity Server.
- Once the server startup, Login to the management console ( https://localhost:9443/carbon/) with admin credentials (username: admin, password: admin).
- On the Main menu, click Identity > Service Providers > Add.
- Fill in the Service Provider Name and provide a brief Description (optional) of the service provider as follows.
- Click Register to add the new service provider.
- Next, under the Inbound Authentication Configuration section, click SAML2 Web SSO Configuration and click on configure.
- Select Manual Configuration and enter the required details as given below.
Issuer —
sample-app
(This needs to be identical to the SAML2.SPEntityId property in the sample-app.properties file)Assertion Consumer URL —
http://localhost:8080/sample-app/home.jsp
(This needs to be identical to the SAML2.AssertionConsumerURL property in the sample-app.properties file)
For the user attrbitues retrieval, enable following configurations;
Enabale Attrbitue Profile
Include Attrbutes in the Response Always
Please refer to Configuring SAML2 Web SSO when filling out the other fields.
- Finally, click on “register” to save the service provider configuration.
To retrive the user attributes, the service provider claim configuration needs to be updated as follows.
- Expand the Claim Configuration section.
- From the expanded menu, set the Claim Mapping Dialect to Use Local Claim Dialect and click on Add Claim URI that is against the Requested Claims field.
- Add the claims you need to retrive from the web app as following. (eg: country, lastname)
- Then, set the Subject Claim URI to a claim you want as the subject.
- After that, click on update to save the configurations of the service provider.
Try it out!
- Create a user in the WSO2 Identity Server and add the relavant user attributes which you want to display on the application.
- Access the following URL on a browser window: http://localhost.com:8080/sample-app/index.html to log into the sample application.
- Log in using the credentials of the user created. You will be redirected to the sample application home page and the user attributes will be displayed on the home page.
This means that you have successfully integrated SAML 2.0 into your web application using the WSO2 Identity Server.