Saturday, February 23, 2019

Monitoring WSO2 Identity Server with Prometheus

Prometheus can be used to monitor the JVM metrics of WSO2 Identity Server. For this, you need to download,
First of all, we need to configure JMX exporter to expose the Identity Server metrics. This exporter is intended to be run as a Java Agent, exposing an HTTP server and serving metrics of the Identity Server JVM. We start with creating the config file for the agent. Create a file named is.yml in the bin directory of the Identity Server. In the initial phase, we will stick to basic configs. Add below content to the created yml file.

---
lowercaseOutputLabelNames: true
lowercaseOutputName: true

Now open the wso2server.sh and add the Java Agent. Scroll down to the bottom of the file and you will notice the "-D" parameters added. At the end of those parameters add below parameter also.

-javaagent:$CARBON_HOME/bin/jmx_prometheus_javaagent-0.11.0.jar=8080:$CARBON_HOME/bin/is.yml \

After the config, the file would look like below.
...
do
    $JAVACMD \
    ...
    -Dhttpclient.hostnameVerifier="DefaultAndLocalhost" \
    -javaagent:$CARBON_HOME/bin/jmx_prometheus_javaagent-0.11.0.jar=8080:$CARBON_HOME/bin/is.yml \
    org.wso2.carbon.bootstrap.Bootstrap $*
    status=$?
done

We are finished in the Identity Server side and you can start the identity server.

Now we can start configuring Prometheus. Go the downloaded Prometheus directory. Create a file called is.yml there. Add below content.

# my global config
global:
  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

# Alertmanager configuration
alerting:
  alertmanagers:
  - static_configs:
    - targets:
      # - alertmanager:9093

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:

# A scrape configuration containing exactly one endpoint to scrape:
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: 'WSO2 Identity Server'

    static_configs:
    - targets: ['localhost:8080']

Now we can start Prometheus. Run below command from the Prometheus directory.

./prometheus --config.file=is.yml

Everything is set. Navigate to the http://localhost:9090/graph to use Prometheus's built-in expression browser. Now you can monitor the JVM metrics. To view memory consumptions of the JVM enter this into the expression console and click "Execute" button.

jvm_memory_pool_bytes_used

You should be able to see the time series graph of the memory usage like below.



We will dig deeper into configurations in a future post.

Monday, February 11, 2019

New Theme for Oh My ZSH

I have been using Oh My ZSH for quite some time now with robbyrussell and agnoster themes. While neither of them was what I was looking for, I couldn't find a similar theme I was thinking about. When I was recently looking for a theme again af-magic caught my eye. While it was not quite what I was looking for, it was the closest I could find.


Then I thought of customizing this theme to match my liking. Starting from the af-magic theme, I created my own theme. I created a file called my-theme.zsh-theme in ~/.oh-my-zsh/custom/themes folder. Added below content to the file.

# my-theme.zsh-theme
if [ $UID -eq 0 ]; then NCOLOR="red"; else NCOLOR="green"; fi
local return_code="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"

# color vars
eval my_gray='$FG[237]'
eval my_orange='$FG[214]'

# primary prompt
PROMPT='$my_gray%n%{$reset_color%}:% $FG[032]%~\
$(git_prompt_info) \
$FG[105]%(!.#.»)%{$reset_color%} '
PROMPT2='%{$fg[red]%}\ %{$reset_color%}'
RPS1='${return_code}'

# git settings
ZSH_THEME_GIT_PROMPT_PREFIX="$FG[075]($FG[078]"
ZSH_THEME_GIT_PROMPT_CLEAN=""
ZSH_THEME_GIT_PROMPT_DIRTY="$my_orange*%{$reset_color%}"
ZSH_THEME_GIT_PROMPT_SUFFIX="$FG[075])%{$reset_color%}"

Then add the below line to the .zshrc file in your home directory and remove the already defined ZSH_THEME variable.

ZSH_THEME="my-theme"

Source the .zshrc file and below is the result.



Saturday, January 5, 2019

User Attribute Manipulation with WSO2 Identity Server Adaptive Authentication

