Skip to content

Commit

Permalink
Adding READMEs
Browse files Browse the repository at this point in the history
  • Loading branch information
rnavagamuwa committed Apr 1, 2019
1 parent 3499b52 commit cf133f5
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 90 deletions.
79 changes: 1 addition & 78 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,84 +1,7 @@
# XACML based authorization for Spring security

### Overview

Even though spring security provides role-based access control it doesn’t allow users to perform policy-based authorization. The main goal of this project is to write an agent which can be used to perform attribute-based access control for Spring security.

### Implementation

Spring security provides an annotation for custom authorization evaluations.

As the initial version, I have managed to write a working sample for this use case. This sample talks to WSO2 PDP for authorization.

#### The high-level sequence diagram


![](https://i.imgur.com/CUBbSxB.png)


#### Usage

1. Create a `keystore` and a `trustStore` in *Resources* directory.
2. Create a file named `xacmlConfig.json` in *Resources* directory. This file contains the body of the XACML request.
* This file is a json file and this can have more than one *Target Domain Objects*. In this case let's define our target domain object as **admin_xacml**.
* All the variables should start with **'$'**. For example if **action-id** is the variable it should be defined in the `xacmlConfig.sjon` as **$action-id**.

A sample `xacmlConfig.json` file is as follows.
````
{
"admin_xacml": {
"Request": {
"Action": {
"Attribute": [
{
"AttributeId": "urn:oasis:names:tc:xacml:1.0:action:action-id",
"Value": "$action-id"
}
]
},
"Resource": {
"Attribute": [
{
"AttributeId": "urn:oasis:names:tc:xacml:1.0:resource:resource-id",
"Value": "$resource-id"
}
]
}
}
}
}
````
3. Define following properties in the `application.properties` file.
```
xacml.pdp.url.authorize=https://localhost:9443/api/identity/entitlement/decision/pdp
xacml.pdp.url.resourceList=https://localhost:9443/api/identity/entitlement/decision/home
xacml.pdp.trustStore=truststore
xacml.pdp.trustStore.password=password
xacml.pdp.keyStore=keystore
xacml.pdp.keyStore.password=password
```
4. Extend `GlobalMethodSecurityConfiguration` class and set `AttributeEvaluator` as the new `PermissionEvaluator`
```
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler =
new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(new AttributeEvaluator());
return expressionHandler;
}
}
```
5. Now add the `@PreAuthorize("hasPermission()")` or `@PostAuthorize("hasPermission()")` annotation as required before the correct controller method. *Target Domain Object* and the *Permissions* should be passed to this annotaion as parameters.*Permissions* is a json object which contains the key value pairs. These permission values will be extracted from the *headers*.

```
@PreAuthorize("hasPermission('admin_xacml','{$action-id:action-id,$resource-id:resource-id}')")
```

#### Note
In addition to XACML Based Authorization, this SDK exposes methods to get `API Resource List` and `Entitled Attributes`.
As the initial version, I have managed to write a working sample for this use case. This sample talks to WSO2 PDP for authorization.
59 changes: 59 additions & 0 deletions sample/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# XACML based authorization for Spring security - Sample

### Overview

Even though spring security provides role-based access control it doesn’t allow users to perform policy-based authorization. The main goal of this project is to write an agent which can be used to perform attribute-based access control for Spring security.

### Implementation

Spring security provides an annotation for custom authorization evaluations.

As the initial version, I have managed to write a working sample for this use case. This sample talks to WSO2 PDP for authorization.

#### Usage

1. Start WSO2-IS by following [Installation Guide](https://docs.wso2.com/display/IS570/Installation+Guide).
2. Publish the following XAML Policy by following [Publishing a XACML Policy](https://docs.wso2.com/display/IS570/Publishing+a+XACML+Policy).
```
<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="samplePolicy" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0">
<Target>
<AnyOf>
<AllOf>
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http:https://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
<AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" DataType="http:https://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
</Match>
</AllOf>
</AnyOf>
</Target>
<Rule Effect="Permit" RuleId="permit"></Rule>
</Policy>
```
3. Configure SSO by following [Configure Single Sign-On](https://docs.wso2.com/display/IS570/Configuring+Single+Sign-On)
- Issuer id : com:rnavagamuwa:springsecurity
- Assertion consumer URL : http:https://localhost:8080/saml/SSO
- SLO response\request URL : http:https://localhost:8080/saml/SingleLogout
4. Replace the `keystore,jks` and a `trustStore,jks` in *Resources* directory with the correct ones.

5. Define following properties in the `application.properties` file.
```
xacml.pdp.url.entitlement.service=https://localhost:9443/api/identity/entitlement/decision xacml.pdp.url.resourceList=https://localhost:9443/api/identity/entitlement/decision/home
xacml.pdp.trustStore=truststore.jks
xacml.pdp.trustStore.password=password
xacml.pdp.keyStore=keystore.jks
xacml.pdp.keyStore.password=password
```
6. Run the spring boot app by executing `mvn spring-boot:run`
7. Navigate to [http:https://localhost:8080](http:https://localhost:8080) and you'll be redirected to the following page.
![](https://i.imgur.com/oPHkonjl.png)
8. Provide the username and password. (Default is `admin`,`admin`). Then you'll be redirected to the landing page.
![](https://i.imgur.com/OryiqQ1.png)
9. Then click on `Hello` button. Add the following authorization headers and click on `Submit Request`
- Header Key : **action-id** | Header Value : **read**
- Header Key : **resource-id** | Header Value : **http:https://127.0.0.1/service/very_secure/**

You should get the message `Successfully authorized` message if authorized.

![](https://i.imgur.com/wzfOT6p.png)

10. In addition to this you can remove the headers and submit.
66 changes: 55 additions & 11 deletions sdk/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# XACML based authorization for Spring security
# XACML based authorization for Spring security - SDK

### Overview

Expand All @@ -21,8 +21,8 @@ As the initial version, I have managed to write a working sample for this use ca
1. Create a `keystore` and a `trustStore` in *Resources* directory.
2. Create a file named `xacmlConfig.json` in *Resources* directory. This file contains the body of the XACML request.
* This file is a json file and this can have more than one *Target Domain Objects*. In this case let's define our target domain object as **admin_xacml**.
* All the variables should start with **'$'**. For example if **action-id** is the variable it should be defined in the `xacmlConfig.sjon` as **$action-id**.

* All the variables should be passed as **'${variable}'**. For example if **action-id** is the variable it should be defined in the `xacmlConfig.sjon` as **${actionid}**.
A sample `xacmlConfig.json` file is as follows.
````
{
Expand All @@ -32,15 +32,15 @@ As the initial version, I have managed to write a working sample for this use ca
"Attribute": [
{
"AttributeId": "urn:oasis:names:tc:xacml:1.0:action:action-id",
"Value": "$action-id"
"Value": "${actionid}"
}
]
},
"Resource": {
"Attribute": [
{
"AttributeId": "urn:oasis:names:tc:xacml:1.0:resource:resource-id",
"Value": "$resource-id"
"Value": "${resourceid}"
}
]
}
Expand All @@ -51,8 +51,7 @@ As the initial version, I have managed to write a working sample for this use ca
3. Define following properties in the `application.properties` file.
```
xacml.pdp.url.authorize=https://localhost:9443/api/identity/entitlement/decision/pdp
xacml.pdp.url.resourceList=https://localhost:9443/api/identity/entitlement/decision/home
xacml.pdp.url.entitlement.service=https://localhost:9443/api/identity/entitlement/decision
xacml.pdp.trustStore=truststore
xacml.pdp.trustStore.password=password
xacml.pdp.keyStore=keystore
Expand All @@ -74,11 +73,56 @@ As the initial version, I have managed to write a working sample for this use ca
}
}
```
5. Now add the `@PreAuthorize("hasPermission()")` or `@PostAuthorize("hasPermission()")` annotation as required before the correct controller method. *Target Domain Object* and the *Permissions* should be passed to this annotaion as parameters.*Permissions* is a json object which contains the key value pairs. These permission values will be extracted from the *headers*.

5. Now add the `@PreAuthorize("hasPermission()")` or `@PostAuthorize("hasPermission()")` annotation as required before the correct controller method.
*Target Domain Object* and the *Permissions* should be passed to this annotation as parameters.*Permissions* is a json object which contains the key value pairs.
Permission values can be extracted from any of the following.
- Headers
- Pass the value as `header.value`
- Query params
- Pass the value as `queryParam.value`
- Path params
- Pass the value as `pathParam.value`
- Form data
- Pass the value as `formData.value`
- Cookies
- Pass the value as `cookie.value`

For example, let's assume we want to extract `action-id` and `resource-id` from headers.
```
@PreAuthorize("hasPermission('admin_xacml','{$action-id:action-id,$resource-id:resource-id}')")
```

#### Note
In addition to XACML Based Authorization, this SDK exposes methods to get `API Resource List` and `Entitled Attributes`.
#### Other exposed APIs
In addition to XACML Based Authorization, this SDK exposes following methods

- API Resources List
- `getApiResourceList()` can be used to get the API Resource List. Response is a XACML JSON Object.
- Get entitled attributes
- `getEntitledAttributes(String subjectName, String resourceName, String subjectId, String action, boolean enableChildSearch)` method
should be called and the response will be a JSON object with the following format
```
EntitledAttributesResponseModel {
entitledResultSetDTO:EntitledResultSetDTO {
entitledAttributesDTOs:[
EntitledAttributesDTO {
resourceName:string
action:string
environment:string
allActions:boolean
allResources:boolean
attributeDTOs:[
AttributeDTO {
attributeValue:string
attributeDataType:string
attributeId:string
category:string
}
]
}
]
advanceResult:boolean
message:string
messageType:string
}
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ private enum PropertyType {
HEADER("header"),
QUERY_PARAM("queryParam"),
COOKIE("cookie"),
FORM_DATA("formdata"),
FORM_DATA("formData"),
PATH_PARAM("pathParam");

private String property;
Expand Down

0 comments on commit cf133f5

Please sign in to comment.