Monday, June 29, 2015

Claim Management with WSO2 IS


WSO2 Carbon supports different claim dialects. A claim dialect can be thought of as a group of claims. A claim carries information from the underlying user store.

Claim attributes in user profile info page:

In WSO2 IS each piece of user attribute is mapped as a claim. If you visit the user profile page for a specific user (Configure --> Users and Roles --> Users --> User Profile), you can view the user profile data (see figure 1 below).

Figure 1


As you can see there are mandatory fields (eg: Profile Name), optional fields (eg: Country) and read only fields (eg: Role).
You can add a new user profile field to the above page. If you visit Claim Management list (in Configure --> Claim Management), there are set of default claim dialects listed in WSO2 IS. Among them http://wso2.org/claims is the default dialect for WSO2 Carbon. You can follow the steps below to add a new field to the user profile info page:
  1. Click on dialect http://wso2.org/claims . This will list down a set of claim attributes.
  2. Lets say you need to add attribute "Nick Name" to the user profile page. 
  3. Click on attribute "Nick Name" and "Edit" . There are a set of fields you can edit. Some important features are:
    1. Supported by Default - This will add the attribute to the user profile page
    2. Required - This will make the attribute mandatory to fill when updating user profile
    3. Read-only - This will make the attribute read-only 
  4. You can try actions listed above and add any attribute listed in the dialect (or add a new claim attribute using "Add new Claim Mapping" option)
There are some more useful dialects defined in WSO2 IS.

One such dialect is http://wso2.org/oidc/claim  which is defined for OpenID attribute exchange. Attributes defined in this dialect will be used when retrieving claims for user info requests (as I have described in my previous post on "Accessing WSO2 IS profile info with curl"  ).

How to add a value to a claim defined in OpenID dialect?