WSO2 Identity Server Script Based Adaptive Authentication offers you a wide range of functionality other than "adapting" the authentication flow dynamically. In the post, we will manipulate some claims coming from the identity provider, before sending to the service provider. As an example, we will build "full name" of the user combining to "first name" and "last name" provided by the identity provider.

First, configure your federated identity provider as described in the documentation. Now configure your application in Identity Server and add the inbound authentication configuration as described in this documentation.

Now we are ready to configure the script based adaptive authentication for this service provider. Go to the "Local & Outbound Authentication Configuration" section of the service provider configuration and click on the "Advanced Authentication" button.

From the "Authentication Step Configuration" section add an authentication step, and add the configured federated identity provider as the authentication option. Now in the "Script Based Adaptive Authentication" in the editor, add below script.

function onLoginRequest(context) {
    executeStep(1, {
        onSuccess: function (context) {
            var user = context.steps[1].subject;
            if (user.remoteClaims !== null) {
                var firstNameClaim = user.remoteClaims.first_name;
                var lastNameClaim = user.remoteClaims.last_name;
                user.remoteClaims.full_name = firstNameClaim + " " + lastNameClaim;
            }
        }
    });
}

This script is self-explanatory. It will execute the first authentication step, which is your federated identity provider. Upon success, it will check if the "remoteClaims" (which are the user attributes provided by the federated identity provider) is not null. If so it will get the first_name and the last_name and create the full_name and add to the remoteClaims. More about the API reference for the above script is in here.

Now the whole configuration would look like below.


Now save the configs and try the login flow. After successful login application will get the user's full name which was built by combining the user's first name and the last name. Similarly, you can achieve functionality like below.

  • Calculate the user's age based on the birthday.
  • Send static user attributes to the service provider

Friday, December 28, 2018

Adaptive Authentication with WSO2 Identity Server

In one of my previous blog post Conditional Authentication! What and Why, I explained the necessity to "adopt" the authentication flow according to the user’s risk profile or the situation.

In this post, let's see how to implement a use case with WSO2 Identity Server 5.7.0. We will use the example of the user management system from my previous blog post. For convenience, I'll add the use case below.
There is a user management system in your company. All the users can login to the system and manage their profile and change their password. But if you are an admin user in the system, you can add users, delete users, reset passwords of other users and do all the risky tasks in the system. While all the users can login to the system with just username and password, if you are an admin user, you have to enter your “Time-based One Time Password” (TOTP).
First, download the WSO2 Identity Server 5.7.0 from the official download page and start it if you haven't done it already. Now configure the application in Identity Server and add the inbound authentication configuration as described in this documentation.

Now we are ready to configure the adaptive authentication for this service provider. Go to the "Local & Outbound Authentication Configuration" section of the service provider configuration and click on the "Advanced Authentication" button. You will be redirected to below page.


Expand the "Script Based Adaptive Authentication" section and you will be able to see a list of templates available.


From the available template list, we will be using the "Role-Based" template. To use it click on the "+" next to "Role-Based" label. Now the editor will be populated with below template.

// Role-Based from Template...

// This script will step up authentication for any user belonging
// to one of the given roles
// If the user has any of the below roles, authentication will be stepped up
var rolesToStepUp = ['admin', 'manager'];

function onLoginRequest(context) {
    executeStep(1, {
        onSuccess: function (context) {
            // Extracting authenticated subject from the first step
            var user = context.currentKnownSubject;
            // Checking if the user is assigned to one of the given roles
            var hasRole = hasAnyOfTheRoles(user, rolesToStepUp);
            if (hasRole) {
                Log.info(user.username + ' Has one of Roles: ' + rolesToStepUp.toString());
                executeStep(2);
            }
        }
    });
}

// End of Role-Based.......

The script is pretty much self-explanatory. First, we execute step 1, which is configured to basic authentication in the "Authentication Step Configuration" section. The after successful execution of the first step, we check whether the logged in user has the "admin" or the "manager" roles. If so, we execute step 2, which is configured to either TOTP or FIDO authentication.

Click on the "Update" button and then save the service provider configuration.

