Authorize like a Pro with Axiomatics and UMA

Authorize like Champ with Axiomatics and UMA

Overview

Gluu is not really a great place to store policies. While you can express policies in Gluu Server RPT interception scripts, if you have more then a few policies, this approach does not scale. For a long time, we’ve recommended using a product that makes it easier to manage your policies. Axiomatics is one of the leaders in this field. This blog is an overview of a demo we did for the European Identity Conference. We will describe how we protected an API with the Gluu Gateway, and delegated policy evaluation to the Axiomatics Policy Server.

Prerequisites

  • Axiomatic Policy server:
    Returns authorization decisions based on attribute and contextual policies
  • Gluu ServerCommunity Edition 3.1.6 Acts as the UMA Authorization Server
  • Gluu Gateway 2.0: Acts as the policy enforcement point–requiring the presence of certain UMA scopes to grant access to an API
  • oxd UMA Client and Resource Server middleware API’s–installed as a dependency of Gluu Gateway

Configuration

  1. Configure service and route The first step is to configure the service and route in Kong, which controls the basic proxying behavior to the upstream API. This can be done using the Gluu Gateway Admin UI. For more details, see the Gluu Gateway docs on adding routes.

  2. Configure plugins The second step is to configure the Kong plugins. More details see the Gluu Gateway docs on adding a plugin.
    Basically, you need to configure the API gateway to require the presence of an UMA RPT token with a certain scope before it proxies to a certain API. For this, Kong uses the gluu-uma-auth and gluu-uma-pep plugins. See the plugin docs for more details.

  3. Protect Resources In the Gluu Gateway admin Web UI, you can specify which URI patterns are protected. In our example, we used /users/?? GET POST PUT DELETE which is protected by the with-claims UMA scope. GG 2.0 supports wild card characters. The ?? tells GG to protect all the resources which are in the /users folder (path). See the Gluu Gateway docs on resource wildcards for more details.

  4. Configure UMA Scope in Gluu Server The Gluu Server needs to know about this scope. In our example, you’ll can add the scope with-claims using the Gluu Server Admin Console (i.e. oxTrust) and then associate it with the uma_rpt_policy policy.

  5. Call XACML PDP from Script
    Update the script for uma_rpt_policy to call the Axiomatic policy endpoint. Below is the sample code to call the Axiomatic Policy API in the authorize function of uma_rpt_policy policy. Note we send the Request, Resource, Action and Environment to the PDP for a policy decision.
    
    def authorize(self, context):
     country = context.getClaim("country")
     city = context.getClaim("city")
    
     parameters = """{
      "Request": {"AccessSubject": {"Attribute": [{"AttributeId": "country","Value": "%s"}, {"AttributeId": "city","Value": "%s"}]},
      "Resource": {"Attribute": [{"AttributeId": "document_id","Value": "companypolicy"}]},
      "Action": {"Attribute": [{"AttributeId": "idaction","Value": "view"}]},
      "Environment": {"Attribute": [{"AttributeId": "isAllowed","Value": true }]}}
      }""" % (country, city)
    
         creds = bytearray("client_id:secret",'utf-8')
         encodedCreds = Base64.getEncoder().encodeToString(creds);
         basicAuth = "Basic "+ encodedCreds
         url = URL("http://localhost:4080/authorize")
         conn = url.openConnection()
         conn.setDoOutput(True)
         conn.setRequestMethod("POST")
         conn.setRequestProperty("Content-type", "application/xacml+json")
         conn.setRequestProperty ("Authorization", basicAuth)
         conn.getOutputStream().write(bytearray(parameters, 'utf-8'))
    
    
        if conn.getResponseCode() != 200: 
                print "Failed!!"
                print conn.getResponseCode()
                print conn.getResponseMessage()
            else:
                print "Success!!"
                print conn.getResponseCode()
                print conn.getResponseMessage()
    
            instr = conn.getInputStream()
            instrreader = InputStreamReader(instr)
            breader = BufferedReader(instrreader)
            output = breader.readLine()
            jsonResult = ""
            while output != None:
                if output != None:
                    jsonResult += output
                output = breader.readLine()
                 break
            print jsonResult
            conn.disconnect()
    
            jobj1 = JSONObject(jsonResult)
            jarr1 = jobj1.get("Response")
            jobj2 = jarr1.get(0)
            decision = jobj2.get("Decision")
    
            print decision
    
            if decision == "Permit": 
                print "Axiomatics  Authorization successful..."
                return True
        print "Axiomatics  Authorization failed..."    
        return False
    
    

    Conclusion

    Now the web page or API is protected, and requests will only be allowed to users from a certain city and country as defined by policies in Axiomatics! How to define policies in Axiomatics is out of scope for this disucssion, but see their website and documentation for more info.

Have an IAM project you would like to discuss?