(This mapping is currently valid for WSO2 IS 5.0.0 and will get changed in a later release)
You can follow the steps below when adding a value to a claim attribute in the OpenID dialect.
  1.  Start WSO2 IS and login.
  2. Go to wso2 OpenID claim dialect. (http://wso2.org/oidc/claim)
  3. Find a claim attribute that you need to add a value to. (eg: Given Name)
  4. Go to User Profile page. This will not display an entry to add Given Name attribute. 
  5. As I have described in the first section of this post add a new claim mapping to the default dialect for WSO2 Carbon (http://wso2.org/claims) with the name and the "Mapped Attribute (s)". (Eg: Add a new Claim with the following details: )
    1.  Display Name : Given Name
    2.  Claim Uri : given_name
    3.  Mapped Attribute (s) : cn   ----> add the same Mapped Attribute in you OpenID claim attribute
    4.  Supported by Default : check
    5. Required : check
  6. Now you have a new claim attribute added to the default dialect for WSO2 Carbon
  7. If you visit the user profile page of a user you can add a value to the newly added attribute. 
  8. If you retrieve user info as in "Accessing WSO2 IS profile info with curl" you can see the newly added value is retrieved in the format {<Claim Uri > : <given value>} eg: ({given_name : xxxxx})
Please note that if you still can't see the newly added value when retrieving user info, you may have to restart the server or retry after cache invalidates (after 15min).  

This claim mapping operate as follows:
 > When you add a value to a user profile field via the UI (eg: adding a value to "Full Name" will map the value with the mapping attribute "cn" of the claim).
 > Hence if there is any other claim attribute in OpenID dialect http://wso2.org/oidc/claim that has the same mapping attribute "cn" then, this will also get the value added above.
 > (Eg: say you have "Mapping Attribute"="cn" in the claim attribute "Full Name" in OpenID dialect http://wso2.org/oidc/claim), You can get the value you have entered in to the "Full Name" entry in the user profile.




Sunday, May 3, 2015

Accessing WSO2 IS profile info with curl

The WSO2 Identity Server is able to implement the OpendID connect Client profile. This posts give a basic steps you can follow to retrieve profile info from WSO2 IS

You can retrieve the access token with the command below.


curl -X POST -H "Content-Type:application/x-www-form-urlencoded" <oauth2-token-url> --insecure --data "client_id=<client-id>&client_secret=<client-secret>&grant_type=client_credentials&scope=openid"


Please find a sample command below. Token url is https://localhost:9443/oauth2/token if you have a IS server with hostname “localhost” and no port offset is set. You can find the client id and client secret under the “OAuth/OpenID connect configuration” section of the service provider you are using. Please not that you need to set scope to “openid”


curl -X POST -H "Content-Type:application/x-www-form-urlencoded" https://localhost:9443/oauth2/token --insecure --data "client_id=1Kfz8ivbw0hqjoTbo1LbVTJl2f4a&client_secret=8c7d2hVE4p17_lIZ4FHOtWLJfQEa&grant_type=client_credentials&scope=openid"


Following is a sample output received.


{"scope":"openid","token_type":"bearer","expires_in":3300,"id_token":"eyJhbGciOiJSUzI1NiJ9.eyJhdXRoX3RpbWUiOjE0MzAzODkyNjEyOTIsImV4cCI6MTQzMDM5Mjg2MTI5Miwic3ViIjoiYWRtaW4iLCJhenAiOiIxS2Z6OGl2YncwaHFqb1RibzFMYlZUSmwyZjRhIiwiYXRfaGFzaCI6IlkyUXlNMk5pWTJNMFlqWXpZell4WkdKaE5HVmxNR0ZtTVRJNU1UUXpOZz09IiwiYXVkIjpbIjFLZno4aXZidzBocWpvVGJvMUxiVlRKbDJmNGEiXSwiaXNzIjoiaHR0cHM6XC9cL2xvY2FsaG9zdDo5NDQzXC9vYXV0aDJlbmRwb2ludHNcL3Rva2VuIiwiaWF0IjoxNDMwMzg5MjYxMjkyfQ.DC9jDagCCkOXYD4ZVF-9wNpddoTdH96B7Mw_3nGv-2lW9SiWvL600b4Cch2mNoFAao1QeGl9pAP4bvbVgJGuthunQxBJuTYLy2KCH5k5Hc9lQsZtEM5Z6yzQ7q2wWfu9il9Lya-gUXVnBJEd5ovqtwI40KSLvuZUoei7l3S8lZo","access_token":"cd23cbcc4b63c61dba4ee0af1291436"} 


Then we can use the access token retrieved above to view profile info with the curl command below.


curl -k -H "Authorization: Bearer <access-token>" <userinfo-edpoint>?schema=openid 


A sample command is as follows 


curl -k -H "Authorization: Bearer 7244fef5b5de362489c5b2ed16de9e" https://localhost:9443/oauth2/userinfo?schema=openid 


This will then retrieve the list of user info attributes that has not null values as the output below.


{"name":"admin","family_name":"admin","preferred_username":"admin","given_name":"admin"} 


If you have looked into identity.xml inside <IS-HOME>/ repository/conf, you can find the response builder class as follows, You can customize this extending the interface UserInfoResponseBuilder [1]. Sample implementation can be found in [2].

 [1]UserInfoResponseBuilder.java 
 [2]UserInfoJSONResponseBuilder.java


Monday, December 29, 2014

Java Collections Framework

This post will give a brief knowledge on Java Collections framework. This may not cover each and every implementation but most commonly used classes.

Before Java Collections framework was introduced, Arrays, HashTables and Vectors were the standard methods for grouping and manipulate collections of objects. But these implementations used different methods and syntax for accessing members (arrays used [], Vector used elementAt() methods while HashTable used get() and put() method. So you can't wrap one object to another easily). They were too static (changing the size and the type is hard) and had few built-in functions. Further most of the methods in Vector class were marked as final (so that you can't extend is behavior to implement a similar sort of collection), and most importantly none of them implements a standard interface. As programmers develop algorithms (such as sorting) to manipulate collections, they have to decide on what object to pass to the algorithm. Should they pass an Array or Vector or implement both interfaces?

The Java Collections framework provides a set of classes and interfaced to handle collections of objects. Most of the implementations can be found in java.util package. The Collections interface extends Iterable interface which make the Iterable interface (java.lang.Iterable) one of the root interfaced of the java collection classes. Thus all the subtypes of Collections also implements the Iterable interface. It has only one methd: iterator().

There are mainly 2 groups in the framework: Collections and Maps.

Collection

We have collection interface at the top that is used to pass collections around and manipulate then in the most generic way. All other interfaces List, Set etc extends this and make more customized objects.

Figure 1:Overview of Collection
List, Set, SortedSet, NavigableSet, Queue, Deque extends the Collection interface. The Collection interface just defines a set of  basic behaviors (methods such as adding, removing etc) that each of these collection sub-types share.
Both Set and List implements the Collections interface. The Set interface is identical to the Collection interface except for an additional method toArray() which converts a Set to an object array. The List interface also implements the Collections interface but provide more accessors that use and integer index into the List. For instance get(), remove(), and set() all take an integer that affects the indexed element in the list.

Map

The Map interface is not derived from Collection, but provides an interface similar to the methods in java.util.Hashtable.

Figure 2:Map interface
Keys are used to put and get values. This interface is implemented with two new concrete implementations, the TreeMap and the HashMap. The TreeMap is a balanced tree implementation that sorts elements by the key.


Benefits


  • The main advantage is it provides a consistent and a regular API. This reduces the effort required to design and implement APIs. 
  • Reduces programming effort - by providing data structures and algorithms so you don't have to write them yourself. 
  • Increases performance -  by providing high performance implementations of data structures and algorithms. As various implementations of each interface are interchangeable, programs can be tuned by switching implementations.  


List

The 2 commonly used implementations are LinkedList and ArrayList. List allow duplicates in the collections and use indexes to access elements. When deciding between these two implementations, we should consider whether the list is volatile (grows or shrinks often) and whether the access to items is random or ordered.

Following are 2 ways of initializing an ArrayList. Which method is correct?


List<String> values = new ArrayList<String>();

ArrayList<String> values = new ArrayList<String>();

Both approaches are acceptable. But the first option is more suitable. The main reason you'd do the first way is to decouple your code from a specific implementation of the interface and it allows you to switch between different implementations of the List interface with ease. eg: method public List getList() will allow you return any type that implements List interface. An interface gives you more abstraction, and make the code more flexible and resilient to changes as you can use different implementations.

ArrayList - A widely used collections framework in java. We can specify the size while initializing if not a default size will be used initially. We can add and retrieve items using add() and get() methods. But incase of removing items have to use with care. Internally this maintains an array to store items. So if you remove an item at the end, it will just remove the last element. But if you remove the first element, the operation will be very slow. (As it will remove first and copy all the following items back to fill the gap).

LinkedList - Internally maintains a doubly linked list, so that each element has a reference to the previous and next element. Thus retrieving an item from the list will be slow compared to the ArrayList as it traverse elements from the beginning.

The rule is if you want to add or remove items from the end of your list, it is efficient to use ArrayList, and to add or remove items from anywhere else it is efficient to use LinkedList.

Below sample will show using List implementations.




Set

Set does not allow duplicates in the collection. Adding a duplicate add nothing to a Set.  Sets allow mathematical operations such as intersection, union, difference.



Map

Maps store elements as key-value pairs. Can store any kind of objects. If you need to store customized objects as the keys, then you need to implement your own hashcode. The keys have to be unique. The inbuilt method map.keySet() returns a Set and does not have duplicates in the result. Thus if you have added different values with same keys, older will be replaced by the new one
If you iterate and retrieve items from the map, this will not maintain any order. Hence will get random order when iterate.

Two commonly used implementations are LinkedHashMap and TreeMap. LinkedHashMap will return values in order that they were inserted, while the treeMap is going to sort the keys


References:

[1]This is a very useful set of video tutorials that I could found on - Java Collections Framework