Note:
- This tutorial requires access to Oracle Cloud. To sign up for a free account, see Get started with Oracle Cloud Infrastructure Free Tier.
- It uses example values for Oracle Cloud Infrastructure credentials, tenancy, and compartments. When completing your lab, substitute these values with ones specific to your cloud environment.
Deploy App Gateway with Oracle Analytics Server on OCI Identity and Access Management Domains for Single Sign-On
Introduction
If you want to implement Single Sign-on (SSO) for Oracle Analytics Server on-premises using Oracle Cloud Infrastructure Identity and Access Management (OCI IAM) Domains, we recommend to set up the App Gateway for SSO with IAM Domains for Oracle Analytics Server application. This set up will enable users to use their IAM Domain credentials and log in to the Oracle Analytics Server application.
Key Benefits
-
User can use the credentials stored on IAM Domains.
-
User can also leverage the 3rd party Identity Provider (IDP) federated with IAM Domain.
Objectives
Implement SSO for accessing the Enterprise Oracle Analytics Server and learn how to deploy the App Gateway docker image for SSO with IAM.
Prerequisites
-
Oracle Apps Premium SKU for IAM Domains.
-
Admin account for the IAM Domain.
-
A machine to run the App Gateway.
-
Oracle Analytics Server Application. If you do not have Oracle Analytics Server application, you can create one using the Marketplace Image, see Deploy Oracle Analytics Server on Oracle Cloud.
Task 1: Create an Enterprise Application in IAM Domain
You can create an Enterprise Application in IAM Domain using two approaches:
Approach 1: Create the Enterprise Application manually via Console
-
Register the Enterprise Application in the IAM Domain. This will represent your Oracle Analytics Server application. Provide the necessary detail to register the application in IAM Domain and edit the SSO configuration. You can add the default resource to allow the access to all resources, else you can add each resources manually to get access to specific resources. Also, you can check the Configure SSO with Oracle Identity Cloud Service and App Gateway to know about the resources to add.
Default Resource: /.*
Check the box for Allow CORS, Require secure cookies and Add managed resources.
-
Add the resources to the Authentication Policy. Add the default resource to cover all the resources. While adding it for authentication policy, remember to add the header for as iv-user and map it to the User Name.
Approach 2: Create the Enterprise Application via Python code
-
Create a confidential application and retrieve client ID and client secret, which can then be used to perform a REST API call to OCI IAM for retrieving Access Token and subsequent API endpoints, see Oracle Identity Cloud Service: First REST API Call.
-
Set up the config file on your local machine. The
config.json
file has information about the Identity Domain URL, Client ID and Client Secret which is used to generate the Access Token.{ "iamurl" : "https://idcs-###########.identity.oraclecloud.com", "client_id" : "#######################", "client_secret" : "#######################" }
-
Generate the Access Token, which can be used to make further REST API calls to the OCI IAM endpoints.
In the below code snippet, the function
_get_encoded_
takes in Client ID and Client Secret as arguments and returns the base64-encoded string. This encoded string is further passed as an argument to the functionget_access_token
as an Authorization header, to obtain the Access Token by performing a POST request.#get base64 encoded def get_encoded(self,clid, clsecret): encoded = clid + ":" + clsecret baseencoded = base64.urlsafe_b64encode(encoded.encode('UTF-8')).decode('ascii') return baseencoded #get access token def get_access_token(self,url, header): para = "grant_type=client_credentials&scope=urn:opc:idm:__myscopes__" response = requests.post(url, headers=header, data=para, verify=False) jsonresp = json.loads(response.content) access_token = jsonresp.get('access_token') return access_token #print access token def printaccesstoken(self): obj = IAM() encodedtoken = obj.get_encoded(clientID, clientSecret) extra = "/oauth2/v1/token" headers = {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', 'Authorization': 'Basic %s' % encodedtoken, 'Accept': '*/*'} accesstoken = obj.get_access_token(idcsURL + extra, headers) return accesstoken
-
Create Enterprise application in IAM domain using the below Python code snippet.
def createapplication(self): global clID global appID global resID1 obj = IAM() obj.searchapps() accesstoken = obj.printaccesstoken() extra = "/admin/v1/Apps" headers = {'Accept': '*/*', 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + accesstoken} para = json.dumps({ "schemas": [ "urn:ietf:params:scim:schemas:oracle:idcs:App", "urn:ietf:params:scim:schemas:oracle:idcs:extension:samlServiceProvider:App", "urn:ietf:params:scim:schemas:oracle:idcs:extension:requestable:App", "urn:ietf:params:scim:schemas:oracle:idcs:extension:managedapp:App", "urn:ietf:params:scim:schemas:oracle:idcs:extension:webTierPolicy:App" ], "displayName": "OAS Enterprise App", "description": "New Enterprise Application for OAS", "landingPageURL": "http://150.xx.xx.xx:9502/analytics", "basedOnTemplate": { "value": "CustomEnterpriseAppTemplateId" }, "isSamlServiceProvider": False, "isOAuthResource": False, "isOAuthClient": False, "showInMyApps": False, "isWebTierPolicy": False, "active": True, "isEnterpriseApp": True, "urn:ietf:params:scim:schemas:oracle:idcs:extension:requestable:App": { "requestable": False }, "urn:ietf:params:scim:schemas:oracle:idcs:extension:webTierPolicy:App": { "webTierPolicyAZControl": "local" } }) resp = requests.post(idcsURL + extra, headers=headers, verify=False, data=para) jsonresp = json.loads(resp.content) clID = jsonresp.get("name") #clSecret = jsonresp.get("clientSecret") appID = jsonresp.get("id") print("OAS Enterprise Application created with Client ID") print(clID) print("App ID of the created OAS Enterprise Application is :") print(appID) extra1 = "/admin/v1/AppResources" extra5 = "/admin/v1/Apps/"+appID headers1 = {'Accept': '*/*', 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + accesstoken} data= pd.read_csv("AppResourse.csv",delimiter=',') x=0 # For Reading the Data from the CSV file i=1 # For Providing the sequence vaule to the Web Policy ### This part of the code reads the data from CSV file adds the AppResource to the Enterprise application and also adds the Web Policy for all the added resources### for line in data.iterrows() : AppRsUrl=data.AppResourseURL[x] ## Take Application Resource URL as input from CSV file at xth Location ##print(AppRsUrl) metD=data.accessMode[x] ## Take Access method for Application Resource URL as input from CSV file at xth Location ResName=data.ResourceName[x] ## Take Application Resource Name as input from CSV file at xth Location para1 = json.dumps({ "schemas": [ "urn:ietf:params:scim:schemas:oracle:idcs:AppResource" ], "name": ResName, "resourceURL": AppRsUrl, "isRegex": True, "description": "OAS App Resourse", "app": { "value": appID } }) resp1 = requests.request("POST",idcsURL + extra1, headers=headers1, verify=False, data=para1) ##print(resp1) jsonresp1 = json.loads(resp1.content) ##print(jsonresp1) resID1= jsonresp1.get("id") print("Resourse Added to the OAS Enterprise Application with ID") print(resID1) para3 = json.dumps({ "schemas":[ "urn:ietf:params:scim:api:messages:2.0:PatchOp" ], "Operations":[ { "op":"add", "path":"urn:ietf:params:scim:schemas:oracle:idcs:extension:enterpriseApp:App:appResources", "value":[ { "value":resID1 } ]}]}) resp3 = requests.request("PATCH",idcsURL + extra5, headers=headers1, verify=False, data=para3) # print(resp3) # jsonresp3 = json.loads(resp3.content) # print(jsonresp3) ### Based on the Access Mode the Web Policy will be generated### if metD=="oauth": jsonBody= "{\"filter\":\""+AppRsUrl+"\",\"headers\":[{\"iv-user\":\"$subject.user.userName\"}],\"comment\":\"abc\",\"resourceRefId\": \""+resID1+"\",\"resourceRefName\":\""+ResName+"\",\"type\":\"regex\",\"sequence\":\""+str(i)+"\",\"method\":\"oauth\"}"+"," else: jsonBody= "{\"filter\":\""+AppRsUrl+"\",\"comment\":\"abc\",\"resourceRefId\": \""+resID1+"\",\"resourceRefName\":\""+ResName+"\",\"type\":\"regex\",\"sequence\":\""+str(i)+"\",\"method\":\"public\"}"+"," ##print(jsonBody) x=x+1 i=i+1 with open('data.json', 'a') as f: json.dump(jsonBody, f) ## construct the payload for webtier and send it as a Json Body to the REST call### with open('data.json', 'r') as file: ## Temp json file to hold the payload before getting formated data = file.read() data1=data.replace('""','') ##print(data1) with open('formatedData.json', 'a') as file1: ## Actual json file to hoad the payload for the REST call to PATCH WebPolicy file1.writelines('{ \n') file1.writelines('"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],\n') file1.writelines('"Operations": [\n') file1.writelines('{"op": "add",\n') file1.writelines('"path": "urn:ietf:params:scim:schemas:oracle:idcs:extension:webTierPolicy:App:webTierPolicyJson",\n') file1.writelines(R'"value":"{\"cloudgatePolicy\":{\"version\":\"2.6\",\"requireSecureCookies\":true,\"allowCors\":true,\"disableAuthorize\":true,\"webtierPolicy\":[{\"policyName\":\"default\",\"comment\":\"Webtier policy\",\"resourceFilters\":[') data2=re.sub(r'.', '', data1, count = 1) data3=data2.rstrip(data2[-1]) data4=data3.rstrip(data3[-1]) file1.write(data4) file1.write(']}]}}"}]}') os.remove("data.json") ### REST API Call to PATCH the Web Policy to the created Enterprise Application### extra2 = "/admin/v1/Apps/"+appID headers2 = {'Accept': '*/*', 'Content-Type': 'application/scim+json', 'Authorization': 'Bearer ' + accesstoken} param = {'attributes': "urn:ietf:params:scim:schemas:oracle:idcs:extension:webTierPolicy:App:webTierPolicyJson,urn:ietf:params:scim:schemas:oracle:idcs:extension:webTierPolicy:App:webTierPolicyAZControl,urn:ietf:params:scim:schemas:oracle:idcs:extension:webTierPolicy:App:resourceRef"} webPolicy = json.load(open('formatedData.json')) payload = json.dumps(webPolicy) resp7 = requests.request("PATCH",idcsURL + extra2, headers=headers2, verify=False, data=payload, params=param) jsonresp7 = json.loads(resp7.content) ##print(resp7) ##print(jsonresp7) print("The OAS Enterprise Application has been PATCH with the WebPolicy for all the added Resources") os.remove("formatedData.json")
-
You will need a
csv
file containing all the resources to be created using the above code snippet. Here is the link to the resource AppResources.csv.
Note: Make sure you have Python 3.x installed on your system and
urllib3
,requests
andpandas
Python packages installed as well to use the above code snippet. Also, the above code snippet is for reference purpose only and you can also build your own logic to achieve the same.
Task 2: Create App Gateway in IAM Domain
-
Create the App Gateway on the IAM Domain under Security tab. Provide the necessary details to complete the configuration. Details needed to register the App Gateway are Name of the App Gateway and Host, which is the Public IP of the machine where you want to deploy the App Gateway image. Select the SSL enabled check box and add the certificate in the Additional Properties section that you are going to use for App Gateway in below format. Add correct path of the certificate on the App Gateway.
ssl_certificate /usr/local/nginx/conf/server.crt; ssl_certificate_key /usr/local/nginx/conf/server.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5;
Note: You can use the public SSL certificate for above step and if you do not have any public certificate then you can use the self signed certificate as well. You can generate the self signed certificate with the following openSSL command.
openssl req -x509 -newkey rsa:4096 -keyout /home/opc/certs/key.pem -out /home/opc/certs/cert.pem -sha256 -days 3650 -nodes -subj "/C=US/ST=Florida/L=Miami/O=Oracle/OU=Cloud/CN=oracle"
-
Add the Enterprise application on the App Gateway we have registered in the first step as Apps. Choose the Enterprise app you created under Application, select Host under the Select a Host. Provide the Resource Prefix as / and under Origin Server provide the URL for your Oracle Analytics Server and Save the changes.
Task 3: Deploy the App Gateway Docker Image
-
Download the App Gateway docker image. In IAM Domain, on the left hand side menu, click Settings, and then click Downloads. Download the App Gateway Docker Image for Identity Cloud Service and the App Gateway Wallet tool. Keep the App Gateway Docker Image and Wallet tool in separate directories. For example:
/home/opc/appgateway
for App Gateway and/home/opc/cwallet
for Wallet tool. -
Create a wallet file containing the Client ID and Client Secret of the App Gateway that was created in the IAM Domain. Use the following steps to create the wallet file.
env LD_LIBRARY_PATH=./lib ./cgwallettool --create -i **ClientID of AppGateway in IAM Domain**.
Note: Upon executing the above, it will ask for Client Secret of App Gateway. These steps will create the
cwallet.sso
file for App Gateway. -
Install the Docker on the Machine for App Gateway using the following commands.
sudo yum-config-manager --disable ol7_UEKR3 ol7_UEKR4 sudo yum-config-manager --enable ol7_UEKR5 sudo yum-config-manager --enable ol7_addons sudo yum install docker-engine docker-cli -y sudo systemctl enable --now docker sudo systemctl status docker sudo docker info sudo usermod -a -G docker $USER
Note: We have used Oracle Linux 7 for configuring the docker image of App Gateway.
-
You can use the certificate from any trusted public certificate authority or create the self-signed certificate as well using openSSL. Self-signed certificate example is as below:
openssl req -x509 -newkey rsa:4096 -keyout /home/opc/certs/key.pem -out /home/opc/certs/cert.pem -sha256 -days 3650 -nodes -subj "/C=US/ST=Florida/L=Miami/O=Oracle/OU=Cloud/CN=oracle"
-
As the docker image is in
tar.gz
format, we need to extract the image to create the docker container with the following step. Load thetar.gz
file to the local Docker registry using following command:$ docker load -i **filename.tar.gz**
Task 4: Create App Gateway ENV file
-
To run the App Gateway Docker container, the following environment variables must be set in the
appgateway-env
file. CG_APP_TENANT=<tenant name>
IDCS_INSTANCE_URL=<idcs instance url>
. The URL required to access the Identity Cloud Service instance. NGINX_DNS_RESOLVER=<resolver ip>
.Note Do the nslookup of the IAM Domain URL and the server IP will be the value you need.
-
Run the Docker using following command.
sudo docker run -it -p 4443:4443 --name appgateway --env-file /home/opc/AppgwDocker/appgateway-env --env HOST_MACHINE=`hostname -f` --volume /home/opc/cwallet.sso:/usr/local/nginx/conf/cwallet.sso --volume /home/opc/server.key:/usr/local/nginx/conf/server.key --volume /home/opc/server.crt:/usr/local/nginx/conf/server.crt --net=host idcs/idcs-appgateway:23.2.92-2301160723
-
Restart the docker using below commands:
docker stop conatiner_ID docker start conatiner_ID
Task 5: Create Identity asserter on the Oracle Analytics Server WebLogic server
-
Log in as admin to the WebLogic server admin console.
-
Navigate to to the myrealm and to Providers. Create the OAMIdentityAsserter as a provider.
-
After creating the Provider, edit the same to change the Control Flag to Required and then choose the Active types as iv-user.
-
Set the iv-user in Provider Specific properties under SSOHeader Name and click Save.
-
Reorder the providers list and keep the newly created provider on top.
-
Restart the WebLogic server using script as below.
sudo su oracle cd /u01/data/domains/bi/bitools/bin ./stop.sh ./start.sh
-
Once the server is up again, you are ready to test the SSO.
Task 6: Test the SSO
Test the SSO by accessing the App Gateway URL https://AppGateway.example.com:4443/analytics
, it will redirect the user to the OCI IAM Identity Domain for authentication and after successful authentication, user will get access to Oracle Analytics Server based on their role.
Note: AppGateway.example.com is for reference here, use correct URL as per your environment and make sure you have the correct DNS routing for it.
Acknowledgments
- Author - Sagar Takkar (Senior Security Architect)
More Learning Resources
Explore other labs on docs.oracle.com/learn or access more free learning content on the Oracle Learning YouTube channel. Additionally, visit education.oracle.com/learning-explorer to become an Oracle Learning Explorer.
For product documentation, visit Oracle Help Center.
Deploy App Gateway with Oracle Analytics Server on OCI Identity and Access Management Domains for Single Sign-On
F88066-01
October 2023
Copyright © 2023, Oracle and/or its affiliates.