Difference between revisions of "Oauth"

From 3forge Documentation
Jump to navigation Jump to search
m (Elizabeth Marion moved page Security to 3forge Documentation:Security)
(Add new property for OAuth plugin, reformat page)
 
(11 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 +
=Introduction=
 +
 +
OAuth is one of the multiple ways you can authenticate users to 3forge AMI. The 3forge AMI OAuth Plugin makes it easy to integrate AMI with any OAuth based identity manager. It provides a simple standard authentication mechanism and allows you to build access control into your 3forge AMI Layouts.
  
 +
 +
Go to <strong>Section 2 OAuth Quickstart</strong> to quickly get started with using the OAuthPlugin.
 +
 +
 +
=OAuth Quickstart=
 +
 +
Prerequisites:
 +
<ol><li>Find out your identity provider and ensure it allows for OAuth 2.0 Authentication. You will need to know the identity provider url.
 +
 +
<li>Register a new Web App with your identity provider. 
 +
<ol type="a"><li>Provide a Sign In Redirect Url, we recommend https://<your-server>:33332/oauthRedirectUrl 
 +
<ol type="i"><li>This will be used in the oauth.redirect.url property
 +
</li></ol><li>Provide a Sign Out Redirect Url (Optional but recommended)
 +
</li></ol></li></ol>
 +
 +
 +
How to setup the OAuth Plugin
 +
<ol><li>Navigate to your 3forge AMI config directory, it's typically located in <em> ami\amione\config </em><li>Create a file called local.properties if one is not already present
 +
 +
<li>Add the properties from Section 2.2 Minimal Configuration to the file <em>local.properties</em><li>Update the values of the properties to match your identity provider.
 +
 +
<li>Restart 3forge AMI
 +
 +
</li></ol><h3>Minimal Configuration </h3>
 +
 +
Note: Please refer to Section 3 <em>OAuth Full Properties List </em>for a detailed understanding of each property
 +
 +
 +
sso.plugin.class=com.f1.ami.web.AmiWebOAuthPluginImpl
 +
 +
 +
<strong># Provide the url to your OAuth 2.0 identity provider</strong>
 +
 +
oauth.server.domain=https://oauthprovider.com 
 +
 +
 +
<strong># Provide the redirect url that you configured for the app with your identity provider</strong>
 +
 +
oauth.redirect.uri=http://localhost:33332/oauthRedirectUrl
 +
 +
 +
<strong># Provide the endpoints for authorization, token and refresh token</strong>
 +
 +
oauth.authorization.endpoint=/authorizeEndpoint
 +
 +
oauth.token.endpoint=/tokenEndpoint
 +
 +
oauth.refresh.token.endpoint=/refreshTokenEndpoint
 +
 +
 +
<strong># Properties related to refresh tokens, redirect uri and scope are optional, by default are set to null</strong>
 +
 +
oauth.refresh.redirect.uri=/refreshRedirectUri
 +
 +
oauth.refresh.scope=/refreshScope
 +
 +
oauth.refresh.client.id=/refreshClientId
 +
 +
oauth.refresh.client.secret=/refreshClientSecret
 +
 +
 +
<strong># Provide the client id and secret that will be used for the OAuth authentication</strong>
 +
 +
oauth.client.id=clientid
 +
 +
oauth.client.secret=secret
 +
 +
 +
<strong># Replace this with the default scope that is used for Web Based Applications in your firm</strong>
 +
 +
oauth.scope=openid profile email offline_access
 +
 +
 +
<strong># Replace this with unique identifier that identifies the user</strong>
 +
 +
oauth.username.field=email
 +
 +
 +
<strong># Recommended to replace this with an attribute that identifies the group a user belongs to</strong>
 +
 +
oauth.ami.isdev.field=email
 +
 +
oauth.ami.isdev.values=<comma_delimited_list_of_emails>
 +
 +
 +
<strong># Logout Page AMI will display when logged out</strong>
 +
 +
web.logged.out.url=/loggedout.htm
 +
 +
 +
<strong># This is enabled for development, disable this after OAuth has been setup</strong>
 +
 +
oauth.debug=true
 +
 +
 +
=OAuth Full Properties List=
 +
 +
 +
{| class="wikitable" style="margin:auto"
 +
|-
 +
! Description !! Property and Default Value
 +
|-
 +
| <span style="color:#FF0000">REQUIRED</span> <br />  Specify class to use Oauth SSO || sso.plugin.class=com.f1.ami.web.AmiWebOAuthPluginImpl
 +
|-
 +
| <span style="color:#FF0000">REQUIRED</span> <br /> The domain of the auth server account || oauth.server.domain=https://oauthprovider.com
 +
|-
 +
| <span style="color:#FF0000">REQUIRED</span> <br /> Set AMI logged out page || web.logged.out.url=/loggedout.htm
 +
|-
 +
| <span style="color:#FF0000">REQUIRED</span> <br /> 3forge AMI Url for Oauth server to redirect after login || oauth.redirect.uri=http://localhost:33332/oauthRedirectUrl/
 +
|-
 +
| <span style="color:#FF0000">REQUIRED</span> <br /> Client ID || oauth.client.id=clientid
 +
|-
 +
| <span style="color:#FF0000">REQUIRED</span> <br /> Client secret || oauth.client.secret=secret
 +
|-
 +
| <span style="color:#FF0000">REQUIRED</span> <br /> Authorization endpoint || oauth.authorization.endpoint=/authorizeEndpoint
 +
|-
 +
| <span style="color:#FF0000">REQUIRED</span> <br /> Token endpoint || oauth.token.endpoint=/tokenEndpoint
 +
|-
 +
| <span style="color:#FF0000">REQUIRED</span> <br /> Oauth scope || oauth.scope=openid profile email offline_access
 +
|-
 +
| <span style="color:#FF0000">REQUIRED</span> <br /> User Email || oauth.username.field=email
 +
|-
 +
| <span style="color:#3c78d8">OPTIONAL</span> <br /> The endpoint to get the refresh token || oauth.refresh.token.endpoint=/refreshTokenEndpoint
 +
|-
 +
| <span style="color:#3c78d8">OPTIONAL</span> <br /> The refresh redirect uri, by default is null, can be overriden || oauth.refresh.redirect.uri=/refreshRedirectUri
 +
|-
 +
| <span style="color:#3c78d8">OPTIONAL</span> <br /> The refresh scope, by default is null,can be overriden || oauth.refresh.scope=/refreshScope
 +
|-
 +
| <span style="color:#3c78d8">OPTIONAL</span> <br /> The client Id after refresh, by default is the same as ''oauth.client.id'',can be overriden || oauth.refresh.client.id=/refreshClientId
 +
|-
 +
| <span style="color:#3c78d8">OPTIONAL</span> <br /> The client Sercret after refresh, by default is the same as ''oauth.client.secret'',can be overriden || oauth.refresh.client.secret=/refreshClientSecret
 +
|-
 +
| <span style="color:#3c78d8">OPTIONAL</span> <br /> Dev User Email || oauth.ami.isdev.field=email
 +
|-
 +
| <span style="color:#3c78d8">OPTIONAL</span> <br /> List of dev user emails || oauth.ami.isdev.values=<comma_delimited_list_of_emails>
 +
|-
 +
| <span style="color:#3c78d8">OPTIONAL</span> <br /> Key that contains the time the access token expires in || oauth.access.token.expires.in=expires_in
 +
|-
 +
| <span style="color:#3c78d8">OPTIONAL</span> <br /> Code challenge method || oauth.code.challenge.method=S256
 +
|-
 +
| <span style="color:#3c78d8">OPTIONAL</span> <br /> Java hashing algorithm || oauth.digest.algo=SHA-256
 +
|-
 +
| <span style="color:#3c78d8">OPTIONAL</span> <br /> Seconds to check refresh token expiration || oauth.session.check.period.seconds=60
 +
|-
 +
| <span style="color:#3c78d8">OPTIONAL</span> <br /> The 3forge AMI endpoint that triggers the build auth request. || ami.web.index.html.file=index2.htm
 +
|-
 +
| <span style="color:#3c78d8">OPTIONAL</span> <br /> Enables Debugging Mode || oauth.debug=true
 +
|-
 +
| <span style="color:#3c78d8">OPTIONAL</span> <br /> Disables certificate validation (for ssl) || oauth.validate.certs=false
 +
 +
|}
 +
 +
 +
 +
=Creating your own AMI OAuth Plugin=
 +
 +
The AMI OAuth plugin handles authorization code and access token requests that are needed for Authenticating to AMI. By  extending the 3forge AMI OAuth plugin, you can create your own Ami OAuth Plugin if you have custom requirements for access control or entitlements. 
 +
 +
 +
There are three main components to the 3forge AMI OAuth Plugin: buildAuthRequest, processResponse, and createAmiUserSSOSession.
 +
==Main Components of the 3forge AMI OAuth Plugin==
 +
 +
The <strong>buildAuthRequest </strong>method is responsible for creating the url for the Authorization Code request.
 +
 +
 +
The <strong>processResponse </strong>method is responsible for processing the response from the Authorization Code request, then building an Access Token request. Once it obtains an access token, it needs to return an AmiAuthUser.
 +
 +
 +
The <strong>createAmiUserSSOSession </strong>is responsible for creating the AmiAuthUser and OAuthSSO Session. The AmiAuthUser can be used to set user session variables or  restrict access to layouts. The OAuth Session is accessible in AMIScript by session.getSsoSession().
 +
 +
 +
==Diagram of the 3forge AMI OAuth Plugin==
 +
 +
 +
[[File:OAuthDiagram.png]]
 +
 +
 +
==Example Java Code==
 +
 +
<syntaxhighlight lang="java" line="1">
 +
package com.company.3forge;
 +
 +
 +
import java.util.Map;
 +
import com.f1.ami.web.auth.AmiAuthUser;
 +
import com.f1.container.ContainerTools;
 +
import com.f1.http.HttpRequestResponse;
 +
import com.f1.http.HttpSession;
 +
import com.f1.suite.web.HttpRequestAction;
 +
import com.f1.utils.PropertyController;
 +
 +
 +
public class AmiWebOAuthPluginSample extends AmiWebOAuthPluginImpl {
 +
    @Override
 +
    public void init(ContainerTools tools, PropertyController props) {
 +
        // This is where you can initialize any properties.
 +
        super.init(tools, props);
 +
        String sample = props.getRequired("oauth.sample.property");
 +
        String sample2 = props.getOptional("oauth.sample2.property", "defaultValue");
 +
    }
 +
    @Override
 +
    public String getPluginId() {
 +
        return "SampleOAuthPlugin";
 +
    }
 +
    @Override
 +
    public String buildAuthRequest(HttpRequestResponse req) throws Exception {
 +
        HttpSession session = req.getSession(true);
 +
        String requestUri = req.getRequestUri(); // This will be your ami.web.index.html.file
 +
        Map<String, String> header = req.getHeader();
 +
        Map<String, String> cookies = req.getCookies();
 +
        Map<String, String> params = req.getParams();
 +
 +
 +
        // This is how you can add a cookie to the response
 +
        String optionalDomain = null;
 +
        long optionalExpires = 0;
 +
        req.putCookie("myCookie", "secretCode", optionalDomain, optionalExpires, null);
 +
 +
 +
        // This is how you add a header to the response
 +
        req.putResponseHeader("myHeader", "value");
 +
 +
 +
        // This will build an Authorization Code Request
 +
        String redirectUrlForLogin = super.buildAuthRequest(req);
 +
        return redirectUrlForLogin;
 +
    }
 +
    @Override
 +
    public String getExpectedResponsePath() {
 +
        // This returns the login redirect url that is provided to your identity manager, it is used in the buildAuthRequest
 +
        return super.getExpectedResponsePath();
 +
    }
 +
    @Override
 +
    public AmiAuthUser processResponse(HttpRequestAction req) throws Exception {
 +
        HttpRequestResponse authorizeResponse = req.getRequest();
 +
 +
 +
        // 1| Create access token request
 +
        Map<String, Object> accessTokenResult = doAccessTokenRequest(authorizeResponse);
 +
        if (accessTokenResult == null)
 +
            return null;
 +
        AmiAuthUser user = createAmiUserSSOSession(authorizeResponse, accessTokenResult);
 +
 +
 +
        // You may add your own properties to the AmiAuthUser via the auth attributes
 +
        Map<String, Object> authAttributes = user.getAuthAttributes();
 +
 +
 +
        // The below is the OAuth session which can be accessed via AMIScript through session.getSsoSession() which returns a SsoSession object
 +
        AmiWebOAuthSsoSession oauthSession = (AmiWebOAuthSsoSession) authAttributes.get(AmiAuthUser.PROPERTY_SSO_SESSION);
 +
        Map<String, Object> oauthSessionProperties = oauthSession.getProperties();
 +
        return user;
 +
    }
 +
    @Override
 +
    protected Map<String, Object> doAccessTokenRequest(HttpRequestResponse request) {
 +
        // TODO Auto-generated method stub
 +
        // If you need to change how the access token request operates
 +
        return super.doAccessTokenRequest(request);
 +
    }
 +
    @Override
 +
    protected Map<String, Object> doRefreshTokenRequest(AmiWebOAuthSsoSession ssoSession) {
 +
        // TODO Auto-generated method stub
 +
        // If you need to change how the refresh token request operates
 +
        return super.doRefreshTokenRequest(ssoSession);
 +
    }
 +
 +
 +
}
 +
</syntaxhighlight>
 +
 +
 +
==Example Configuration==
 +
 +
sso.plugin.class=com.company.3forge.AmiWebOAuthPluginSample
 +
 +
 +
<nowiki># Include the same properties you need for the Quick Start Guide</nowiki>
 +
 +
 +
<nowiki># ...</nowiki>
 +
 +
 +
<nowiki># Enabling debug for development to help with diagnosing</nowiki>
 +
 +
 +
oauth.debug=true

Latest revision as of 03:27, 13 February 2024

Introduction

OAuth is one of the multiple ways you can authenticate users to 3forge AMI. The 3forge AMI OAuth Plugin makes it easy to integrate AMI with any OAuth based identity manager. It provides a simple standard authentication mechanism and allows you to build access control into your 3forge AMI Layouts.


Go to Section 2 OAuth Quickstart to quickly get started with using the OAuthPlugin.


OAuth Quickstart

Prerequisites:

  1. Find out your identity provider and ensure it allows for OAuth 2.0 Authentication. You will need to know the identity provider url.
  2. Register a new Web App with your identity provider.
    1. Provide a Sign In Redirect Url, we recommend https://<your-server>:33332/oauthRedirectUrl
      1. This will be used in the oauth.redirect.url property
    2. Provide a Sign Out Redirect Url (Optional but recommended)


How to setup the OAuth Plugin

  1. Navigate to your 3forge AMI config directory, it's typically located in ami\amione\config
  2. Create a file called local.properties if one is not already present
  3. Add the properties from Section 2.2 Minimal Configuration to the file local.properties
  4. Update the values of the properties to match your identity provider.
  5. Restart 3forge AMI

Minimal Configuration

Note: Please refer to Section 3 OAuth Full Properties List for a detailed understanding of each property


sso.plugin.class=com.f1.ami.web.AmiWebOAuthPluginImpl


# Provide the url to your OAuth 2.0 identity provider

oauth.server.domain=https://oauthprovider.com


# Provide the redirect url that you configured for the app with your identity provider

oauth.redirect.uri=http://localhost:33332/oauthRedirectUrl


# Provide the endpoints for authorization, token and refresh token

oauth.authorization.endpoint=/authorizeEndpoint

oauth.token.endpoint=/tokenEndpoint

oauth.refresh.token.endpoint=/refreshTokenEndpoint


# Properties related to refresh tokens, redirect uri and scope are optional, by default are set to null

oauth.refresh.redirect.uri=/refreshRedirectUri

oauth.refresh.scope=/refreshScope

oauth.refresh.client.id=/refreshClientId

oauth.refresh.client.secret=/refreshClientSecret


# Provide the client id and secret that will be used for the OAuth authentication

oauth.client.id=clientid

oauth.client.secret=secret


# Replace this with the default scope that is used for Web Based Applications in your firm

oauth.scope=openid profile email offline_access


# Replace this with unique identifier that identifies the user

oauth.username.field=email


# Recommended to replace this with an attribute that identifies the group a user belongs to

oauth.ami.isdev.field=email

oauth.ami.isdev.values=<comma_delimited_list_of_emails>


# Logout Page AMI will display when logged out

web.logged.out.url=/loggedout.htm


# This is enabled for development, disable this after OAuth has been setup

oauth.debug=true


OAuth Full Properties List

Description Property and Default Value
REQUIRED
Specify class to use Oauth SSO
sso.plugin.class=com.f1.ami.web.AmiWebOAuthPluginImpl
REQUIRED
The domain of the auth server account
oauth.server.domain=https://oauthprovider.com
REQUIRED
Set AMI logged out page
web.logged.out.url=/loggedout.htm
REQUIRED
3forge AMI Url for Oauth server to redirect after login
oauth.redirect.uri=http://localhost:33332/oauthRedirectUrl/
REQUIRED
Client ID
oauth.client.id=clientid
REQUIRED
Client secret
oauth.client.secret=secret
REQUIRED
Authorization endpoint
oauth.authorization.endpoint=/authorizeEndpoint
REQUIRED
Token endpoint
oauth.token.endpoint=/tokenEndpoint
REQUIRED
Oauth scope
oauth.scope=openid profile email offline_access
REQUIRED
User Email
oauth.username.field=email
OPTIONAL
The endpoint to get the refresh token
oauth.refresh.token.endpoint=/refreshTokenEndpoint
OPTIONAL
The refresh redirect uri, by default is null, can be overriden
oauth.refresh.redirect.uri=/refreshRedirectUri
OPTIONAL
The refresh scope, by default is null,can be overriden
oauth.refresh.scope=/refreshScope
OPTIONAL
The client Id after refresh, by default is the same as oauth.client.id,can be overriden
oauth.refresh.client.id=/refreshClientId
OPTIONAL
The client Sercret after refresh, by default is the same as oauth.client.secret,can be overriden
oauth.refresh.client.secret=/refreshClientSecret
OPTIONAL
Dev User Email
oauth.ami.isdev.field=email
OPTIONAL
List of dev user emails
oauth.ami.isdev.values=<comma_delimited_list_of_emails>
OPTIONAL
Key that contains the time the access token expires in
oauth.access.token.expires.in=expires_in
OPTIONAL
Code challenge method
oauth.code.challenge.method=S256
OPTIONAL
Java hashing algorithm
oauth.digest.algo=SHA-256
OPTIONAL
Seconds to check refresh token expiration
oauth.session.check.period.seconds=60
OPTIONAL
The 3forge AMI endpoint that triggers the build auth request.
ami.web.index.html.file=index2.htm
OPTIONAL
Enables Debugging Mode
oauth.debug=true
OPTIONAL
Disables certificate validation (for ssl)
oauth.validate.certs=false


Creating your own AMI OAuth Plugin

The AMI OAuth plugin handles authorization code and access token requests that are needed for Authenticating to AMI. By extending the 3forge AMI OAuth plugin, you can create your own Ami OAuth Plugin if you have custom requirements for access control or entitlements.


There are three main components to the 3forge AMI OAuth Plugin: buildAuthRequest, processResponse, and createAmiUserSSOSession.

Main Components of the 3forge AMI OAuth Plugin

The buildAuthRequest method is responsible for creating the url for the Authorization Code request.


The processResponse method is responsible for processing the response from the Authorization Code request, then building an Access Token request. Once it obtains an access token, it needs to return an AmiAuthUser.


The createAmiUserSSOSession is responsible for creating the AmiAuthUser and OAuthSSO Session. The AmiAuthUser can be used to set user session variables or restrict access to layouts. The OAuth Session is accessible in AMIScript by session.getSsoSession().


Diagram of the 3forge AMI OAuth Plugin

OAuthDiagram.png


Example Java Code

 1package com.company.3forge;
 2
 3
 4import java.util.Map;
 5import com.f1.ami.web.auth.AmiAuthUser;
 6import com.f1.container.ContainerTools;
 7import com.f1.http.HttpRequestResponse;
 8import com.f1.http.HttpSession;
 9import com.f1.suite.web.HttpRequestAction;
10import com.f1.utils.PropertyController;
11
12
13public class AmiWebOAuthPluginSample extends AmiWebOAuthPluginImpl {
14    @Override
15    public void init(ContainerTools tools, PropertyController props) {
16        // This is where you can initialize any properties.
17        super.init(tools, props);
18        String sample = props.getRequired("oauth.sample.property");
19        String sample2 = props.getOptional("oauth.sample2.property", "defaultValue");
20    }
21    @Override
22    public String getPluginId() {
23        return "SampleOAuthPlugin";
24    }
25    @Override
26    public String buildAuthRequest(HttpRequestResponse req) throws Exception {
27        HttpSession session = req.getSession(true);
28        String requestUri = req.getRequestUri(); // This will be your ami.web.index.html.file
29        Map<String, String> header = req.getHeader();
30        Map<String, String> cookies = req.getCookies();
31        Map<String, String> params = req.getParams();
32
33
34        // This is how you can add a cookie to the response
35        String optionalDomain = null;
36        long optionalExpires = 0;
37        req.putCookie("myCookie", "secretCode", optionalDomain, optionalExpires, null);
38
39
40        // This is how you add a header to the response
41        req.putResponseHeader("myHeader", "value");
42
43
44        // This will build an Authorization Code Request
45        String redirectUrlForLogin = super.buildAuthRequest(req);
46        return redirectUrlForLogin;
47    }
48    @Override
49    public String getExpectedResponsePath() {
50        // This returns the login redirect url that is provided to your identity manager, it is used in the buildAuthRequest
51        return super.getExpectedResponsePath();
52    }
53    @Override
54    public AmiAuthUser processResponse(HttpRequestAction req) throws Exception {
55        HttpRequestResponse authorizeResponse = req.getRequest();
56
57
58        // 1| Create access token request
59        Map<String, Object> accessTokenResult = doAccessTokenRequest(authorizeResponse);
60        if (accessTokenResult == null)
61            return null;
62        AmiAuthUser user = createAmiUserSSOSession(authorizeResponse, accessTokenResult);
63
64
65        // You may add your own properties to the AmiAuthUser via the auth attributes
66        Map<String, Object> authAttributes = user.getAuthAttributes();
67
68
69        // The below is the OAuth session which can be accessed via AMIScript through session.getSsoSession() which returns a SsoSession object
70        AmiWebOAuthSsoSession oauthSession = (AmiWebOAuthSsoSession) authAttributes.get(AmiAuthUser.PROPERTY_SSO_SESSION);
71        Map<String, Object> oauthSessionProperties = oauthSession.getProperties();
72        return user;
73    }
74    @Override
75    protected Map<String, Object> doAccessTokenRequest(HttpRequestResponse request) {
76        // TODO Auto-generated method stub
77        // If you need to change how the access token request operates
78        return super.doAccessTokenRequest(request);
79    }
80    @Override
81    protected Map<String, Object> doRefreshTokenRequest(AmiWebOAuthSsoSession ssoSession) {
82        // TODO Auto-generated method stub
83        // If you need to change how the refresh token request operates
84        return super.doRefreshTokenRequest(ssoSession);
85    }
86
87
88}


Example Configuration

sso.plugin.class=com.company.3forge.AmiWebOAuthPluginSample


# Include the same properties you need for the Quick Start Guide


# ...


# Enabling debug for development to help with diagnosing


oauth.debug=true