Now we are ready to test the adaptive authentication.
First, try to log in as an admin user. After entering the admin credentials, the user will be prompted for a second factor.
Next, try to log in as a normal user (a user that don't have admin or the manager roles). Just by entering the username and the password, the user will be able to log in.

So now we have implemented the scenario successfully. Identity Server has a set of pre-defined templates for adaptive authentication. Explore them and see the use cases you can implement. Adaptive Authentication JS API Reference document contains more information about each API and objects used in the authentication script. Using them you can implement many more use cases.

Centering Widgets with ConstraintLayout in Android

Placing widgets in the exact place you want on an Android layout is a difficult task. With ConstraintLayout, you can achieve this relatively easy. In a ConstraintLayout, you can use below configuration to center the button in the window.

<Button
        android:id="@+id/testbutton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Test"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

Interestingly this will add the button in the center of the window like below.

If we consider horizontal positioning, we have configured to place the left of the button to the left of the parent, (which refers to the parent container, i.e. the ConstraintLayout) and place the right of the button to the right of the parent. This is an impossible layout unless the width of the button is equal to the width of the parent. ConstraintLayout handles this by placing the button in the center of the parent, like pulling the button by the two constraints resulting to make the button keep in the middle. Same goes with the vertical positioning.






But if you add a bias to position the widget in favor of one side. For example, if we add below bias to the above positioning, the result will be as below image.

<Button
        ...
        app:layout_constraintVertical_bias="0.8" />

If we add the bias as 0.8, the widget will be placed after 80% of the container.

Tuesday, November 20, 2018

Conditional Authentication! What and Why

When you read the term “Conditional Authentication” the first thing that comes to your mind is what is “Conditional Authentication”?

Conditional authentication is a type of multi-factor authentication that can change or “adopt” the authentication flow or steps according to the user’s risk profile or the situation.

Still confusing? Let’s take a few examples.
  1. There is a banking application. Viewing the balance in your bank account is relatively less risky, right? So its enough to authenticate with just username and password. But if you want to make a transaction, it's relatively high risk. So you have to authenticate with your username and password and then maybe with SMS One-Time-Password (OTP).
  2. There is a user management system in your company. All the users can login to the system and manage their profile and change their password. But if you are an admin user in the system, you can add users, delete users, reset passwords of other users and do all the risky tasks in the system. While all the users can login to the system with just username and password, if you are an admin user, you have to enter your “Time-based One Time Password” (TOTP).
  3. There is a financial management application in your company. You are a financial officer in the company and while working in the office, you have to login to the application always. If you are working from the office, it is sufficient for you to enter the username and password only to login to the application. But if you are trying to login to the application from outside of the office network, you have to enter One-Time-Password sent to you over the email.
We can demonstrate a simple scenario with below flow chart.


Now you can ask, why do we need conditional authentication? We can just have the additional authentication steps statically configured for all the users and all the operations. Well, mostly its related to user experience. Let’s take the above examples again.
  1. When checking the account balance from a banking application, if you always have to enter your SMS OTP, you would be frustrated over time, right?
  2. When you need to update the profile picture, if you have to enter a TOTP, you would be frustrated, right?
  3. If you work in the office and you need to authenticate with two steps always, you would be frustrated over time, right?
So we can summarize the idea of conditional authentication like below.
Conditional authentication is a type of multi-factor authentication that can change or “adopt” the authentication flow or steps according to user’s risk profile or the situation without compromising user experience.

Sunday, July 24, 2016

WSO2 IDP for Spring SAML Service Provider

Today we are going to see how to add WSO2 Identity Server as an IDP to a Spring application. We are going to do this using the Spring SAML sample provided here. You can download one of the releases of Spring SAML sample from here. I have tested this with 1.0.2.RELEASE.

Sample Application Configurations

Create SAML metadata file like below (wso2.xml). You have to change the entityID, samlsso url and X509Certificate according to your installation of the Identity Server. Below values is the default. You can use this blog post to find the X509Certificate of your Identity Server deployment.

<?xml version="1.0" encoding="UTF-8"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="localhost" validUntil="2026-05-16T21:51:14.927Z">
   <md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
      <md:KeyDescriptor use="signing">
         <ds:KeyInfo>
            <ds:X509Data>
                  <ds:X509Certificate>
MIICNTCCAZ6gAwIBAgIES343gjANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJV
UzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxDTALBgNVBAoM
BFdTTzIxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xMDAyMTkwNzAyMjZaFw0zNTAy
MTMwNzAyMjZaMFUxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwN
TW91bnRhaW4gVmlldzENMAsGA1UECgwEV1NPMjESMBAGA1UEAwwJbG9jYWxob3N0
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUp/oV1vWc8/TkQSiAvTousMzO
M4asB2iltr2QKozni5aVFu818MpOLZIr8LMnTzWllJvvaA5RAAdpbECb+48FjbBe
0hseUdN5HpwvnH/DW8ZccGvk53I6Orq7hLCv1ZHtuOCokghz/ATrhyPq+QktMfXn
RS4HrKGJTzxaCcU7OQIDAQABoxIwEDAOBgNVHQ8BAf8EBAMCBPAwDQYJKoZIhvcN
AQEFBQADgYEAW5wPR7cr1LAdq+IrR44iQlRG5ITCZXY9hI0PygLP2rHANh+PYfTm
xbuOnykNGyhM6FjFLbW2uZHQTY1jMrPprjOrmyK5sjJRO4d1DeGHT/YnIjs9JogR
Kv4XHECwLtIVdAbIdWHEtVZJyMSktcyysFcvuhPQK8Qc/E/Wq8uHSCo=
                  </ds:X509Certificate>
            </ds:X509Data>
         </ds:KeyInfo>
      </md:KeyDescriptor>
      <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost:9443/samlsso"/>
      <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost:9443/samlsso"/>
      <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
      <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://localhost:9443/samlsso"/>
      <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://localhost:9443/samlsso"/>
   </md:IDPSSODescriptor>
</md:EntityDescriptor>

Copy the created wso2.xml metadata file to <SAMPLE_HOME>/sample/src/main/resources/metadata directory. Now you need to refer this metadata file from the application. To do this you need to open <SAMPLE_HOME>/sample/src/main/webapp/WEB-INF/securityContext.xml file and find the bean with id "metadata". In the list add below to include Identity Server as an identity provider.


<bean class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate">
    <constructor-arg>
        <bean class="org.opensaml.saml2.metadata.provider.ResourceBackedMetadataProvider">
            <constructor-arg>
                <bean class="java.util.Timer"/>
            </constructor-arg>
            <constructor-arg>
                <bean class="org.opensaml.util.resource.ClasspathResource">
                    <constructor-arg value="/metadata/wso2.xml"/>
                </bean>
            </constructor-arg>
            <property name="parserPool" ref="parserPool"/>
        </bean>
    </constructor-arg>
    <constructor-arg>
        <bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
        </bean>
    </constructor-arg>
</bean>

Identity Server Configurations

Create a service provider. Go to Inbound Authentication Configuration and SAML2 Web SSO Configuration. Add the below configurations.
  • Issuer: http://localhost:8080/spring-security-saml2-sample/saml/metadata
  • Assertion Consumer URLs: http://localhost:8080/spring-security-saml2-sample/saml/SSO
  • Enable Response Signing.
  • Enable Single Logout.
  • SLO Response URL: http://localhost:8080/spring-security-saml2-sample/saml/SingleLogout
  • Enable Attribute Profile.
  • Include Attributes in the Response Always.
It will look like below.


Working with the sample.

Go to <SAMPLE_HOME>/sample from the terminal and run below command to build the project.
                 mvn package
Now run the below command to start the tomcat server and start the application.
                 mvn tomcat7:run

Go to the below url.
                 http://localhost:8080/spring-security-saml2-sample
You will be redirected to below page which is the index page of the sample application.


You can see the localhost as an IDP here. Its because the entityID of the metadata file we created is localhost. From the list select localhost and click "Start single sign-on" button. Now you will be redirected to the login page of the Identity Server.


Insert the username and password in the Identity Server and click Sign In. You will be redirected back to the sample application. Now you are logged in to the application and you can see the details of the authenticated user.