Using PingAccess to limit access to web applications based on browser

Recently, we at PEGRight have seen an increasing demand to limit access to Web Applications (published through PingAccess) based on the browser criteria, such as user-agent. This blog post will show how to do this.

If you have an application that is browser specific (e.g., Internet Explorer only) - maybe due to compatibility issues, policy, whatever - you may desire to block requests at PingAccess so the user never lands on the application if the user-agent (i.e., browser) isn't supported.

To accomplish this, you're going to want create a Policy in PingAccess. This policy should be of type "GROOVY SCRIPT (FOR WEB APPS)". Upon completion of the Policy's configuration, you will apply that policy to the Application or Resource which needs protecting. Note: Groovy scripts give a tremendous amount of flexibility when dealing with complex rules.

The script itself is going to utilize the "anyOf" Matcher. This matcher will specify the collection of supported browsers. For example:

PingAccess Groovy script - Limit by browser

The code from the screenshot above looks as follows:

1
2
3
4
anyOf(
    requestHeaderContains("User-Agent", "*Chrome*"),
    requestHeaderContains("User-Agent", "*Firefox*")
)


The “AnyOf” directive implements “Or” logic where as the “AllOf” implements “And” logic. In the above example, if we try to hit the test site with Firefox or Chrome, we’d connect fine. If we try to hit it with IE, then we'd get the following:

PingAccess - Access Denied Error

To go along with the above Access Denied message, you'd see similar messages as the following in your PingAccess.log file.

1
2
3
4
5
6
7
2016-06-17T09:49:41,737 DEBUG [iYPqd_VdBxLRL5s_D6h9kw] com.pingidentity.pa.policy.BuiltInRuleInterceptorBase - Policy failure:
       (request source 'HEADER', field 'User-Agent' contains '*Chrome*', negate the value 'false', case sensitive, 'false' or request source 'HEADER', field 'User-Agent' contains '*Firefox*', negate the value 'false', case sensitive, 'false')
       with context: "com.pingidentity.pa.api.policy.PolicyContext@e0939f2"
2016-06-17T09:49:41,738 DEBUG [iYPqd_VdBxLRL5s_D6h9kw] com.pingidentity.pa.core.interceptor.flow.InterceptorFlowController - Exception caught.  Invoking abort handlers
com.pingidentity.pa.sdk.policy.PolicyAccessException: Policy Error
       at com.pingidentity.pa.policy.PolicyEnforcementInterceptor.handleRequest(PolicyEnforcementInterceptor.java:55) ~[pingaccess-engine-4.0.1.3.jar:4.0.1.3]
[…]


Note: The available “matchers” (e.g. “requestHeaderContains”) can be found here.

If we expand out the use-case a bit, let's fabricate another request: "Do not allow mobile devices". How might we block mobile devices based on user agent? Well, the solution is very similar. You'd create another policy, and it might look something like this:

1
2
3
4
5
not(anyOf(
       requestHeaderContains("User-Agent", "*iPhone*"),
       requestHeaderContains("User-Agent", "*iPad*"),
       requestHeaderContains("User-Agent", "*Android*")
))


You see we used the negation matcher ("not()"). Now, if the user-agent string in the request header included any of those strings, the connection would be blocked. If we wanted the opposite of this (i.e., only allow mobile devices) - we could remove the negation matcher thusly:

1
2
3
4
5
anyOf(
       requestHeaderContains("User-Agent", "*iPhone*"),
       requestHeaderContains("User-Agent", "*iPad*"),
       requestHeaderContains("User-Agent", "*Android*")
)


There are plenty of other interesting and exciting examples of problems that can be solved with the Groovy scripts. We at PEGRight hope that you've found this technical guide helpful and informative. If you have comments or questions, please contact us!

Rate this blog entry:
0