diff options
author | 2016-06-16 14:49:55 +0200 | |
---|---|---|
committer | 2016-06-16 14:49:55 +0200 | |
commit | 506a1fc1252268fa31ba89882ea55b7665579965 (patch) | |
tree | b7f83bb4578e227e3b7a2dbe938864e27f38156f /odl-aaa-moon/aaa-authn-api/src/main/docs | |
parent | 4bc079a2664f9a407e332291f34d174625a9d5ea (diff) |
Delete old files
Change-Id: I35cf053f404ba4134eeef46ef177259340634d4f
Diffstat (limited to 'odl-aaa-moon/aaa-authn-api/src/main/docs')
22 files changed, 0 insertions, 4589 deletions
diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/Makefile b/odl-aaa-moon/aaa-authn-api/src/main/docs/Makefile deleted file mode 100644 index 446795b4..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -all: sssd_configuration.html sssd_configuration.pdf mapping.html - - -images = sssd_01.png sssd_02.png sssd_03.png sssd_04.png sssd_05.png - -sssd_configuration.html: $(images) - -sssd_configuration.pdf: $(images) - -%.html: %.rst - rst2html $< $@ - -%.pdf: %.rst - rst2pdf --footer='-###Page###-' $< -o $@ - -%.png: %.svg - inkscape -z -e $@ -w 800 $< - -sssd_01.svg: sssd_01.diag - blockdiag -Tsvg $< - -sssd_02.svg: sssd_02.diag - blockdiag -Tsvg $< - -sssd_03.svg: sssd_03.diag - seqdiag -Tsvg $< - -sssd_04.svg: sssd_04.diag - blockdiag -Tsvg $< diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/class_diagram.png b/odl-aaa-moon/aaa-authn-api/src/main/docs/class_diagram.png Binary files differdeleted file mode 100644 index 999a41f9..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/class_diagram.png +++ /dev/null diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/class_diagram.ucls b/odl-aaa-moon/aaa-authn-api/src/main/docs/class_diagram.ucls deleted file mode 100644 index 68345256..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/class_diagram.ucls +++ /dev/null @@ -1,127 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<class-diagram version="1.1.6" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true" - realizations="true" associations="true" dependencies="true" nesting-relationships="true"> - <interface id="1" language="java" name="org.opendaylight.aaa.api.TokenStore" project="aaa-authn-api" - file="/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/TokenStore.java" binary="false" corner="BOTTOM_RIGHT"> - <position height="-1" width="-1" x="637" y="568"/> - <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" accessors="true" - visibility="true"> - <attributes public="true" package="true" protected="true" private="false" static="true"/> - <operations public="true" package="true" protected="true" private="false" static="true"/> - </display> - </interface> - <interface id="2" language="java" name="org.opendaylight.aaa.api.AuthenticationService" project="aaa-authn-api" - file="/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/AuthenticationService.java" binary="false" - corner="BOTTOM_RIGHT"> - <position height="-1" width="-1" x="385" y="727"/> - <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" accessors="true" - visibility="true"> - <attributes public="true" package="true" protected="true" private="false" static="true"/> - <operations public="true" package="true" protected="true" private="false" static="true"/> - </display> - </interface> - <interface id="3" language="java" name="org.opendaylight.aaa.api.CredentialAuth" project="aaa-authn-api" - file="/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/CredentialAuth.java" binary="false" - corner="BOTTOM_RIGHT"> - <position height="-1" width="-1" x="148" y="94"/> - <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" accessors="true" - visibility="true"> - <attributes public="true" package="true" protected="true" private="false" static="true"/> - <operations public="true" package="true" protected="true" private="false" static="true"/> - </display> - </interface> - <interface id="4" language="java" name="org.opendaylight.aaa.api.TokenAuth" project="aaa-authn-api" - file="/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/TokenAuth.java" binary="false" corner="BOTTOM_RIGHT"> - <position height="-1" width="-1" x="139" y="568"/> - <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" accessors="true" - visibility="true"> - <attributes public="true" package="true" protected="true" private="false" static="true"/> - <operations public="true" package="true" protected="true" private="false" static="true"/> - </display> - </interface> - <interface id="5" language="java" name="org.opendaylight.aaa.api.PasswordCredentials" project="aaa-authn-api" - file="/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/PasswordCredentials.java" binary="false" - corner="BOTTOM_RIGHT"> - <position height="-1" width="-1" x="383" y="218"/> - <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" accessors="true" - visibility="true"> - <attributes public="true" package="true" protected="true" private="false" static="true"/> - <operations public="true" package="true" protected="true" private="false" static="true"/> - </display> - </interface> - <interface id="6" language="java" name="org.opendaylight.aaa.api.Credentials" project="aaa-authn-api" - file="/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/Credentials.java" binary="false" corner="BOTTOM_RIGHT"> - <position height="-1" width="-1" x="385" y="93"/> - <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" accessors="true" - visibility="true"> - <attributes public="true" package="true" protected="true" private="false" static="true"/> - <operations public="true" package="true" protected="true" private="false" static="true"/> - </display> - </interface> - <interface id="7" language="java" name="org.opendaylight.aaa.api.Authentication" project="aaa-authn-api" - file="/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/Authentication.java" binary="false" - corner="BOTTOM_RIGHT"> - <position height="-1" width="-1" x="386" y="567"/> - <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" accessors="true" - visibility="true"> - <attributes public="true" package="true" protected="true" private="false" static="true"/> - <operations public="true" package="true" protected="true" private="false" static="true"/> - </display> - </interface> - <interface id="8" language="java" name="org.opendaylight.aaa.api.ClaimAuth" project="aaa-authn-api" - file="/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/ClaimAuth.java" binary="false" corner="BOTTOM_RIGHT"> - <position height="-1" width="-1" x="138" y="386"/> - <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" accessors="true" - visibility="true"> - <attributes public="true" package="true" protected="true" private="false" static="true"/> - <operations public="true" package="true" protected="true" private="false" static="true"/> - </display> - </interface> - <interface id="9" language="java" name="org.opendaylight.aaa.api.Claim" project="aaa-authn-api" - file="/aaa-authn-api/src/main/java/org/opendaylight/aaa/api/Claim.java" binary="false" corner="BOTTOM_RIGHT"> - <position height="-1" width="-1" x="386" y="386"/> - <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" accessors="true" - visibility="true"> - <attributes public="true" package="true" protected="true" private="false" static="true"/> - <operations public="true" package="true" protected="true" private="false" static="true"/> - </display> - </interface> - <dependency id="10"> - <end type="SOURCE" refId="3"/> - <end type="TARGET" refId="6"/> - </dependency> - <dependency id="11"> - <end type="SOURCE" refId="2"/> - <end type="TARGET" refId="7"/> - </dependency> - <generalization id="12"> - <end type="SOURCE" refId="5"/> - <end type="TARGET" refId="6"/> - </generalization> - <dependency id="13"> - <end type="SOURCE" refId="3"/> - <end type="TARGET" refId="9"/> - </dependency> - <generalization id="14"> - <end type="SOURCE" refId="7"/> - <end type="TARGET" refId="9"/> - </generalization> - <dependency id="15"> - <end type="SOURCE" refId="1"/> - <end type="TARGET" refId="7"/> - </dependency> - <dependency id="16"> - <end type="SOURCE" refId="8"/> - <end type="TARGET" refId="9"/> - </dependency> - <dependency id="17"> - <end type="SOURCE" refId="4"/> - <end type="TARGET" refId="7"/> - </dependency> - <classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" - accessors="true" visibility="true"> - <attributes public="true" package="true" protected="true" private="false" static="true"/> - <operations public="true" package="true" protected="true" private="false" static="true"/> - </classifier-display> - <association-display labels="true" multiplicity="true"/> -</class-diagram>
\ No newline at end of file diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/credential_auth_sequence.png b/odl-aaa-moon/aaa-authn-api/src/main/docs/credential_auth_sequence.png Binary files differdeleted file mode 100644 index 52d63650..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/credential_auth_sequence.png +++ /dev/null diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/credential_auth_sequence.wsd b/odl-aaa-moon/aaa-authn-api/src/main/docs/credential_auth_sequence.wsd deleted file mode 100644 index 383d4031..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/credential_auth_sequence.wsd +++ /dev/null @@ -1,18 +0,0 @@ -title Credential Authentication Sequence - -# This walks through the credential authentication use case where a credential -# (typically username/password) is used to authenticate directly with the ODL -# controller. - -Client -> ServletContainer: request access token -note right of Client -(credentials, scope=domain) -end note -ServletContainer -> TokenEndpoint: credentials, domain -TokenEndpoint -> CredentialAuth: authenticate(Credentials, domain) -CredentialAuth -> TokenEndpoint: Claim -note left of CredentialAuth -(user/domain/roles) -end note -TokenEndpoint -> TokenEndpoint: createToken -TokenEndpoint -> Client: access token
\ No newline at end of file diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/federated_auth_sequence.png b/odl-aaa-moon/aaa-authn-api/src/main/docs/federated_auth_sequence.png Binary files differdeleted file mode 100644 index 799cc909..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/federated_auth_sequence.png +++ /dev/null diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/federated_auth_sequence.wsd b/odl-aaa-moon/aaa-authn-api/src/main/docs/federated_auth_sequence.wsd deleted file mode 100644 index 22d1d916..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/federated_auth_sequence.wsd +++ /dev/null @@ -1,24 +0,0 @@ -title Federated Authentication Sequence (w/ Claim Transformation) - -# This walks through the federated authentication sequence where a claim from a -# third-party IdP system is posted to the ODL token endpoint in exchange for an -# access token. The claim information is assumed to be in format specific to the -# third-party IdP system and assumed to be captured via either Apache environment -# variables (Servlet attributes) or HTTP headers. - -Client -> ServletContainer: request access token -note right of Client -(claim as Apache env/HTTP headers) -end note -ServletContainer -> ClaimAuthFilter: Servlet attributes/headers -loop foreach ClaimAuth - ClaimAuthFilter -> ClaimAuth: transform(Map<String, Object> claim) - ClaimAuth -> ClaimAuth: transformClaim -end -ClaimAuth -> ClaimAuthFilter: Claim -note left of ClaimAuth -(user/domain/roles) -end note -ClaimAuthFilter --> TokenEndpoint: Claim -TokenEndpoint -> TokenEndpoint: createToken -TokenEndpoint -> Client: access token
\ No newline at end of file diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/mapping.rst b/odl-aaa-moon/aaa-authn-api/src/main/docs/mapping.rst deleted file mode 100644 index 33635502..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/mapping.rst +++ /dev/null @@ -1,1609 +0,0 @@ -Operation Model -=============== - -The assertions from an IdP are stored in an associative array. A -sequence of rules are applied, the first rule which returns success is -considered a match. During the execution of each rule values from the -assertion can be tested and transformed with the results selectively -stored in variables local to the rule. If the rule succeeds an -associative array of mapped values is returned. The mapped values are -taken from the local variables set during the rule execution. The -definition of the rules and mapped results are expressed in JSON -notation. - -A rule is somewhat akin to a function in a programming language. It -starts execution with a set of predefined local variables. It executes -statements which are grouped together in blocks. Execution continues -until an `exit`_ statement returning a success/fail result is -executed or until the last statement is reached which implies -success. The remaining statements in a block may be skipped via a -`continue`_ statement which tests a condition, this is equivalent to -an "if" control flow of logic in a programming language. - -Rule execution continues until a rule returns success. Each rule has a -`mapping`_ associative array bound to it which is a template for the -transformed result. Upon success the `mapping`_ template for the -rule is loaded and the local variables from the successful rule are -used to populate the values in the `mapping`_ template yielding the -final mapped result. - -If no rules returns success authentication fails. - - -Pseudo Code Illustrating Operational Model ------------------------------------------- - -:: - - mapped = null - foreach rule in rules { - result = null - initialize rule.variables with pre-defined values - - foreach block in rule.statement_blocks { - for statement in block.statements { - if statement.verb is exit { - result = exit.status - break - } - elif statement.verb is continue { - break - } - } - if result { - break - } - if result == null { - result = success - } - if result == success { - mapped = rule.mapping(rule.variables) - } - return mapped - - - -Structure Of Rule Definitions -============================= - -Rules are loaded by the rule processor via a JSON document called a -rule definition. A definition has an *optional* set of mapping -templates and a list of rules. Each rule has specifies a mapping -template and has a list of statement blocks. Each statement block has -a list of statements. - -In pseudo-JSON (JSON does not have comments, the ... ellipsis is a -place holder): - -:: - - { - "mappings": { - "template1": "{...}", - "template2": "{...}" - }, - "rules": [ - { # Rule 0. A rule has a mapping or a mapping name - # and a list of statement blocks - - "mapping": {...}, - # -OR- - "mapping_name": "template1", - - "statement_blocks": [ - [ # Block 0 - [statement 0] - [statement 1] - ], - [ # Block 1 - [statement 0] - [statement 1] - ], - - ] - }, - { # Rule 1 ... - } - ] - - } - -Mapping -------- - -A mapping template is used to produce the final associative array of -name/value pairs. The template is a JSON Object. The value in a -name/value pair can be a constant or a variable. If the template value -is a variable the value of the variable is retrieved from the set of -local variables bound to the rule thereby replacing it in the final -result. - -For example given this mapping template and rule variables in JSON: - -template: - -:: - - { - "organization": "BigCorp.com", - "user: "$subject", - "roles": "$roles" - } - -local variables: - -:: - - { - "subject": "Sally", - "roles": ["user", "admin"] - } - -The final mapped results would be: - -:: - - { - "organization": "BigCorp.com", - "user: "Sally", - "roles": ["user", "admin"] - } - - -Each rule must bind a mapping template to the rule. The mapping -template may either be defined directly in the rule via the -``mapping`` key or referenced by name via the ``mapping_name`` key. - -If the ``mapping_name`` is specified the mapping is looked up in a -table of mapping templates bound to the Rule Processor. Using the name -of a mapping template is useful when many rules generate the exact -same template values. - -If both ``mapping`` and ``mapping_name`` are defined the locally bound -``mapping`` takes precedence. - -Syntax ------- - -The logic for a rule consists of a sequence of statements grouped in -blocks. A statement is similar to a function call in a programming -language. - -A statement is a list of values the first of which is a verb which -defines the operation the statement will perform. Think of the -`verbs`_ as function names or operators. Following the verb are -parameters which may be constants or variables. If the statement -assigns a value to a variable left hand side of the assignment (lhs) -is always the first parameter following the verb in the list of -statement values. - -For example this statement in JSON: - -:: - - ["split", "$groups", "$assertion[Groups]", ":"] - -will assign an array to the variable ``$groups``. It looks up the -string named ``Groups`` in the assertion which is a colon (:) -separated list of group names splitting that string on the colon -character. - -Statements **must** be grouped together in blocks. Therefore a rule is -a sequence of blocks and block is a sequence of statements. The -purpose of blocks is allow for crude flow of control logic. For -example this JSON rule has 4 blocks. - -:: - - [ - [ - ["set", $user, ""], - ["set", $roles, []] - ], - [ - ["in", "UserName", "$assertion"], - ["continue", "if_not_success"], - ["set", "$user", "$assertion[UserName"], - ], - [ - ["in", "subject", "$assertion"], - ["continue", "if_not_success"], - ["set", "$user", "$assertion[subject]"], - ], - [ - ["length", "$temp", "$user"], - ["compare", "$temp", ">", 0], - ["exit", "rule_fails", "if_not_success"] - ["append" "$roles", "unprivileged"] - ] - ] - -The rule will succeed if either ``UserName`` or ``subject`` is defined -in the assertion and if so the local variable ``$user`` will be set to -the value found in the assertion and the "unprivileged" role will be -appended to the roles array. - -The first block performs initialization. The second block tests to see -if the assertion has the key ``UserName`` if not execution continues -at the next block otherwise the value of UserName in the assertion is -copied into the variable ``$user``. The third block performs a similar -operation looking for a ``subject`` in the assertion. The fourth block -checks to see if the ``$user`` variable is empty, if it is empty the -rule fails because it didn't find either a ``UserName`` nor a -``subject`` in the assertion. If ``$user`` is not empty the -"unprivileged" role is appended and the rule succeeds. - -Data Types ----------- - -There are 7 supported types which equate to the types available in -JSON. At the time of this writing there are 2 implementations of this -Mapping specification, one in Python and one in Java. This table -illustrates how each data type is represented. The first two columns -are definitions from an abstract specification. The JSON column -enumerates the data type JSON supports. The Mapping column lists the -7 enumeration names used by the Mapping implemenation in each -language. The following columns list the concrete data type used in -that language. - -+-----------+------------+--------------------+---------------------+ -| JSON | Mapping | Python | Java | -+===========+============+====================+=====================+ -| object | MAP | dict | Map<String, Object> | -+-----------+------------+--------------------+---------------------+ -| array | ARRAY | list | List<Object> | -+-----------+------------+--------------------+---------------------+ -| string | STRING | unicode (Python 2) | String | -| | +--------------------+ | -| | | str (Python 3) | | -+-----------+------------+--------------------+---------------------+ -| | INTEGER | int | Long | -| number +------------+--------------------+---------------------+ -| | REAL | float | Double | -+-----------+------------+--------------------+---------------------+ -| true | | | | -+-----------+ BOOLEAN | bool | Boolean | -| false | | | | -+-----------+------------+--------------------+---------------------+ -| null | NULL | None | null | -+-----------+------------+--------------------+---------------------+ - - -Rule Debugging and Documentation --------------------------------- - -If the rule processor reports an error or if you're debugging your -rules by enabling DEBUG log tracing then you must be able to correlate -the reported statement to where it appears in your rule JSON source. A -message will always identify a statement by the rule number, block -number within that rule and the statement number within that -block. However once your rules become moderately complex it will -become increasingly difficult to identify a statement by counting -rules, blocks and statements. - -A better approach is to tag rules and blocks with a name or other -identifying string. You can set the `Reserved Variables`_ -``rule_name`` and ``block_name`` to a string of your choice. These -strings will be reported in all messages along with the rule, block -and statement numbers. - -JSON does not permit comments, as such you cannot include explanatory -comments next to your rules, blocks and statements in the JSON -source. The ``rule_name`` and ``block_name`` can serve a similar -purpose. By putting assignments to these variables as the first -statement in a block you'll both document your rules and be able to -identify specific statements in log messages. - -During rule execution the ``rule_name`` and ``block_name`` are -initialized to the empty string at the beginning of each rule and -block respectively. - -The above example is augmented to include this information. The rule -name is set in the first statement in the first block. - -:: - - [ - [ - ["set", "$rule_name", "Must have UserName or subject"], - ["set", "block_name", "Initialization"], - ["set", $user, ""], - ["set", $roles, []] - ], - [ - ["set", "block_name", "Test for UserName, set $user"], - ["in", "UserName", "$assertion"], - ["continue", "if_not_success"], - ["set", "$user", "$assertion[UserName"], - ], - [ - ["set", "block_name", "Test for subject, set $user"], - ["in", "subject", "$assertion"], - ["continue", "if_not_success"], - ["set", "$user", "$assertion[subject]"], - ], - [ - ["set", "block_name", "If not $user fail, else append unprivileged to roles"], - ["length", "$temp", "$user"], - ["compare", "$temp", ">", 0], - ["exit", "rule_fails", "if_not_success"] - ["append" "$roles", "unprivileged"] - ] - ] - - - - -Variables ---------- - - -Variables always begin with a dollar sign ($) and are followed by an -identifier which is any alpha character followed by zero or more -alphanumeric or underscore characters. The variable may optionally be -delimited with braces ({}) to separate the variable from surrounding -text. Three types of variables are supported: - -* scalar -* array (indexed by zero based integer) -* associative array (indexed by string) - -Both arrays and associative arrays use square brackets ([]) to specify -a member of the array. Examples of variable usage: - -:: - - $name - ${name} - $groups[0] - ${groups[0]} - $properties[key] - ${properties[key]} - -An array or an associative array may be referenced by it's base name -(omitting the indexing brackets). For example the associative array -array named "properties" is referenced using it's base name -``$properties`` but if you want to access a member of the "properties" -associative array named "duration" you would do this ``$properties[duration]`` - -This is not a general purpose language with full expression -syntax. Only one level of variable lookup is supported. Therefore -compound references like this - -:: - - $properties[$groups[2]] - -will not work. - - -Escaping -^^^^^^^^ - -If you need to include a dollar sign in a string (where it is -immediately followed by either an identifier or a brace and identifier) -and do not want to have it be interpreted as representing a variable -you must escape the dollar sign with a backslash, for example -"$amount" is interpreted as the variable ``amount`` but "\\$amount" -is interpreted as the string "$amount" . - - -Reserved Variables ------------------- - -A rule has the following reserved variables: - -assertion - The current assertion values from the federated IdP. It is a - dictionary of key/value pairs. - -regexp_array - The regular expression groups from the last successful regexp match - indexed by number. Group 0 is the entire match. Groups 1..n are - the corresponding parenthesized group counting from the left. For - example regexp_array[1] is the first group. - -regexp_map - The regular expression groups from the last successful regexp match - indexed by group name. - -rule_number - The zero based index of the currently executing rule. - -rule_name - The name of the currently executing rule. If the rule name has not - been set it will be the empty string. - -block_number - The zero based index of the currently executing block within the - currently executing rule. - -block_name - The name of the currently executing block. If the block name has not - been set it will be the empty string. - - -statement_number - The zero based index of the currently executing statement within the - currently executing block. - - -Examples -======== - -Split a fully qualified username into user and realm components ---------------------------------------------------------------- - -It's common for some IdP's to return a fully qualified username -(e.g. principal or subject). The fully qualified username is the -concatenation of the user name, separator and realm name. A common -separator is the @ character. In this example lets say the fully -qualified username is ``bob@example.com`` and you want to return the -user and realm as independent values in your mapped result. The -username appears in the assertion as the value ``Principal``. - -Our strategy will be to use a regular expression identify the user and -realm components and then assign them to local variables which will -then populate the mapped result. - -The mapping in JSON is: - -:: - - { - "user": "$username", - "realm": "$domain" - } - -The assertion in JSON is: - -:: - - { - "Principal": "bob@example.com" - } - -Our rule is: - -:: - - [ - [ - ["in", "Principal", "assertion"], - ["exit", "rule_fails", "if_not_success"], - ["regexp", "$assertion[Principal]", (?P<username>\\w+)@(?P<domain>.+)"], - ["set", "$username", "$regexp_map[username]"], - ["set", "$domain", "$regexp_map[domain]"], - ["exit, "rule_succeeds", "always"] - ] - ] - -Rule explanation: - -Block 0: - -0. Test if the assertion contains a Principal value. -1. Abort the rule if the assertion does not contain a Principal - value. -2. Apply a regular expression the the Principal value. Use named - groupings for the username and domain components for clarity. -3. Assign the regexp group username to the $username local variable. -4. Assign the regexp group domain to the $domain local variable. -5. Exit the rule, apply the mapping, return the mapped values. Note, an - explicit `exit`_ is not required if there are no further statements - in the rule, as is the case here. - -The mapped result in JSON is: - -:: - - { - "user": "bob", - "realm": "example.com" - } - -Build a set of roles based on group membership ----------------------------------------------- - -Often one wants to grant roles to a user based on their membership in -certain groups. In this example let's say the assertion contains a -``Groups`` value which is a colon separated list of group names. Our -strategy is to split the ``Groups`` assertion value into an array of -group names. Then we'll test if a specific group is in the groups -array, if it is we'll add a role. Finally if no roles have been mapped -we fail. Users in the group "student" will get the role "unprivileged" -and users in the group "helpdesk" will get the role "admin". - -The mapping in JSON is: - -:: - - { - "roles": "$roles", - } - -The assertion in JSON is: - -:: - - { - "Groups": "student:helpdesk" - } - -Our rule is: - -:: - - [ - [ - ["in", "Groups", "assertion"], - ["exit", "rule_fails", "if_not_success"], - ["set", "$roles", []], - ["split", "$groups", "$assertion[Groups]", ":"], - ], - [ - ["in", "student", "$groups"], - ["continue", "if_not_success"], - ["append", "$roles", "unprivileged"] - ], - [ - ["in", "helpdesk", "$groups"], - ["continue", "if_not_success"], - ["append", "$roles", "admin"] - ], - [ - ["unique", "$roles", "$roles"], - ["length", "$temp", "roles"], - ["compare", $temp", ">", 0], - ["exit", "rule_fails", "if_not_success"] - ] - - ] - -Rule explanation: - -Block 0 - -0. Test if the assertion contains a Groups value. -1. Abort the rule if the assertion does not contain a Groups - value. -2. Initialize the $roles variable to an empty array. -3. Split the colon separated list of group names into an array of - individual group names - -Block 1 - -0. Test if "student" is in the $groups array -1. Exit the block if it's not. -2. Append "unprivileged" to the $roles array - -Block 2 - -0. Test if "helpdesk" is in the $groups array -1. Exit the block if it's not. -2. Append "admin" to the $roles array - -Block 3 - -0. Strip any duplicate roles that might have been appended to the - $roles array to assure each role is unique. -1. Count how many members are in the $roles array, assign the - length to the $temp variable. -2. Test to see if the $roles array had any members. -3. Fail if no roles had been assigned. - -The mapped result in JSON is: - -:: - - { - "roles": ["unprivileged", "admin"] - } - -However, suppose whatever is receiving your mapped results is not -expecting an array of roles. Instead it expects a comma separated list -in a string. To accomplish this add the following statement as the -last one in the final block: - -:: - - ["join", "$roles", "$roles", ","] - -Then the mapped result will be: - -:: - - { - "roles": "unprivileged,admin"] - } - - - - -White list certain users and grant them specific roles ------------------------------------------------------- - -Suppose you have certain users you always want to unconditionally -accept and authorize with specific roles. For example if the user is -"head_of_IT" then assign her the "user" and "admin" roles. Otherwise -keep processing. The list of white listed users is hard-coded into the -rule. - -The mapping in JSON is: - -:: - - { - "user": $user, - "roles": "$roles", - } - -The assertion in JSON is: - -:: - - { - "UserName": "head_of_IT" - } - -Our rule in JSON is: - -:: - - [ - [ - ["in", "UserName", "assertion"], - ["exit", "rule_fails", "if_not_success"], - ["in", "$assertion[UserName]", ["head_of_IT", "head_of_Engineering"]], - ["continue", "if_not_success"], - ["set", "$user", "$assertion[UserName"] - ["set", "$roles", ["user", "admin"]], - ["exit", "rule_succeeds", "always"] - ], - [ - ... - ] - ] - -Rule explanation: - -Block 0 - -0. Test if the assertion contains a UserName value. -1. Abort the rule if the assertion does not contain a UserName - value. -2. Test if the user is in the hardcoded list of white listed users. -3. If the user isn't in the white listed array then exit the block and - continue execution at the next block. -4. Set the $user local variable to $assertion[UserName] -5. Set the $roles local variable to the hardcoded array containing - "user" and "admin" -6. We're done, unconditionally exit and return the mapped result. - -Block 1 - -0. Further processing - -The mapped result in JSON is: - -:: - - { - "user": "head_of_IT", - "roles": ["users", "admin"] - } - - -Black list certain users ------------------------- - -Suppose you have certain users you always want to unconditionally -deny access to by placing them in a black list. In this example the -user "BlackHat" will try to gain access. The black list includes the -users "BlackHat" and "Spook". - -The mapping in JSON is: - -:: - - { - "user": $user, - "roles": "$roles", - } - -The assertion in JSON is: - -:: - - { - "UserName": "BlackHat" - } - -Our rule in JSON is: - -:: - - [ - [ - ["in", "UserName", "assertion"], - ["exit", "rule_fails", "if_not_success"], - ["in", "$assertion[UserName]", ["BlackHat", "Spook"]], - ["exit", "rule_fails", "if_success"] - ], - [ - ... - ] - ] - -Rule explanation: - -Block 0 - -0. Test if the assertion contains a UserName value. -1. Abort the rule if the assertion does not contain a UserName - value. -2. Test if the user is in the hard-coded list of black listed users. -3. If the test succeeds then immediately abort and return failure. - -Block 1 - -0. Further processing - -The mapped result in JSON is: - -:: - - Null - -Format Strings and/or Concatenate Strings ------------------------------------------ - -You can replace variables in a format string using the `interpolate`_ -verb. String concatenation is trivially placing two variables adjacent -to one another in a format string. Suppose you want to form an email -address from the username and domain in an assertion. - -The mapping in JSON is: - -:: - - { - "email": $email, - } - -The assertion in JSON is: - -:: - - { - "UserName": "Bob", - "Domain": "example.com" - } - -Our rule in JSON is: - -:: - - [ - [ - ["interpolate", "$email", "$assertion[UserName]@$assertion[Domain]"], - ] - ] - -Rule explanation: - -Block 0 - -0. Replace the variable $assertion[UserName] with it's value and - replace the variable $assertion[Domain] with it's value. - -The mapped result in JSON is: - -:: - - { - "email": "Bob@example.com", - } - - -Note, sometimes it's necessary to utilize braces to separate variables -from surrounding text by using the brace notation. This can also make -the format string more readable. Using braces to delimit variables the -above would be: - -:: - - [ - [ - ["interpolate", "$email", "${assertion[UserName]}@${assertion[Domain]}"], - ] - ] - - - -Make associative array lookups case insensitive ------------------------------------------------ - -Many systems treat field names as case insensitive. By default -associative array indexing is case sensitive. The solution is to lower -case all the keys in an associative array and then only use lower case -indices. Suppose you want the assertion associative array to be case -insensitive. - -The mapping in JSON is: - -:: - - { - "user": $user, - } - -The assertion in JSON is: - -:: - - { - "UserName": "Bob" - } - -Our rule in JSON is: - -:: - - [ - [ - ["lower", "$assertion", "$assertion"], - ["in", "username", "assertion"], - ["exit", "rule_fails", "if_not_success"], - ["set", "$user", "$assertion[username"] - ] - ] - -Rule explanation: - -Block 0 - -0. Lower case all the keys in the assertion associative array. -1. Test if the assertion contains a username value. -2. Abort the rule if the assertion does not contain a username - value. -3. Assign the username value in the assertion to $user - -The mapped result in JSON is: - -:: - - { - "user": "Bob", - } - - -Verbs -===== - -The following verbs are supported: - -* `set`_ -* `length`_ -* `interpolate`_ -* `append`_ -* `unique`_ -* `regexp`_ -* `regexp_replace`_ -* `split`_ -* `join`_ -* `lower`_ -* `upper`_ -* `compare`_ -* `in`_ -* `not_in`_ -* `exit`_ -* `continue`_ - -Some verbs have a side effects. A verb may set a boolean success/fail -result which may then be tested with a subsequent verb. For example -the ``fail`` verb can be used to indicate the rule fails if a prior -result is either ``success`` or ``not_success``. The ``regexp`` verb -which performs a regular expression search on a string stores the -regular expression sub-matches as a side effect in the variables -``$regexp_array`` and ``$regexp_map``. - - -Verb Definitions -================ - -set ---- - -``set $variable value`` - -$variable - The variable being assigned (i.e. lhs) - -value - The value to assign to the variable (i.e. rhs). The value may be - another variable or a constant. - -**set** assigns a value to a variable, in other words it's an -assignment statement. - -Examples: -^^^^^^^^^ - -Initialize a variable to an empty array. - -:: - - ["set", "$groups", []] - -Initialize a variable to an empty associative array. - -:: - - ["set", "$groups", {}] - -Assign a string. - -:: - - ["set", "$version", "1.2.3"] - -Copy the ``UserName`` value from the assertion to a temporary variable. - -:: - - ["set", "$temp", "$assertion[UserName]"], - - -Get the 2nd item in an array (array indexing is zero based) - -:: - - ["set", "$group", "$groups[1]"] - - -Set the associative array entry "IdP" to "kdc.example.com". - -:: - - ["set", "$metadata[IdP]", "kdc.example.com""] - --------------------------------------------------------------------------------- - -length ------- - -``length $variable value`` - -$variable - The variable which receives the length value - -value - The value whose length is to be determined. May be one of array, - associative array, or string. - -**length** computes the number of items in the value. How this is done -depends upon the type of value: - -array - The length is the number of items in the array. - -associative array - The length is the number of key/value pairs in the associative - array. - -string - The length is the number of *characters* (not octets) in the - string. - -Examples: -^^^^^^^^^ - -Count how many items are in the ``$groups`` array and assign that -value to the ``$groups_length`` variable. - -:: - - ["length", "$groups_length", "$groups"] - -Count how many key/value pairs are in the ``$assertion`` associative -array and assign that value to the ``$num_assertion_values`` variable. - -:: - - ["length", "$num_assertion_values", "$assertion"] - -Count how many characters are in the assertion's UserName and assign -the value to ``$username_length``. - -:: - - ["length", "$user_name_length", "$assertion[UserName]"] - - --------------------------------------------------------------------------------- - -interpolate ------------ - -``interpolate $variable string`` - -$variable - This variable is assigned the result of the interpolation. - -string - A string containing references to variables which will be replaced - in the string. - -**interpolate** replaces each occurrence of a variable in a string with -it's value. The result is assigned to $variable. - -Examples: -^^^^^^^^^ - -Form an email address given the username and domain. If the username -is "jane" and the domain is "example.com" then $email will be -"jane@example.com" - -:: - - ["interpolate", "$email", "${username}@${domain}"] - - --------------------------------------------------------------------------------- - - -append ------- - -``append $variable value`` - -$variable - This variable **must** be an array. It is modified in place by - appending ``value`` to the end of the array. - -value - The value to append to the end of the array. - -**append** adds a value to end of an array. - -Examples: -^^^^^^^^^ - -Append the role "qa_test" to the roles list. - -:: - - ["append", "$roles", "qa_test"] - - --------------------------------------------------------------------------------- - - -unique ------- - -``unique $variable value`` - -$variable - This variable is assigned the unique values in the ``value`` - array. - -value - An array of values. **must** be an array. - -**unique** builds an array of unique values in ``value`` by stripping -out duplicates and assigns the array of unique values to -``$variable``. The order of items in the ``value`` array are -preserved. - -Examples: -^^^^^^^^^ - -$one_of_a_kind will be assigned ["a", "b"] - -:: - - ["unique", "$one_of_a_kind", ["a", "b", "a"]] - - --------------------------------------------------------------------------------- - -regexp ------- - -``regexp string pattern`` - -string - The string the regular expression pattern is applied to. - -pattern - The regular expression pattern. - -**regexp** performs a regular expression match against ``string``. The -regular expression pattern syntax is defined by the regular expression -implementation of the language this API is written in. - -Pattern groups are a convenient way to select sub-matches. Pattern -groups may accessed by either group number or group name. After a -successful regular expression match the groups are stored in the -special variables ``$regexp_array`` and -``$regexp_map``. - -``$regexp_array`` is used to access the groups by -numerical index. Groups are numbered by counting the left parenthesis -group delimiter starting at 1. Group 0 is the entire -match. ``$regexp_array`` is valid irregardless of whether you used -named groups or not. - -``$regexp_map`` is used to access the groups by -name. ``$regexp_map`` is only valid if you used named groups in the -pattern. - -Examples: -^^^^^^^^^ - -Many user names are of the form "user@domain", to split the username -from the domain and to be able to work with those values independently -use a regular expression and then assign the results to a variable. In -this example there are two regular expression groups, the first group -is the username and the second group is the domain. In the first -example we use named groups and then access the match information in -the special variable ``$regexp_map`` via the name of the group. - -:: - - ["regexp", "$assertion[UserName]", "(?P<username>\\w+)@(?P<domain>.+)"], - ["continue", "if_not_success"], - ["set", "$username", "$regexp_map[username]"], - ["set", "$domain", "$regexp_map[domain]"], - - -This is exactly equivalent but uses numbered groups instead of named -groups. In this instance the group matches are stored in the special -variable ``$regexp_array`` and accessed by numerical index. - -:: - - ["regexp", "$assertion[UserName]", "(\\w+)@(.+)"], - ["continue", "if_not_success"], - ["set", "$username", "$regexp_array[1]"], - ["set", "$domain", "$regexp_array[2]"], - - - --------------------------------------------------------------------------------- - -regexp_replace --------------- - -``regexp_replace $variable string pattern replacement`` - -$variable - The variable which receives result of the replacement. - -string - The string to perform the replacement on. - -pattern - The regular expression pattern. - -replacement - The replacement specification. - -**regexp_replace** replaces each occurrence of ``pattern`` in -``$string`` with ``replacement``. See `regexp`_ for details of using -regular expressions. - -Examples: -^^^^^^^^^ - -Convert hyphens in a name to underscores. - -:: - - ["regexp_replace", "$name", "$name", "-", "_"] - - --------------------------------------------------------------------------------- - -split ------ - -``split $variable string pattern`` - -$variable - This variable is assigned an array containing the split items. - -string - The string to split into separate items. - -pattern - The regular expression pattern used to split the string. - -**split** splits ``string`` into separate pieces and assigns the -result to ``$variable`` as an array of pieces. The split occurs -wherever the regular expression ``pattern`` occurs in ``string``. See -`regexp`_ for details of using regular expressions. - -Examples: -^^^^^^^^^ - -Split a list of groups separated by a colon (:) into an array of -individual group names. If $assertion[Groups] contained the string -"user:admin" then $group_list will set to ["user", "admin"]. - -:: - - ["split", "$group_list", "$assertion[Groups]", ":"] - - - --------------------------------------------------------------------------------- - -join ----- - -``join $variable array join_string`` - -$variable - This variable is assigned the string result of the join operation. - -array - An array of string items to be joined together with - ``$join_string``. - -join_string - The string inserted between each element in ``array``. - -**join** accepts an array of strings and produces a single string -where each element in the array is separated by ``join_string``. - -Examples: -^^^^^^^^^ - -Convert a list of group names into a single string where each group -name is separated by a colon (:). If the array ``$group_list`` is -["user", "admin"] and the ``join_string`` is ":" then the -``$group_string`` variable will be set to "user:admin". - -:: - - ["join", "$group_string", "$groups", ":"] - - --------------------------------------------------------------------------------- - -lower ------ - -``lower $variable value`` - -$variable - This variable is assigned the result of the lower operation. - -value - The value to lower case, may be either a string, array, or - associative array. - -**lower** lower cases the input value. The input value may be one of -the following types: - -string - The string is lower cased. - -array - Each member of the array must be a string, the result is an array - with the items replaced by their lower case value. - -associative array - Each key in the associative array is lower cased. The values - associated with the key are **not** modified. - -Examples: -^^^^^^^^^ - -Lookup ``UserName`` in the assertion and set the variable -``$username`` to it's lower case value. - -:: - - ["lower", "$username", "$assertion[UserName]"], - -Set each member of the ``$groups`` array to it's lower case value. If -``$groups`` was ["User", "Admin"] then ``$groups`` will become -["user", "admin"]. - -:: - - ["lower", "$groups", "$groups"], - -To enable case insensitive lookup's in an associative array lower case -each key in the associative array. If ``$assertion`` was {"UserName": -"JoeUser"} then ``$assertion`` will become {"username": "JoeUser"} - -:: - - ["lower", "$assertion", $assertion"] - --------------------------------------------------------------------------------- - -upper ------ - -``upper $variable value`` - -$variable - This variable is assigned the result of the upper operation. - -value - The value to upper case, may be either a string, array, or - associative array. - -**upper** is exactly analogous to `lower`_ except the values are upper -cased, see `lower`_ for details. - - --------------------------------------------------------------------------------- - -in --- - -``in member collection`` - -member - The value whose membership is being tested. - -collection - A collection of members. May be string, array or associative array. - -**in** tests to see if ``member`` is a member of ``collection``. The -membership test depends on the type of collection, the following are -supported: - -array - If any item in the array is equal to ``member`` then the result is - success. - -associative array - If the associative array contains a key equal to ``member`` then - the result is success. - -string - If the string contains a sub-string equal to ``member`` then the - result is success. - -Examples: -^^^^^^^^^ - -Test to see if the assertion contains a UserName value. - -:: - - ["in", "UserName", "$assertion"] - ["continue", "if_not_success"] - -Test to see if a group is one of "user" or "admin". - -:: - - ["in", "$group", ["user", "admin"]] - ["continue", "if_not_success"] - -Test to see if the sub-string "BigCorp" is in -the assertion's ``Provider`` value. - -:: - - ["in", "BigCorp", "$assertion[Provider]"] - ["continue", "if_not_success"] - - --------------------------------------------------------------------------------- - -not_in ------- - -``in member collection`` - -member - The value whose membership is being tested. - -collection - A collection of members. May be string, array or associative array. - -**not_in** is exactly analogous to `in`_ except the sense of the test -is reversed. See `in`_ for details. - --------------------------------------------------------------------------------- - -compare -------- - -``compare left operator right`` - -left - The left hand value of the binary operator. - -operator - The binary operator used for comparing left to right. - -right - The right hand value of the binary operator. - - -**compare** compares the left value to the right value according the -operator and sets success if the comparison evaluates to True. The -following relational operators are supported. - -+----------+-----------------------+ -| Operator | Description | -+==========+=======================+ -| == | equal | -+----------+-----------------------+ -| != | not equal | -+----------+-----------------------+ -| < | less than | -+----------+-----------------------+ -| <= | less than or equal | -+----------+-----------------------+ -| > | greater than | -+----------+-----------------------+ -| >= | greater than or equal | -+----------+-----------------------+ - - -The left and right hand sides of the comparison operator *must* be -the same type, no type conversions are performed. Not all combinations -of operator and type are supported. The table below illustrates the -supported combinations. Essentially you can test for equality or -inequality on any type. But only strings and numbers support the -magnitude relational operators. - - -+----------+--------+---------+------+---------+-----+------+------+ -| Operator | STRING | INTEGER | REAL | BOOLEAN | MAP | LIST | NULL | -+==========+========+=========+======+=========+=====+======+======+ -| == | X | X | X | X | X | X | X | -+----------+--------+---------+------+---------+-----+------+------+ -| != | X | X | X | X | X | X | X | -+----------+--------+---------+------+---------+-----+------+------+ -| < | X | X | X | | | | | -+----------+--------+---------+------+---------+-----+------+------+ -| <= | X | X | X | | | | | -+----------+--------+---------+------+---------+-----+------+------+ -| > | X | X | X | | | | | -+----------+--------+---------+------+---------+-----+------+------+ -| >= | X | X | X | | | | | -+----------+--------+---------+------+---------+-----+------+------+ - - -Examples: -^^^^^^^^^ - -Test to see if the ``$groups`` array has at least 2 members - -:: - - ["length", "$group_length", "$groups"], - ["compare", "$group_length", ">=", 2] - - --------------------------------------------------------------------------------- - -exit ----- - -``exit status criteria`` - -status - The result for the rule. - -criteria - The criteria upon which will cause the rule will be immediately - exited with a failed status. - -**exit** causes the rule being executed to immediately exit and a rule -result if the specified criteria is met. Statement verbs such as `in`_ -or `compare`_ set the result status which may be tested with the -``success`` and ``not_success`` criteria. - -The exit ``status`` may be one of: - -rule_fails - The rule has failed and no mapping will occur. - -rule_succeeds - The rule succeeded and the mapping will be applied. - -The ``criteria`` may be one of: - -if_success - If current result status is success then exit with ``status``. - -if_not_success - If current result status is not success then exit with ``status``. - -always - Unconditionally exit with ``status``. - -never - Effectively a no-op. Useful for debugging. - -Examples: -^^^^^^^^^ - -The rule requires ``UserName`` to be in the assertion. - -:: - - ["in", "UserName", "$assertion"] - ["exit", "rule_fails", "if_not_success"] - --------------------------------------------------------------------------------- - - -continue --------- - -``continue criteria`` - -criteria - The criteria which causes the remainder of the *block* to be - skipped. - -**continue** is used to control execution for statement blocks. It -mirrors in a crude way the `if` expression in a procedural -language. ``continue`` does *not* affect the success or failure of a -rule, rather it controls whether subsequent statements in a block are -executed or not. Control continues at the next statement block. - -Statement verbs such as `in`_ or `compare`_ set the result status -which may be tested with the ``success`` and ``not_success`` criteria. - -The criteria may be one of: - -if_success - If current result status is success then exit the statement - block and continue execution at the next statement block. - -if_not_success - If current result status is not success then exit the statement - block and continue execution at the next statement block. - -always - Immediately exit the statement block and continue execution at the - next statement block. - -never - Effectively a no-op. Useful for debugging. Execution continues at - the next statement. - -Examples: -^^^^^^^^^ - -The following pseudo code: - -:: - - roles = []; - if ("Groups" in assertion) { - groups = assertion["Groups"].split(":"); - if ("qa_test" in groups) { - roles.append("tester"); - } - } - -could be implemented this way: - -:: - - [ - ["set", "$roles", []], - ["in", "Groups", "$assertion"], - ["continue", "if_not_success"], - ["split" "$groups", $assertion[Groups]", ":"], - ["in", "qa_test", "$groups"], - ["continue", "if_not_success"], - ["append", "$roles", "tester"] - ] diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/resource_access_sequence.png b/odl-aaa-moon/aaa-authn-api/src/main/docs/resource_access_sequence.png Binary files differdeleted file mode 100644 index 728b86ce..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/resource_access_sequence.png +++ /dev/null diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/resource_access_sequence.wsd b/odl-aaa-moon/aaa-authn-api/src/main/docs/resource_access_sequence.wsd deleted file mode 100644 index 3a1c1474..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/resource_access_sequence.wsd +++ /dev/null @@ -1,25 +0,0 @@ -title Resource Access Sequence with Access Token - - This walks through a listing request of a secured resource (MD-SAL topology) - from a client to the ODL controller using an access token (either one generated - by the ODL token endpoint, or a token from a third-party IdP) and shows how the - authentication context get set upon successful token validation. If token - validation fails, the TokenAuthFilter will return a 401, and the REST layer - will be oblivious to the failed request. - -Client -> ServletContainer: list topologies -note right of Client -(Authorization = access token) -end note -ServletContainer -> TokenAuthFilter: access token -loop foreach TokenAuth - TokenAuthFilter -> TokenAuth: validate(token) - TokenAuth -> TokenAuth: validateToken -end -TokenAuth -> TokenAuthFilter: Authentication -note left of TokenAuth -(user/domain/roles/expiration) -end note -TokenAuthFilter -> AuthenticationService: set(Authentication) -TokenAuthFilter -> RestConf: list topologies -RestConf -> AuthenticationService: get: Authentication
\ No newline at end of file diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_01.diag b/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_01.diag deleted file mode 100644 index 28317393..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_01.diag +++ /dev/null @@ -1,6 +0,0 @@ -blockdiag { - User <-> AAA; - User [numbered = 1, shape = actor] - AAA [numbered = 2, label = "App Server\nAAA"] -} - diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_01.svg b/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_01.svg deleted file mode 100644 index 4056b10a..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_01.svg +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> -<svg viewBox="0 0 448 120" xmlns="http://www.w3.org/2000/svg" xmlns:inkspace="http://www.inkscape.org/namespaces/inkscape" xmlns:xlink="http://www.w3.org/1999/xlink"> - <defs id="defs_block"> - <filter height="1.504" id="filter_blur" inkspace:collect="always" width="1.1575" x="-0.07875" y="-0.252"> - <feGaussianBlur id="feGaussianBlur3780" inkspace:collect="always" stdDeviation="4.2" /> - </filter> - </defs> - <title>blockdiag</title> - <desc>blockdiag { - User <-> AAA; - User [numbered = 1, shape = actor] - AAA [numbered = 2, label = "App Server\nAAA"] -} - -</desc> - <polygon fill="rgb(0,0,0)" points="134,56 134,61 151,61 151,66 134,66 134,71 148,86 141,86 131,76 121,86 114,86 128,71 128,66 111,66 111,61 128,61 128,56" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" /> - <ellipse cx="131" cy="51" fill="rgb(0,0,0)" rx="7" ry="7" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" /> - <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="259" y="46" /> - <polygon fill="rgb(255,255,255)" points="131,50 131,55 148,55 148,60 131,60 131,65 145,80 138,80 128,70 118,80 111,80 125,65 125,60 108,60 108,55 125,55 125,50" stroke="rgb(0,0,0)" /> - <ellipse cx="128" cy="45" fill="rgb(255,255,255)" rx="7" ry="7" stroke="rgb(0,0,0)" /> - <ellipse cx="64" cy="40" fill="pink" rx="12" ry="12" stroke="rgb(0,0,0)" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="61" y="44">1</text> - <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="256" y="40" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="293" y="60">App Server</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="310" y="70">AAA</text> - <ellipse cx="256" cy="40" fill="pink" rx="12" ry="12" stroke="rgb(0,0,0)" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="253" y="44">2</text> - <path d="M 156 60 L 248 60" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="149,60 156,56 156,64 149,60" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="255,60 248,56 248,64 255,60" stroke="rgb(0,0,0)" /> -</svg> diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_02.diag b/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_02.diag deleted file mode 100644 index 2076dd16..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_02.diag +++ /dev/null @@ -1,18 +0,0 @@ -blockdiag { - span_width = 30 - User <-> Apache; - Proxy <-> AAA; - group { - Apache <-> Proxy; - group { - orientation = portrait - Apache <-> SSSD; - } - } - User [numbered = 1, shape = actor, width = 60] - Apache [numbered = 2, label = "Apache\nAuthenticates user"] - SSSD [numbered = 3, label = "SSSD\nProvides user info"] - Proxy [numbered = 4, label = "Proxy Transport\nRequest + Metadata"] - AAA [numbered = 5, label = "App Server\nAAA"] -} - diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_02.svg b/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_02.svg deleted file mode 100644 index 42196b60..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_02.svg +++ /dev/null @@ -1,79 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> -<svg viewBox="0 0 594 200" xmlns="http://www.w3.org/2000/svg" xmlns:inkspace="http://www.inkscape.org/namespaces/inkscape" xmlns:xlink="http://www.w3.org/1999/xlink"> - <defs id="defs_block"> - <filter height="1.504" id="filter_blur" inkspace:collect="always" width="1.1575" x="-0.07875" y="-0.252"> - <feGaussianBlur id="feGaussianBlur3780" inkspace:collect="always" stdDeviation="4.2" /> - </filter> - </defs> - <title>blockdiag</title> - <desc>blockdiag { - span_width = 30 - User <-> Apache; - Proxy <-> AAA; - group { - Apache <-> Proxy; - group { - orientation = portrait - Apache <-> SSSD; - } - } - User [numbered = 1, shape = actor, width = 60] - Apache [numbered = 2, label = "Apache\nAuthenticates user"] - SSSD [numbered = 3, label = "SSSD\nProvides user info"] - Proxy [numbered = 4, label = "Proxy Transport\nRequest + Metadata"] - AAA [numbered = 5, label = "App Server\nAAA"] -} - -</desc> - <rect fill="rgb(243,152,0)" height="140" style="filter:url(#filter_blur)" width="292" x="117" y="30" /> - <rect fill="rgb(243,152,0)" height="140" style="filter:url(#filter_blur)" width="134" x="117" y="30" /> - <polygon fill="rgb(0,0,0)" points="66,56 66,61 83,61 83,66 66,66 66,71 80,86 73,86 63,76 53,86 46,86 60,71 60,66 43,66 43,61 60,61 60,56" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" /> - <ellipse cx="63" cy="51" fill="rgb(0,0,0)" rx="7" ry="7" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" /> - <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="123" y="46" /> - <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="123" y="126" /> - <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="281" y="46" /> - <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="439" y="46" /> - <polygon fill="rgb(255,255,255)" points="63,50 63,55 80,55 80,60 63,60 63,65 77,80 70,80 60,70 50,80 43,80 57,65 57,60 40,60 40,55 57,55 57,50" stroke="rgb(0,0,0)" /> - <ellipse cx="60" cy="45" fill="rgb(255,255,255)" rx="7" ry="7" stroke="rgb(0,0,0)" /> - <ellipse cx="30" cy="40" fill="pink" rx="12" ry="12" stroke="rgb(0,0,0)" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="27" y="44">1</text> - <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="120" y="40" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="166" y="60">Apache</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="133" y="70">Authenticates user</text> - <ellipse cx="120" cy="40" fill="pink" rx="12" ry="12" stroke="rgb(0,0,0)" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="117" y="44">2</text> - <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="120" y="120" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="170" y="139">SSSD</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="138" y="149">Provides user info</text> - <ellipse cx="120" cy="120" fill="pink" rx="12" ry="12" stroke="rgb(0,0,0)" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="117" y="124">3</text> - <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="278" y="40" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="300" y="59">Proxy Transport</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="289" y="71">Request + Metadata</text> - <ellipse cx="278" cy="40" fill="pink" rx="12" ry="12" stroke="rgb(0,0,0)" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="275" y="44">4</text> - <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="436" y="40" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="473" y="60">App Server</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="490" y="70">AAA</text> - <ellipse cx="436" cy="40" fill="pink" rx="12" ry="12" stroke="rgb(0,0,0)" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="433" y="44">5</text> - <path d="M 88 60 L 112 60" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="81,60 88,56 88,64 81,60" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="119,60 112,56 112,64 119,60" stroke="rgb(0,0,0)" /> - <path d="M 414 60 L 428 60" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="407,60 414,56 414,64 407,60" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="435,60 428,56 428,64 435,60" stroke="rgb(0,0,0)" /> - <path d="M 184 88 L 184 112" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="184,81 180,88 188,88 184,81" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="184,119 180,112 188,112 184,119" stroke="rgb(0,0,0)" /> - <path d="M 256 60 L 270 60" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="249,60 256,56 256,64 249,60" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="277,60 270,56 270,64 277,60" stroke="rgb(0,0,0)" /> - <path d="M 184 88 L 184 112" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="184,81 180,88 188,88 184,81" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="184,119 180,112 188,112 184,119" stroke="rgb(0,0,0)" /> - <path d="M 256 60 L 270 60" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="249,60 256,56 256,64 249,60" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="277,60 270,56 270,64 277,60" stroke="rgb(0,0,0)" /> -</svg> diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_03.diag b/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_03.diag deleted file mode 100644 index 6ece3760..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_03.diag +++ /dev/null @@ -1,31 +0,0 @@ -seqdiag { - // Set edge properties - //edge_length = 300; // default value is 192 - //span_height = 80; // default value is 40 - - // Set fontsize. - //default_fontsize = 12; // default value is 11 - - // Numbering edges automaticaly - autonumber = False; - - // Change note color - default_note_color = lightblue; - - Client -> Apache [label = "Request"]; - === Apache mod_auth_kerb === - Client <- Apache [label = "401 Unauthorized"]; - Client -> Apache [label = "Authorization: Credentials"]; - Apache -> Apache [label = "Set\nUser Name\nAuth Type"]; - === Apache mod_lookup_identity === - Apache -> SSSD [label = "Get User Info"]; - SSSD --> IdP [label = "Get User Info", leftnote = "Only if\nnot cached\nby SSSD"]; - SSSD <-- IdP [label = "Return User Info"]; - Apache <- SSSD [label = "Return User Info"]; - Apache -> Apache [label = "Set User specific\nenvironment\nvariables"]; - === Apache mod_proxy === - Apache -> Container [label = "Proxy With User's Metadata"]; - Apache <- Container [label = "Response"]; - Client <- Apache [label = "Response"]; - -} diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_03.svg b/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_03.svg deleted file mode 100644 index 91e8b1be..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_03.svg +++ /dev/null @@ -1,143 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> -<svg viewBox="0 0 1024 1227" xmlns="http://www.w3.org/2000/svg" xmlns:inkspace="http://www.inkscape.org/namespaces/inkscape" xmlns:xlink="http://www.w3.org/1999/xlink"> - <defs id="defs_block"> - <filter height="1.504" id="filter_blur" inkspace:collect="always" width="1.1575" x="-0.07875" y="-0.252"> - <feGaussianBlur id="feGaussianBlur3780" inkspace:collect="always" stdDeviation="4.2" /> - </filter> - </defs> - <title>blockdiag</title> - <desc>seqdiag { - // Set edge properties - //edge_length = 300; // default value is 192 - //span_height = 80; // default value is 40 - - // Set fontsize. - //default_fontsize = 12; // default value is 11 - - // Numbering edges automaticaly - autonumber = False; - - // Change note color - default_note_color = lightblue; - - Client -> Apache [label = "Request"]; - === Apache mod_auth_kerb === - Client <- Apache [label = "401 Unauthorized"]; - Client -> Apache [label = "Authorization: Credentials"]; - Apache -> Apache [label = "Set\nUser Name\nAuth Type"]; - === Apache mod_lookup_identity === - Apache -> SSSD [label = "Get User Info"]; - SSSD --> IdP [label = "Get User Info", leftnote = "Only if\nnot cached\nby SSSD"]; - SSSD <-- IdP [label = "Return User Info"]; - Apache <- SSSD [label = "Return User Info"]; - Apache -> Apache [label = "Set User specific\nenvironment\nvariables"]; - === Apache mod_proxy === - Apache -> Container [label = "Proxy With User's Metadata"]; - Apache <- Container [label = "Response"]; - Client <- Apache [label = "Response"]; - -} -</desc> - <rect fill="rgb(0,0,0)" height="1065" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="8" x="127" y="140" /> - <rect fill="rgb(0,0,0)" height="142" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="8" x="319" y="140" /> - <rect fill="rgb(0,0,0)" height="815" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="8" x="319" y="344" /> - <rect fill="rgb(0,0,0)" height="200" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="8" x="511" y="586" /> - <rect fill="rgb(0,0,0)" height="70" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="8" x="703" y="654" /> - <rect fill="rgb(0,0,0)" height="64" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="8" x="895" y="1031" /> - <polygon fill="rgb(0,0,0)" points="420,636 491,636 499,644 499,672 420,672 420,636" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" /> - <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="67" y="46" /> - <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="259" y="46" /> - <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="451" y="46" /> - <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="643" y="46" /> - <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="835" y="46" /> - <path d="M 128 80 L 128 1215" fill="none" stroke="rgb(0,0,0)" stroke-dasharray="8 4" /> - <rect fill="moccasin" height="1065" stroke="rgb(0,0,0)" width="8" x="124" y="134" /> - <path d="M 320 80 L 320 1215" fill="none" stroke="rgb(0,0,0)" stroke-dasharray="8 4" /> - <rect fill="moccasin" height="142" stroke="rgb(0,0,0)" width="8" x="316" y="134" /> - <rect fill="moccasin" height="815" stroke="rgb(0,0,0)" width="8" x="316" y="338" /> - <path d="M 512 80 L 512 1215" fill="none" stroke="rgb(0,0,0)" stroke-dasharray="8 4" /> - <rect fill="moccasin" height="200" stroke="rgb(0,0,0)" width="8" x="508" y="580" /> - <path d="M 704 80 L 704 1215" fill="none" stroke="rgb(0,0,0)" stroke-dasharray="8 4" /> - <rect fill="moccasin" height="70" stroke="rgb(0,0,0)" width="8" x="700" y="648" /> - <path d="M 896 80 L 896 1215" fill="none" stroke="rgb(0,0,0)" stroke-dasharray="8 4" /> - <rect fill="moccasin" height="64" stroke="rgb(0,0,0)" width="8" x="892" y="1025" /> - <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="64" y="40" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="113" y="64">Client</text> - <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="256" y="40" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="302" y="65">Apache</text> - <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="448" y="40" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="498" y="64">SSSD</text> - <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="640" y="40" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="697" y="64">IdP</text> - <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="832" y="40" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="871" y="64">Container</text> - <path d="M 136 134 L 312 134" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="304,130 312,134 304,138" stroke="rgb(0,0,0)" /> - <path d="M 136 276 L 312 276" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="144,272 136,276 144,280" stroke="rgb(0,0,0)" /> - <path d="M 136 338 L 312 338" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="304,334 312,338 304,342" stroke="rgb(0,0,0)" /> - <path d="M 328 422 L 416 422" fill="none" stroke="rgb(0,0,0)" /> - <path d="M 416 422 L 416 438" fill="none" stroke="rgb(0,0,0)" /> - <path d="M 416 438 L 328 438" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="336,434 328,438 336,442" stroke="rgb(0,0,0)" /> - <path d="M 328 580 L 504 580" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="496,576 504,580 496,584" stroke="rgb(0,0,0)" /> - <path d="M 520 648 L 696 648" fill="none" stroke="rgb(0,0,0)" stroke-dasharray="4" /> - <polygon fill="rgb(0,0,0)" points="688,644 696,648 688,652" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(173,216,230)" points="417,630 488,630 496,638 496,666 417,666 417,630" stroke="rgb(0,0,0)" /> - <path d="M 488 630 L 488 638" fill="none" stroke="rgb(0,0,0)" /> - <path d="M 488 638 L 496 638" fill="none" stroke="rgb(0,0,0)" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="425" y="642">Only if</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="425" y="652">not cached</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="425" y="664">by SSSD</text> - <path d="M 520 718 L 696 718" fill="none" stroke="rgb(0,0,0)" stroke-dasharray="4" /> - <polygon fill="rgb(0,0,0)" points="528,714 520,718 528,722" stroke="rgb(0,0,0)" /> - <path d="M 328 780 L 504 780" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="336,776 328,780 336,784" stroke="rgb(0,0,0)" /> - <path d="M 328 864 L 416 864" fill="none" stroke="rgb(0,0,0)" /> - <path d="M 416 864 L 416 880" fill="none" stroke="rgb(0,0,0)" /> - <path d="M 416 880 L 328 880" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="336,876 328,880 336,884" stroke="rgb(0,0,0)" /> - <path d="M 328 1025 L 888 1025" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="880,1021 888,1025 880,1029" stroke="rgb(0,0,0)" /> - <path d="M 328 1089 L 888 1089" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="336,1085 328,1089 336,1093" stroke="rgb(0,0,0)" /> - <path d="M 136 1153 L 312 1153" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="144,1149 136,1153 144,1157" stroke="rgb(0,0,0)" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="140" y="132">Request</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="217" y="274">401 Unauthorized</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="140" y="336">Authorization: Credentials</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="328" y="398">Set</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="328" y="408">User Name</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="328" y="420">Auth Type</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="332" y="578">Get User Info</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="524" y="646">Get User Info</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="608" y="716">Return User Info</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="416" y="778">Return User Info</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="328" y="842">Set User specific</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="328" y="852">environment</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="328" y="862">variables</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="332" y="1023">Proxy With User's Metadata</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="841" y="1087">Response</text> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="265" y="1151">Response</text> - <path d="M 40 202 L 442 202" fill="none" stroke="rgb(0,0,0)" /> - <path d="M 40 206 L 442 206" fill="none" stroke="rgb(0,0,0)" /> - <path d="M 581 202 L 984 202" fill="none" stroke="rgb(0,0,0)" /> - <path d="M 581 206 L 984 206" fill="none" stroke="rgb(0,0,0)" /> - <rect fill="rgb(208,208,208)" height="18" stroke="rgb(0,0,0)" width="139" x="442" y="195" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="452" y="209">Apache mod_auth_kerb</text> - <path d="M 40 506 L 429 506" fill="none" stroke="rgb(0,0,0)" /> - <path d="M 40 510 L 429 510" fill="none" stroke="rgb(0,0,0)" /> - <path d="M 594 506 L 984 506" fill="none" stroke="rgb(0,0,0)" /> - <path d="M 594 510 L 984 510" fill="none" stroke="rgb(0,0,0)" /> - <rect fill="rgb(208,208,208)" height="18" stroke="rgb(0,0,0)" width="165" x="429" y="499" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="439" y="513">Apache mod_lookup_identity</text> - <path d="M 40 948 L 455 948" fill="none" stroke="rgb(0,0,0)" /> - <path d="M 40 952 L 455 952" fill="none" stroke="rgb(0,0,0)" /> - <path d="M 568 948 L 984 948" fill="none" stroke="rgb(0,0,0)" /> - <path d="M 568 952 L 984 952" fill="none" stroke="rgb(0,0,0)" /> - <rect fill="rgb(208,208,208)" height="18" stroke="rgb(0,0,0)" width="113" x="455" y="941" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="465" y="955">Apache mod_proxy</text> -</svg> diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_04.diag b/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_04.diag deleted file mode 100644 index 8f69a0b8..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_04.diag +++ /dev/null @@ -1,25 +0,0 @@ -blockdiag { - Connector -> SssdFilter; - SssdFilter -> ClaimAuthFilter; - ClaimAuthFilter -> SssdClaimAuth; - SssdClaimAuth -> Assertion [folded]; - - group { - orientation = portrait - Assertion -> JsonAssertion; - JsonAssertion -> IdPMapper; - IdPMapper -> JsonMapped; - } - - JsonMapped -> Claim; - - Connector [numbered = 1] - SssdFilter [numbered = 2] - ClaimAuthFilter [numbered = 3] - SssdClaimAuth [numbered = 4] - Assertion [numbered = 4.1] - JsonAssertion [numbered = 4.2] - IdPMapper [numbered = 4.3] - JsonMapped [numbered = 4.4] - Claim [numbered = 5] -} diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_04.svg b/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_04.svg deleted file mode 100644 index 74850a85..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_04.svg +++ /dev/null @@ -1,100 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> -<svg viewBox="0 0 832 440" xmlns="http://www.w3.org/2000/svg" xmlns:inkspace="http://www.inkscape.org/namespaces/inkscape" xmlns:xlink="http://www.w3.org/1999/xlink"> - <defs id="defs_block"> - <filter height="1.504" id="filter_blur" inkspace:collect="always" width="1.1575" x="-0.07875" y="-0.252"> - <feGaussianBlur id="feGaussianBlur3780" inkspace:collect="always" stdDeviation="4.2" /> - </filter> - </defs> - <title>blockdiag</title> - <desc>blockdiag { - Connector -> SssdFilter; - SssdFilter -> ClaimAuthFilter; - ClaimAuthFilter -> SssdClaimAuth; - SssdClaimAuth -> Assertion [folded]; - - group { - orientation = portrait - Assertion -> JsonAssertion; - JsonAssertion -> IdPMapper; - IdPMapper -> JsonMapped; - } - - JsonMapped -> Claim; - - Connector [numbered = 1] - SssdFilter [numbered = 2] - ClaimAuthFilter [numbered = 3] - SssdClaimAuth [numbered = 4] - Assertion [numbered = 4.1] - JsonAssertion [numbered = 4.2] - IdPMapper [numbered = 4.3] - JsonMapped [numbered = 4.4] - Claim [numbered = 5] -} -</desc> - <rect fill="rgb(243,152,0)" height="300" style="filter:url(#filter_blur)" width="144" x="56" y="110" /> - <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="67" y="46" /> - <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="259" y="46" /> - <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="451" y="46" /> - <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="643" y="46" /> - <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="67" y="126" /> - <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="67" y="206" /> - <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="67" y="286" /> - <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="67" y="366" /> - <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="259" y="366" /> - <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="64" y="40" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="103" y="64">Connector</text> - <ellipse cx="64" cy="40" fill="pink" rx="12" ry="12" stroke="rgb(0,0,0)" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="61" y="44">1</text> - <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="256" y="40" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="294" y="64">SssdFilter</text> - <ellipse cx="256" cy="40" fill="pink" rx="12" ry="12" stroke="rgb(0,0,0)" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="253" y="44">2</text> - <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="448" y="40" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="471" y="64">ClaimAuthFilter</text> - <ellipse cx="448" cy="40" fill="pink" rx="12" ry="12" stroke="rgb(0,0,0)" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="445" y="44">3</text> - <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="640" y="40" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="665" y="64">SssdClaimAuth</text> - <ellipse cx="640" cy="40" fill="pink" rx="12" ry="12" stroke="rgb(0,0,0)" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="637" y="44">4</text> - <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="64" y="120" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="103" y="144">Assertion</text> - <ellipse cx="64" cy="120" fill="pink" rx="12" ry="12" stroke="rgb(0,0,0)" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="56" y="124">4.1</text> - <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="64" y="200" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="91" y="224">JsonAssertion</text> - <ellipse cx="64" cy="200" fill="pink" rx="12" ry="12" stroke="rgb(0,0,0)" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="56" y="204">4.2</text> - <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="64" y="280" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="102" y="305">IdPMapper</text> - <ellipse cx="64" cy="280" fill="pink" rx="12" ry="12" stroke="rgb(0,0,0)" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="56" y="284">4.3</text> - <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="64" y="360" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="97" y="385">JsonMapped</text> - <ellipse cx="64" cy="360" fill="pink" rx="12" ry="12" stroke="rgb(0,0,0)" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="56" y="364">4.4</text> - <rect fill="rgb(255,255,255)" height="40" stroke="rgb(0,0,0)" width="128" x="256" y="360" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="307" y="384">Claim</text> - <ellipse cx="256" cy="360" fill="pink" rx="12" ry="12" stroke="rgb(0,0,0)" /> - <text fill="rgb(0,0,0)" font-family="sansserif" font-size="11" font-style="normal" font-weight="normal" x="253" y="364">5</text> - <path d="M 192 60 L 248 60" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="255,60 248,56 248,64 255,60" stroke="rgb(0,0,0)" /> - <path d="M 384 60 L 440 60" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="447,60 440,56 440,64 447,60" stroke="rgb(0,0,0)" /> - <path d="M 576 60 L 632 60" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="639,60 632,56 632,64 639,60" stroke="rgb(0,0,0)" /> - <path d="M 704 80 L 704 100" fill="none" stroke="rgb(0,0,0)" /> - <path d="M 128 100 L 704 100" fill="none" stroke="rgb(0,0,0)" /> - <path d="M 128 100 L 128 112" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="128,119 124,112 132,112 128,119" stroke="rgb(0,0,0)" /> - <path d="M 128 160 L 128 192" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="128,199 124,192 132,192 128,199" stroke="rgb(0,0,0)" /> - <path d="M 128 240 L 128 272" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="128,279 124,272 132,272 128,279" stroke="rgb(0,0,0)" /> - <path d="M 128 320 L 128 352" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="128,359 124,352 132,352 128,359" stroke="rgb(0,0,0)" /> - <path d="M 192 380 L 248 380" fill="none" stroke="rgb(0,0,0)" /> - <polygon fill="rgb(0,0,0)" points="255,380 248,376 248,384 255,380" stroke="rgb(0,0,0)" /> -</svg> diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_05.svg b/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_05.svg deleted file mode 100644 index f4657f06..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_05.svg +++ /dev/null @@ -1,613 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<svg - xmlns:osb="http://www.openswatchbook.org/uri/2009/osb" - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="689.19269" - height="212.05057" - id="svg2" - version="1.1" - inkscape:version="0.48.5 r10040" - sodipodi:docname="sssd_05.svg"> - <defs - id="defs4"> - <linearGradient - inkscape:collect="always" - id="linearGradient12785" - osb:paint="gradient"> - <stop - style="stop-color:#000000;stop-opacity:1;" - offset="0" - id="stop12787" /> - <stop - style="stop-color:#000000;stop-opacity:0;" - offset="1" - id="stop12789" /> - </linearGradient> - <linearGradient - id="linearGradient12777"> - <stop - style="stop-color:#ffcc00;stop-opacity:1;" - offset="0" - id="stop12779" /> - <stop - style="stop-color:#ffcc00;stop-opacity:0;" - offset="1" - id="stop12781" /> - </linearGradient> - <marker - inkscape:stockid="Scissors" - orient="auto" - refY="0" - refX="0" - id="Scissors" - style="overflow:visible"> - <path - id="schere" - d="M 9.0898857,-3.6061018 C 8.1198849,-4.7769976 6.3697607,-4.7358294 5.0623558,-4.2327734 l -8.2124046,3.0779029 c -2.3882933,-1.3067135 -4.7482873,-0.9325372 -4.7482873,-1.5687873 0,-0.4973164 0.4566662,-0.3883222 0.3883068,-1.6831941 -0.065635,-1.2432767 -1.3635771,-2.1630796 -2.5903987,-2.0816435 -1.227271,-0.00735 -2.499439,0.9331613 -2.510341,2.2300611 -0.09143,1.3063864 1.007209,2.5196896 2.306764,2.6052316 1.5223406,0.2266616 4.218258,-0.6955566 5.482945,1.57086006 -0.9422847,1.73825774 -2.6140244,1.74307674 -4.1255107,1.65607034 -1.2548743,-0.072235 -2.7620933,0.2873979 -3.3606483,1.5208605 -0.578367,1.1820862 -0.0112,2.8646022 1.316749,3.226412 1.3401912,0.4918277 3.1806689,-0.129711 3.4993722,-1.6707242 0.2456585,-1.187823 -0.5953659,-1.7459574 -0.2725074,-2.1771537 0.2436135,-0.32536 1.7907806,-0.1368452 4.5471053,-1.3748244 L 5.6763468,4.2330688 C 6.8000164,4.5467672 8.1730685,4.5362646 9.1684433,3.4313614 L -0.05164093,-0.05372222 9.0898857,-3.6061018 z m -18.3078016,-1.900504 c 1.294559,0.7227998 1.1888392,2.6835702 -0.1564272,3.0632889 -1.2165179,0.423661 -2.7710269,-0.7589694 -2.3831779,-2.0774648 0.227148,-1.0818519 1.653387,-1.480632 2.5396051,-0.9858241 z m 0.056264,8.0173649 c 1.3508301,0.4988648 1.1214429,2.7844356 -0.2522207,3.091609 -0.9110594,0.3163391 -2.2135494,-0.1387976 -2.3056964,-1.2121394 -0.177609,-1.305055 1.356085,-2.4841482 2.5579171,-1.8794696 z" - style="fill:#000000" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="DotL" - orient="auto" - refY="0" - refX="0" - id="DotL" - style="overflow:visible"> - <path - id="path4170" - d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" - transform="matrix(0.8,0,0,0.8,5.92,0.8)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="StopL" - orient="auto" - refY="0" - refX="0" - id="StopL" - style="overflow:visible"> - <path - id="path4278" - d="M 0,5.65 0,-5.65" - style="fill:none;stroke:#000000;stroke-width:1pt" - transform="scale(0.8,0.8)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow2Mstart" - orient="auto" - refY="0" - refX="0" - id="Arrow2Mstart" - style="overflow:visible"> - <path - id="path4133" - style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round" - d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" - transform="scale(0.6,0.6)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow2Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow2Mend" - style="overflow:visible"> - <path - id="path4136" - style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round" - d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" - transform="scale(-0.6,-0.6)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend" - style="overflow:visible"> - <path - id="path4118" - d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" - transform="matrix(-0.4,0,0,-0.4,-4,0)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow2Lend" - orient="auto" - refY="0" - refX="0" - id="Arrow2Lend" - style="overflow:visible"> - <path - id="path4130" - style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round" - d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" - transform="matrix(-1.1,0,0,-1.1,-1.1,0)" - inkscape:connector-curvature="0" /> - </marker> - <filter - color-interpolation-filters="sRGB" - height="1.5039999" - id="filter_blur" - inkscape:collect="always" - width="1.1575" - x="-0.078749999" - y="-0.252"> - <feGaussianBlur - id="feGaussianBlur3780" - inkscape:collect="always" - stdDeviation="4.2" /> - </filter> - <marker - inkscape:stockid="Arrow2Mstart" - orient="auto" - refY="0" - refX="0" - id="Arrow2Mstart-7" - style="overflow:visible"> - <path - inkscape:connector-curvature="0" - id="path4133-8" - style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round" - d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" - transform="scale(0.6,0.6)" /> - </marker> - <marker - inkscape:stockid="Arrow2Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow2Mend-1" - style="overflow:visible"> - <path - inkscape:connector-curvature="0" - id="path4136-9" - style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round" - d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" - transform="scale(-0.6,-0.6)" /> - </marker> - <filter - color-interpolation-filters="sRGB" - height="1.5039999" - id="filter_blur-1" - inkscape:collect="always" - width="1.1575" - x="-0.078749999" - y="-0.252"> - <feGaussianBlur - id="feGaussianBlur3780-1" - inkscape:collect="always" - stdDeviation="4.2" /> - </filter> - <filter - inkscape:collect="always" - id="filter18355"> - <feGaussianBlur - inkscape:collect="always" - stdDeviation="6.2598764" - id="feGaussianBlur18357" /> - </filter> - </defs> - <sodipodi:namedview - id="base" - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1.0" - inkscape:pageopacity="0.0" - inkscape:pageshadow="2" - inkscape:zoom="1.4" - inkscape:cx="405.52492" - inkscape:cy="110.18507" - inkscape:document-units="px" - inkscape:current-layer="layer1" - showgrid="false" - inkscape:snap-grids="true" - inkscape:window-width="1920" - inkscape:window-height="992" - inkscape:window-x="0" - inkscape:window-y="27" - inkscape:window-maximized="1" - fit-margin-top="0" - fit-margin-left="0" - fit-margin-right="0" - fit-margin-bottom="0" /> - <metadata - id="metadata7"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title /> - </cc:Work> - </rdf:RDF> - </metadata> - <g - inkscape:label="Layer 1" - inkscape:groupmode="layer" - id="layer1" - transform="translate(-22.986913,-110.53072)"> - <rect - y="136.89983" - x="254.85715" - height="185.19879" - width="456.83981" - id="rect12822" - style="fill:#f39800;fill-opacity:1;stroke:#000000;stroke-width:0.96499999999999997;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;filter:url(#filter18355)" /> - <g - id="g18452"> - <rect - y="244.58766" - x="105.58965" - height="41.710945" - width="129.83621" - id="rect2987" - style="fill:#ffffff;stroke:#000000;stroke-width:1.41119610999999989px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" /> - <text - sodipodi:linespacing="125%" - id="text2991" - y="261.25369" - x="112.20991" - style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" - xml:space="preserve"><tspan - id="tspan2995" - y="261.25369" - x="112.20991" - sodipodi:role="line">Apache mod_proxy:</tspan><tspan - id="tspan2997" - y="276.25369" - x="112.20991" - sodipodi:role="line">forward port 8383</tspan></text> - </g> - <g - id="g18364"> - <rect - y="167.43681" - x="304.33868" - height="50.483749" - width="98.582535" - id="rect2987-7" - style="fill:#ffffff;stroke:#000000;stroke-width:1.35282063000000008px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" /> - <text - sodipodi:linespacing="125%" - id="text2991-2" - y="181.34079" - x="353.99908" - style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans" - xml:space="preserve"><tspan - id="tspan2997-2" - y="181.34079" - x="353.99908" - sodipodi:role="line">Connector:</tspan><tspan - id="tspan3813" - y="196.34079" - x="353.99908" - sodipodi:role="line">port = 80</tspan><tspan - id="tspan3908" - y="211.34079" - x="353.99908" - sodipodi:role="line">(web)</tspan></text> - </g> - <flowRoot - xml:space="preserve" - id="flowRoot3815" - style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><flowRegion - id="flowRegion3817"><rect - id="rect3819" - width="201.02036" - height="90.913727" - x="174.25131" - y="117.466" /></flowRegion><flowPara - id="flowPara3821" /></flowRoot> <g - id="g18419"> - <rect - y="240.20126" - x="304.33868" - height="50.483749" - width="98.582535" - id="rect2987-7-6" - style="fill:#ffffff;stroke:#000000;stroke-width:1.35282063000000008px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" /> - <text - sodipodi:linespacing="125%" - id="text2991-2-6" - y="253.64822" - x="353.63287" - style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans" - xml:space="preserve"><tspan - id="tspan2997-2-4" - y="253.64822" - x="353.63287" - sodipodi:role="line">Connector:</tspan><tspan - id="tspan3813-5" - y="268.64822" - x="353.63287" - sodipodi:role="line">port = 8383</tspan><tspan - id="tspan3908-2" - y="283.64822" - x="353.63287" - sodipodi:role="line">(auth proxy)</tspan></text> - </g> - <g - id="g7018" - transform="translate(-14,35.850205)"> - <g - id="g7023" - transform="translate(218.19295,1.0101525)"> - <g - id="g7028" - transform="translate(-97.984797,178.797)"> - <polygon - id="polygon6858" - style="opacity:0.7;fill:#000000;fill-opacity:1;filter:url(#filter_blur)" - points="60,61 60,56 66,56 66,61 83,61 83,66 66,66 66,71 80,86 73,86 63,76 53,86 46,86 60,71 60,66 43,66 43,61 " - transform="translate(-115.02286,-17.004219)" /> - <polygon - id="polygon6872" - points="57,55 57,50 63,50 63,55 80,55 80,60 63,60 63,65 77,80 70,80 60,70 50,80 43,80 57,65 57,60 40,60 40,55 " - style="fill:#ffffff;stroke:#000000" - transform="translate(-115.02286,-17.004219)" /> - <ellipse - d="m 67,45 c 0,3.865993 -3.134007,7 -7,7 -3.865993,0 -7,-3.134007 -7,-7 0,-3.865993 3.134007,-7 7,-7 3.865993,0 7,3.134007 7,7 z" - id="ellipse6874" - ry="7" - rx="7" - cy="45" - cx="60" - sodipodi:cx="60" - sodipodi:cy="45" - sodipodi:rx="7" - sodipodi:ry="7" - style="fill:#ffffff;stroke:#000000" - transform="translate(-115.02286,-17.004219)" /> - </g> - </g> - </g> - <rect - style="fill:#ffffff;stroke:#000000;stroke-width:1.35282063000000008px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" - id="rect2987-7-5" - width="98.582535" - height="50.483749" - x="589.35858" - y="239.54141" /> - <text - xml:space="preserve" - style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans" - x="638.74945" - y="254.25693" - id="text2991-2-67" - sodipodi:linespacing="125%"><tspan - id="tspan10147" - sodipodi:role="line" - x="638.74945" - y="254.25693">AAA Servlet</tspan><tspan - id="tspan10204" - sodipodi:role="line" - x="638.74945" - y="269.25693">executes</tspan><tspan - id="tspan10206" - sodipodi:role="line" - x="638.74945" - y="284.25693">with roles</tspan></text> - <flowRoot - xml:space="preserve" - id="flowRoot10151" - style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><flowRegion - id="flowRegion10153"><rect - id="rect10155" - width="139.90613" - height="110.10663" - x="648.01288" - y="147.2655" /></flowRegion><flowPara - id="flowPara10157" /></flowRoot> <g - id="g18431"> - <rect - y="169.04143" - x="589.86121" - height="50.483749" - width="98.582535" - id="rect2987-7-5-0" - style="fill:#ffffff;stroke:#000000;stroke-width:1.35282063000000008px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" /> - <text - sodipodi:linespacing="125%" - id="text2991-2-67-9" - y="191.07236" - x="638.61047" - style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans" - xml:space="preserve"><tspan - y="191.07236" - x="638.61047" - sodipodi:role="line" - id="tspan10147-8">Non-AAA</tspan><tspan - y="206.07236" - x="638.61047" - sodipodi:role="line" - id="tspan10198">Servlet</tspan><tspan - y="221.07236" - x="638.61047" - sodipodi:role="line" - id="tspan10196" /></text> - </g> - <g - id="g18474"> - <rect - y="168.30391" - x="437.00925" - height="122.27845" - width="121.29423" - id="rect2987-7-2-2" - style="fill:#ffffff;stroke:#000000;stroke-width:2.33539009000000020px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" /> - <text - sodipodi:linespacing="125%" - id="text2991-2-9-8" - y="181.0443" - x="497.75305" - style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans" - xml:space="preserve"><tspan - id="tspan3908-4-7" - y="181.0443" - x="497.75305" - sodipodi:role="line">ClaimAuthFilter:</tspan><tspan - id="tspan4038" - y="196.0443" - x="497.75305" - sodipodi:role="line">localPort in</tspan><tspan - id="tspan4040" - y="211.0443" - x="497.75305" - sodipodi:role="line">secureProxyPorts?</tspan><tspan - id="tspan4044" - y="226.0443" - x="497.75305" - sodipodi:role="line" /></text> - <g - id="g18469"> - <rect - style="fill:#ff0000;stroke:#000000;stroke-width:0.81352955000000005;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" - id="rect10241" - width="98.994949" - height="23.733509" - x="448.15887" - y="220.00537" /> - <text - xml:space="preserve" - style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" - x="488.27258" - y="236.16118" - id="text10243" - sodipodi:linespacing="125%"><tspan - sodipodi:role="line" - id="tspan10245" - x="488.27258" - y="236.16118">No</tspan></text> - </g> - <g - id="g18461"> - <rect - style="fill:#00ff00;stroke:#000000;stroke-width:0.81352955000000005;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" - id="rect10241-9" - width="98.994949" - height="23.733509" - x="448.15887" - y="253.81883" /> - <text - xml:space="preserve" - style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" - x="488.27258" - y="269.97464" - id="text10243-4" - sodipodi:linespacing="125%"><tspan - sodipodi:role="line" - id="tspan10245-6" - x="488.27258" - y="269.97464">Yes</tspan></text> - </g> - </g> - <g - id="g7018-9" - transform="translate(-15.11838,-36.914245)"> - <g - id="g7023-0" - transform="translate(218.19295,1.0101525)"> - <g - id="g7028-1" - transform="translate(-97.984797,178.797)"> - <polygon - id="polygon6858-6" - style="opacity:0.7;fill:#000000;fill-opacity:1;filter:url(#filter_blur-1)" - points="60,71 60,66 43,66 43,61 60,61 60,56 66,56 66,61 83,61 83,66 66,66 66,71 80,86 73,86 63,76 53,86 46,86 " - transform="translate(-115.02286,-17.004219)" /> - <polygon - id="polygon6872-6" - points="57,65 57,60 40,60 40,55 57,55 57,50 63,50 63,55 80,55 80,60 63,60 63,65 77,80 70,80 60,70 50,80 43,80 " - style="fill:#ffffff;stroke:#000000" - transform="translate(-115.02286,-17.004219)" /> - <ellipse - d="m 67,45 c 0,3.865993 -3.134007,7 -7,7 -3.865993,0 -7,-3.134007 -7,-7 0,-3.865993 3.134007,-7 7,-7 3.865993,0 7,3.134007 7,7 z" - id="ellipse6874-1" - ry="7" - rx="7" - cy="45" - cx="60" - sodipodi:cx="60" - sodipodi:cy="45" - sodipodi:rx="7" - sodipodi:ry="7" - style="fill:#ffffff;stroke:#000000" - transform="translate(-115.02286,-17.004219)" /> - </g> - </g> - </g> - <text - xml:space="preserve" - style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" - x="430.15594" - y="119.6479" - id="text12879" - sodipodi:linespacing="125%"><tspan - sodipodi:role="line" - id="tspan12881" - x="430.15594" - y="119.6479">Java EE Container</tspan></text> - <path - style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow2Mstart-7);marker-end:url(#Arrow2Mend-1)" - d="m 57.185293,265.44314 48.404357,0" - id="path13365" - inkscape:connector-type="polyline" - inkscape:connector-curvature="0" - inkscape:connection-start="#g7018" - inkscape:connection-start-point="d4" /> - <path - style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow2Mstart-7);marker-end:url(#Arrow2Mend-1)" - d="m 235.42587,265.44314 68.91281,0" - id="path14574" - inkscape:connector-type="polyline" - inkscape:connector-curvature="0" /> - <path - style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow2Mstart-7);marker-end:url(#Arrow2Mend-1)" - d="m 402.92122,265.52611 45.23767,0.0762" - id="path14999" - inkscape:connector-type="polyline" - inkscape:connector-curvature="0" /> - <path - style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow2Mstart-7);marker-end:url(#Arrow1Mend)" - d="m 402.92122,206.09216 51.12769,13.91321" - id="path15397" - inkscape:connector-type="polyline" - inkscape:connector-curvature="0" /> - <path - style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow2Mstart-7);marker-end:url(#Arrow2Mend-1)" - d="m 542.32654,220.00537 47.53467,-12.62771" - id="path15795" - inkscape:connector-type="polyline" - inkscape:connector-curvature="0" /> - <path - style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow2Mstart-7);marker-end:url(#Arrow2Mend-1)" - d="m 547.15383,265.36883 42.20475,-0.2701" - id="path16193" - inkscape:connector-type="polyline" - inkscape:connector-curvature="0" /> - <path - style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow2Mstart-7);marker-end:url(#Arrow2Mend-1)" - d="m 56.066913,192.67869 248.271767,0" - id="path17038" - inkscape:connector-type="polyline" - inkscape:connector-curvature="0" - inkscape:connection-start="#g7018-9" - inkscape:connection-start-point="d4" /> - </g> -</svg> diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_auth_sequence.png b/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_auth_sequence.png Binary files differdeleted file mode 100644 index 9f9a0b49..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_auth_sequence.png +++ /dev/null diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_auth_sequence.wsd b/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_auth_sequence.wsd deleted file mode 100644 index f97ed1ee..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_auth_sequence.wsd +++ /dev/null @@ -1,23 +0,0 @@ -title Federated Authentication with SSSD - -# This walks through the federated authentication sequence where a claim from a -# third-party IdP system is posted to the ODL token endpoint in exchange for an -# access token. The claim information is assumed to be in format specific to the -# third-party IdP system and assumed to be captured via either Apache environment -# variables (Servlet attributes) or HTTP headers. - -Client -> Apache WebServer: authenticate -note right of Client -credentials -end note -Apache WebServer -> SSSD: authenticate -SSSD -> LDAP/AD : authenticate -SSSD -> Apache WebServer: claim -Apache WebServer -> ServletContainer: CGI variables -ServletContainer -> SSSD Plugin: Servlet attributes/headers -SSSD Plugin -> SSSD Plugin : transformClaim -SSSD Plugin -> TokenEndPoint : claim -TokenEndPoint -> TokenEndPoint : createToken -TokenEndPoint -> Client : refresh token, list of authorized domains -Client -> TokenEndPoint : refresh token, domain -TokenEndPoint -> Client : access token diff --git a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_configuration.rst b/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_configuration.rst deleted file mode 100644 index 7f912d94..00000000 --- a/odl-aaa-moon/aaa-authn-api/src/main/docs/sssd_configuration.rst +++ /dev/null @@ -1,1687 +0,0 @@ -################################################ -Federated Authentication Utilizing Apache & SSSD -################################################ - -:Author: John Dennis -:Email: jdennis@redhat.com - -.. contents:: Table of Contents - -************ -Introduction -************ - -Applications should not need to handle the burden of authentication -and authorization. These are complex technologies further complicated -by the existence of a wide variety of authentication -mechanisms. Likewise there are numerous identity providers (IdP) which -one may wish to utilize, perhaps in a federated manner. The potential -to make critical mistakes are high while consuming significant -engineering resources. Ideally an application should "outsource" it's -authentication to an "expert" and avoid unnecessary development costs. - -For web based applications (both conventional HTML and REST API) there -has been a trend to embed a simple HTTP server in the application or -application server which handles the HTTP requests eschewing the use -of a traditional web server such as Apache. - -.. figure:: sssd_01.png - :align: center - - _`Figure 1.` - -But traditional web servers have a lot of advantages. They often come -with extensive support for technologies you might wish to utilize in -your application. It would require signification software engineering -to add support for those technologies in your application. The problem -is compounded by the fact many of these technologies demand domain -expertise which is unlikely to be available in the application -development team. Another problem is the libraries needed to utilize -the technology may not even be available in the programming language -the application is being developed in. Fundamentally an application -developer should focus on developing their application instead of -investing resources into implementing complex code for the ancillary -technologies the application may wish to utilize. - -Therefore fronting your application with a web server such as Apache -makes a lot of sense. One should allow Apache to handle complex tasks -such as multiple authentication mechanisms talking to multiple -IdP's. Suppose you want your application to handle Single Sign-On -(SSO) via Kerberos or authentication based on X509 certificates -(i.e. PKI). Apache already has extensions to handle these which have -been field proven, it would be silly to try and support these in your -application. Apache also comes with other useful extensions such as -``mod_identity_lookup`` which can extract metadata about an -authenticated user from multiple sources such as LDAP, -Active Directory, NIS, etc. - -By fronting your application with Apache and allowing Apache to handle -the complex task of authentication, identity lookups etc. you've -greatly increased the features of your application while at the same -time reducing application development time along with increasing -application security and robustness. - -.. figure:: sssd_02.png - :align: center - - _`Figure 2.` - -When Apache fronts your application you will be passed the results of -authentication and identity lookups. Your application only needs a -simple mechanism to accept these values. There are a variety of ways -the values can be passed from Apache to your application which will be -discussed in later sections. - -Authentication & Identity Properties -==================================== - -Authentication is proving that a user is who they claim to be, in -other words after authentication the user has a proven identity. In -security parlance the authenticated entity is call a -principal. Principals may be humans, machines or -services. Authorization is distinct from authentication. Authorization -declares what actions an authenticated principal may perform. For -example, does a principal have permission to read a certain file, run -a specific command, etc. Identity metadata is typically bound to the -principal to provide extra information. Examples include the users -full name, their organization, the groups they are members of, etc. - -Apache can provide both authentication and identity metadata to an -application freeing the application of this task. Authorization -usually will remain the province of the application. A typical -design pattern is to assign roles to a principal based on identity -properties. As the application executes on behalf of a principal the -application will check if the principal has the necessary role needed -to perform the operation. - -Apache ships with a wide variety of authentication modules. After an -Apache authentication module successfully authenticates a principal, it -sets internal variables identifying the principal and the -authentication method used to authenticate the principal. These are -exported as the CGI variables REMOTE_USER and AUTH_TYPE respectively -(see `CGI Export Issues`_ for further information). - -Identity Properties -------------------- - -Most Apache authentication modules do not have access to any of the -identity properties bound to the authenticated principal. Those -identity properties must be provided by some other mechanism. Typical -mechanisms include lookups in LDAP, Active Directory, NIS, POSIX -passwd/gecos and SQL. Managing these lookups can be difficult -especially in a networked environment where services may be -temporarily unavailable and/or in a enterprise deployment where -identity sources must be multiplexed across a variety of services -according to enterprise wide policy. - -`SSSD`_ (System Security Services Daemon) is designed to alleviate many -of the problems surrounding authentication and identity property -lookup. SSSD can provide identity properties via D-Bus using it's -InfoPipe (IFP) feature. The `mod_identity_lookup`_ Apache module is -given the name of the authenticated principal and makes available -identity properties via Apache environment variables (see `Configure -SSSD IFP`_ for details). - -Exporting & Consuming Identity Metadata -======================================= - -The authenticated principal (REMOTE_USER), the mechanism used to -authenticate the principal (AUTH_TYPE) and identity properties -(supplied by SSSD IFP) are exported to the application which trusts -this metadata to be valid. - -How is this identity metadata exported from Apache and then be -consumed by a Java EE Servlet? - -The architectural design inside Apache tries to capitalize on the -existing CGI standard (`CGI RFC`_) as much as possible. CGI defines -these relevant environment variables: - - * REMOTE_USER - * AUTH_TYPE - * REMOTE_ADDR - * REMOTE_HOST - - -Transporting Identity Metadata from Apache to a Java EE Servlet -=============================================================== - -In following figure we can see that the user connects to Apache -instead of the servlet container. Apache authenticates the user, looks -up the principal's identity information and then proxies the request -to the servlet container. The additional identity metadata must be -included in the proxy request in order for the servlet to extract it. - -.. figure:: sssd_03.png - :align: center - - _`Figure 3.` - -The Java EE Servlet API is designed with the HTTP protocol in mind -however the servlet never directly accesses the HTTP protocol stream. -Instead it uses the servlet API to get access to HTTP request -data. The responsibility for HTTP communication rests with the -container's ``Connector`` objects. When the servlet API needs -information it works in conjunction with the ``Connector`` to supply -it. For example the ``HttpServletRequest.getRemoteHost()`` method -interrogates information the ``Connector`` placed on the internal -request object. Analogously ``HttpServletRequest.getRemoteUser()`` -interrogates information placed on the internal request object by an -authentication filter. - -But what happens when a HTTP request is proxied to a servlet container -by Apache and ``getRemoteHost()`` or ``getRemoteUser()`` is called? Most -``Connector`` objects do not understand the proxy scenario, to them -a request from a proxy looks just like a request sent directly to the -servlet container. Therefore ``getRemoteHost()`` or ``getRemoteUser()`` -ends up returning information relative to the proxy instead of the -user who connected to the proxy because it's the proxy who connected -to the servlet container and not the end user. There are 2 fundamental -approaches which allow the servlet API to return data supplied by the -proxy: - - 1. Proxy uses special protocol (e.g. AJP) to embed metadata. - 2. Metadata is embedded in an HTTP extension by the proxy (i.e. headers) - -Proxy With AJP Protocol ------------------------ - -The AJP_ protocol was designed as a protocol to exchange HTTP requests -and responses between Apache and a Java EE Servlet Container. One of -its design goals was to improve performance by translating common text -values appearing in HTTP requests to a more compact binary form. At -the same time AJP provided a mechanism to supply metadata about the -request to the servlet container. That metadata is encoded in an AJP -attribute (a name/value pair). The Apache AJP Proxy module looks up -information in the internal Apache request object (e.g. remote user, -remote address, etc.) and encodes that metadata in AJP attributes. On -the servlet container side a AJP ``Connector`` object is aware of these -metadata attributes, extracts them from the protocol and supplies -their values to the upper layers of the servlet API. Thus a call to -``HttpServletRequest.getRemoteUser()`` made by a servlet will receive -the value set by Apache prior to the proxy. This is the desired and -expected behavior. A servlet should be ignorant of the consequences of -proxies; the servlet API should behave the same regardless of the -presence of a proxy. - -The AJP protocol also has a general purpose attribute mechanism whereby -any arbitrary name/value pair can be passed. This proxy metadata can -be retrieved by a servlet by calling ``ServletRequest.getAttribute()`` -[1]_ When Apache mod_proxy_ajp is being used the authentication -metadata for the remote user and auth type are are automatically -inserted into the AJP protocol and the AJP ``Connector`` object on -the servlet receiving end supplies those values to -``HttpServletRequest.getRemoteHost()`` and -``HttpServletRequest.getRemoteUser()`` respectively. But the identity -metadata supplied by ``mod_identity_lookup`` needs to be explicitly -encoded into an AJP attribute (see `Configure SSSD IFP`_ for details) -that can later be retrieved by ``ServletRequest.getAttribute()``. - -Proxy With HTTP Protocol ------------------------- - -Although the AJP protocol offers a number of nice advantages sometimes -it's not an option. Not all servlet containers support AJP or there -may be some other deployment constraint that precludes its use. In this -case option 2 from above needs to be used. Option 2 requires only the -defined HTTP protocol be used without any "out of band" metadata. The -conventional way to attach extension metadata to a HTTP request is to -add extension HTTP headers. - -One problem with using extension HTTP headers to pass metadata to a -servlet is the expectation the servlet API will have the same -behavior. In other words the value returned by -``HttpServletRequest.getRemoteUser()`` should not depend on whether the -proxy request was exchanged with the AJP protocol or the HTTP -protocol. The solution to this is to wrap the ``HttpServletRequest`` -object in a servlet filter. The wrapper overrides certain request -methods (e.g. ``getRemoteUser()``). The override method looks to see if -the metadata is in the extension HTTP headers, if so it returns the -value found in the extension HTTP header otherwise it defers to the -existing servlet implementation. The ``ServletRequest.getAttribute()`` is -overridden in an analogous manner in the wrapper filter. Any call to -``ServletRequest.getAttribute()`` is first checked to see if the value -exists in the extension HTTP header first. - -Metadata supplied by Apache that is **not** part of the normal Java -EE Servlet API **always** appears to the servlet via the -``ServletRequest.getAttribute()`` method regardless of the proxy -transport mechanism. The consequence of this is a servlet -continues to utilize the existing Java EE Servlet API without concern -for intermediary proxies, *and* any other metadata supplied by a proxy -is *always* retrieved via ``ServletRequest.getAttribute()`` (see the -caveat about ``ServletRequest.getAttributeNames()`` [1]_). - -******************* -Configuration Guide -******************* - -Although Apache authentication and SSSD identity lookup can operate -with a variety of authentication mechanisms, IdP's and identity -metadata providers we will demonstrate a configuration example which -utilizes the FreeIPA_ IdP. FreeIPA excels at Kerberos SSO authentication, -Active Directory integration, LDAP based identity metadata storage and -lookup, DNS services, host based RBAC, SSH key management, certificate -management, friendly web based console, command line tools and many -other advanced IdP features. - -The following configuration steps will need to be performed: - -1. Install FreeIPA_ by following the installation guides in the FreeIPA_ - documentation area. When you install FreeIPA_ you will need to select a - realm (a.k.a domain) in which your users and hosts will exist. In - our example we will use the ``EXAMPLE.COM`` realm. - -2. Install and configure the Apache HTTP web server. The - recommendation is to install and run the Apache HTTP web server on - the same system the Java EE Container running AAA is installed on. - -3. Configure the proxy connector in the Java EE Container and set the - ``secureProxyPorts``. - -We will also illustrate the operation of the system by adding an -example user named ``testuser`` who will be a member of the -``odl_users`` and ``odl_admin`` groups. - -Add Example User and Groups to FreeIPA -====================================== - -After installing FreeIPA you will need to populate FreeIPA with your users, -groups and other data. Refer to the documentation in FreeIPA_ for the -variety of ways this task can be performed; it runs the gamut from web -based console to command line utilities. For simplicity we will use -the command line utilities. - -Identify yourself to FreeIPA as an administrator; this will give you the -necessary privileges needed to create and modify data in FreeIPA. You do -this by obtaining a Kerberos ticket for the ``admin`` user (or any -other user in FreeIPA with administrator privileges. - -:: - - % kinit admin@EXAMPLE.COM - -Create the example ``odl_users`` and `odl_admin`` groups. - -:: - - % ipa group-add odl_users --desc 'OpenDaylight Users' - % ipa group-add odl_admin --desc 'OpenDaylight Administrators' - -Create the example user ``testuser`` with the first name "Test" and a -last name of "User" and an email address of "test.user@example.com" - -:: - - % ipa user-add testuser --first Test --last User --email test.user@example.com - -Now add ``testuser`` to the ``odl_users`` and ``odl_admin`` groups. - -:: - - % ipa group-add-member odl_users --user testuser - % ipa group-add-member odl_admin --user testuser - -Configure Apache -================ - -A number of Apache configuration directives will need to be specified -to implement the Apache to application binding. Although these -configuration directives can be located in any number of different -Apache configuration files the most sensible approach is to co-locate -them in a single application configuration file. This greatly -simplifies the deployment of your application and isolates your -application configuration from other applications and services sharing -the Apache installation. In the examples that follow our application -will be named ``my_app`` and the Apache application configuration file -will be named ``my_app.conf`` which should be located in Apache's -``conf.d/`` directory. The web resource we are protecting and -supplying identity metadata for will be named ``my_resource``. - - -Configure Apache for Kerberos ------------------------------ - -When FreeIPA is deployed Kerberos is the preferred authentication mechanism -for Single Sign-On (SSO). FreeIPA also provides identity metadata via -Apache ``mod_identity_lookup``. To protect your ``my_resource`` resource -with Kerberos authentication identify your resource as requiring -Kerberos authentication in your ``my_app.conf`` Apache -configuration. For example: - -:: - - <Location my_resource> - AuthType Kerberos - AuthName "Kerberos Login" - KrbMethodNegotiate On - KrbMethodK5Passwd Off - KrbAuthRealms EXAMPLE.COM - Krb5KeyTab /etc/http.keytab - require valid-user - </Location> - -You will need to replace EXAMPLE.COM in the KrbAuthRealms declaration -with the Kerberos realm for your deployment. - - -Configure SSSD IFP ------------------- - -To use the Apache ``mod_identity_lookup`` module to supply identity -metadata you need to do the following in ``my_app.conf``: - -1. Enable the module - - :: - - LoadModule lookup_identity_module modules/mod_lookup_identity.so - -2. Apply the identity metadata lookup to specific URL's - (e.g. ``my_resource``) via an Apache location directive. In this - example we look up the "mail" attribute and assign it to the - REMOTE_USER_EMAIL environment variable. - - :: - - <LocationMatch "my_resource"> - LookupUserAttr mail REMOTE_USER_EMAIL - </LocationMatch> - -3. Export the environment variable via the desired proxy protocol, see - `Exporting Environment Variables to the Proxy`_ - -Exporting Environment Variables to the Proxy --------------------------------------------- - -First you need to decide which proxy protocol you're going to use, AJP -or HTTP and then determine the target address and port to proxy to. The -recommended configuration is to run both the Apache server and the -servlet container on the same host and to proxy requests over the -local loopback interface (see `Declaring the Connector Ports for -Authentication Proxies`_). In our examples we'll use port 8383. Thus -in ``my_app.conf`` add a proxy declaration. - -For HTTP Proxy - -:: - - ProxyPass / http://localhost:8383/ - ProxyPassReverse / http://localhost:8383/ - -For AJP Proxy - -:: - - ProxyPass / ajp://localhost:8383/ - ProxyPassReverse / ajp://localhost:8383/ - -AJP Exports -^^^^^^^^^^^ - -AJP automatically forwards REMOTE_USER and AUTH_TYPE making them -available to the ``HttpServletRequest`` API, thus you do not need to -explicitly forward these in the proxy configuration. However all other -``mod_identity_lookup`` metadata must be explicitly forwarded as an AJP -attribute. These AJP attributes become visible in the -``ServletRequest.getAttribute()`` method [1]_. - -The Apache ``mod_proxy_ajp`` module automatically sends any Apache -environment variable prefixed with "AJP\_" as an AJP attribute which -can be retrieved with ``ServletRequest.getAttribute()``. Therefore the -``mod_identity_lookup`` directives which specify the Apache environment -variable to set with the result of a lookup must be prefixed with -"AJP\_". Using the above example of looking up the principal's email -address we modify the environment variable to include the "AJP\_" -prefix. Thusly: - - :: - - <LocationMatch "my_resource"> - LookupUserAttr mail AJP_REMOTE_USER_EMAIL - </LocationMatch> - -The sequence of events is as follows: - - 1. When the URL matches "my_resource". - - 2. ``mod_identity_lookup`` retrieves the mail attribute for the - principal. - - 3. ``mod_identity_lookup`` assigns the value of the mail attribute - lookup to the AJP_REMOTE_USER_EMAIL Apache environment variable. - - 4. ``mod_proxy_ajp`` encodes AJP_REMOTE_USER_EMAIL environment - variable into an AJP attribute in the AJP protocol because the - environment variable is prefixed with "AJP\_". The name of the - attribute is stripped of it's "AJP\_" prefix thus the - AJP_REMOTE_USER_EMAIL environment variable is transferred as the - AJP attribute REMOTE_USER_EMAIL. - - 5. The request is forwarded (i.e. proxied) to servlet container - using the AJP protocol. - - 6. The servlet container's AJP ``Connector`` object is assigned each AJP - attribute to the set of attributes on the ``ServletRequest`` - attribute list. Thus a call to - ``ServletRequest.getAttribute("REMOTE_USER_EMAIL")`` yields the - value set by ``mod_identity_lookup``. - - -HTTP Exports -^^^^^^^^^^^^ - -When HTTP proxy is used there are no automatic or implicit metadata -transfers; every metadata attribute must be explicitly handled on both -ends of the proxy connection. All identity metadata attributes are -transferred as extension HTTP headers, by convention those headers are -prefixed with "X-SSSD-". - -Using the original example of looking up the principal's email -address we must now perform two independent actions: - - 1. Lookup the value via ``mod_identity_lookup`` and assign to an - Apache environment variable. - - 2. Export the environment variable in the request header with the - "X-SSSD-" prefix. - - :: - - <LocationMatch "my_resource"> - LookupUserAttr mail REMOTE_USER_EMAIL - RequestHeader set X-SSSD-REMOTE_USER_EMAIL %{REMOTE_USER_EMAIL}e - </LocationMatch> - -The sequence of events is as follows: - - 1. When the URL matches "my_resource". - - 2. ``mod_identity_lookup`` retrieves the mail attribute for the - principal. - - 3. ``mod_identity_lookup`` assigns the value of the mail attribute - lookup to the REMOTE_USER_EMAIL Apache environment variable. - - 4. Apache's RequestHeader directive executes just prior to the - request being forwarded (i.e. in the Apache fixup stage). It adds - the header X-SSSD-REMOTE_USER_EMAIL and assigns the value for - REMOTE_USER_EMAIL found in the set of environment variables. It - does this because the syntax %{XXX} is a variable reference for - the name XXX and the 'e' appended after the closing brace - indicates the lookup is to be performed in the set of environment - variables. - - 5. The request is forwarded (i.e. proxied) to the servlet container - using the HTTP protocol. - - 6. When ``ServletRequest.getAttribute()`` is called the ``SssdFilter`` - wrapper intercepts the ``getAttribute()`` method. It looks for an - HTTP header of the same name with "X-SSSD-" prefixed to it. In - this case ``getAttribute("REMOTE_USER_EMAIL")`` causes the lookup of - "X-SSSD-REMOTE_USER_EMAIL" in the HTTP headers, if found that - value is returned. - -AJP Proxy Example Configuration -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -If you are using AJP proxy to the Java EE Container on port 8383 your -``my_app.conf`` Apache configuration file will probably look like -this: - -:: - - <LocationMatch "my_resource"> - - ProxyPass / ajp://localhost:8383/ - ProxyPassReverse / ajp://localhost:8383/ - - LookupUserAttr mail AJP_REMOTE_USER_EMAIL " " - LookupUserAttr givenname AJP_REMOTE_USER_FIRSTNAME - LookupUserAttr sn AJP_REMOTE_USER_LASTNAME - LookupUserGroups AJP_REMOTE_USER_GROUPS ":" - - </LocationMatch> - -Note the specification of the colon separator for the -``LookupUserGroups`` operation. [3]_ - -HTTP Proxy Example Configuration -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -If you are using a conventional HTTP proxy to the Java EE Container on -port 8383 your ``my_app.conf`` Apache configuration file will probably -look like this: - -:: - - <LocationMatch "my_resource"> - - ProxyPass / http://localhost:8383/ - ProxyPassReverse / http://localhost:8383/ - - RequestHeader set X-SSSD-REMOTE_USER expr=%{REMOTE_USER} - RequestHeader set X-SSSD-AUTH_TYPE expr=%{AUTH_TYPE} - RequestHeader set X-SSSD-REMOTE_HOST expr=%{REMOTE_HOST} - RequestHeader set X-SSSD-REMOTE_ADDR expr=%{REMOTE_ADDR} - - LookupUserAttr mail REMOTE_USER_EMAIL - RequestHeader set X-SSSD-REMOTE_USER_EMAIL %{REMOTE_USER_EMAIL}e - - LookupUserAttr givenname REMOTE_USER_FIRSTNAME - RequestHeader set X-SSSD-REMOTE_USER_FIRSTNAME %{REMOTE_USER_FIRSTNAME}e - - LookupUserAttr sn REMOTE_USER_LASTNAME - RequestHeader set X-SSSD-REMOTE_USER_LASTNAME %{REMOTE_USER_LASTNAME}e - - LookupUserGroups REMOTE_USER_GROUPS ":" - RequestHeader set X-SSSD-REMOTE_USER_GROUPS %{REMOTE_USER_GROUPS}e - - </LocationMatch> - -Note the specification of the colon separator for the -``LookupUserGroups`` operation. [3]_ - - -Configure Java EE Container Proxy Connector -=========================================== - -The Java EE Container must be configured to listen for connections -from the Apache web server. A Java EE Container specifies connections -via a ``Connector`` object. A ``Connector`` **must** be dedicated -**exclusively** for handling authenticated requests from the Apache -web server. The reason for this is explained in `The Proxy -Problem`_. In addition ``ClaimAuthFilter`` needs to validate that any -request it processes originated from the trusted Apache instance. This -is accomplished by dedicating one or more ports exclusively for use by -the trusted Apache server and enumerating them in the -``secureProxyPorts`` configuration as explained in `Locking Down the -Apache to Java EE Container Channel`_ and `Declaring the Connector -Ports for Authentication Proxies`_. - -Configure Tomcat Proxy Connector --------------------------------- - -The Tomcat Java EE Container defines Connectors in its ``server.xml`` -configuration file. - -:: - - <Connector - address="127.0.0.1" - port="8383" - protocol="HTTP/1.1" - tomcatAuthentication="false" - connectionTimeout="20000" - redirectPort="8443" - /> - - -:address: - This should be the loopback address as explained `Locking Down the - Apache to Java EE Container Channel`_. - -:port: - In our examples we've been using port 8383 as the proxy port. The - exact port is not important but it must be consistent with the - Apache proxy port, the ``Connector`` declaration, and the port value - in ``secureProxyPorts``. - -:protocol: - As explained in `Transporting Identity Metadata from Apache to a - Java EE Servlet`_ you will need to decide if you are using HTTP or - AJP as the proxy protocol. In the example above the protocol is set - for HTTP, if you use AJP instead the protocol should instead be - "AJP/1.3". - -:tomcatAuthentication: - This boolean flag tells Tomcat whether Tomcat should perform - authentication on the incoming requests or not. Since authentication - is performed by Apache we do not want Tomcat to perform - authentication therefore this flag must be set to false. - -The AAA system needs to know which port(s) the trusted Apache proxy -will be sending requests on so it can trust the request authentication -metadata. See `Declaring the Connector Ports for Authentication -Proxies`_ for more information). Set ``secureProxyPorts`` in the -FederationConfiguration. - -:: - - secureProxyPorts=8383 - - -Configure Jetty Proxy Connector -------------------------------- - -The Jetty Java EE Container defines Connectors in its ``jetty.xml`` -configuration file. - -:: - - <!-- Trusted Authentication Federation proxy connection --> - <Call name="addConnector"> - <Arg> - <New class="org.eclipse.jetty.server.nio.SelectChannelConnector"> - <Set name="host">127.0.0.1</Set> - <Set name="port">8383</Set> - <Set name="maxIdleTime">300000</Set> - <Set name="Acceptors">2</Set> - <Set name="statsOn">false</Set> - <Set name="confidentialPort">8445</Set> - <Set name="name">federationConn</Set> - <Set name="lowResourcesConnections">20000</Set> - <Set name="lowResourcesMaxIdleTime">5000</Set> - </New> - </Arg> - </Call> - -:host: - This should be the loopback address as explained `Locking Down the - Apache to Java EE Container Channel`_. - -:port: - In our examples we've been using port 8383 as the proxy port. The - exact port is not important but it must be consistent with the - Apache proxy port, the ``Connector`` declaration, and the port value - in ``secureProxyPorts``. - - -Note, values in Jetty XML can also be parameterized so that they may -be passed from property files or set on the command line. Thus -typically the port is set within Jetty XML, but uses the Property -element to be customizable. Thus the above ``host`` and ``port`` -properties could be specificed this way: - -:: - - <Set name="host"> - <Property name="jetty.host" default="127.0.0.1"/> - </Set> - <Set name="port"> - <Property name="jetty.port" default="8383"/> - </Set> - - -The AAA system needs to know which port(s) the trusted Apache proxy -will be sending requests on so it can trust the request authentication -metadata. See `Declaring the Connector Ports for Authentication -Proxies`_ for more information). Set ``secureProxyPorts`` in the -FederationConfiguration. - -************************************************ -How Apache Identity Metadata is Processed in AAA -************************************************ - -`Figure 2.`_ and `Figure 3.`_ illustrates the fact the first stage in -processing a request from a user begins with Apache where the user is -authenticated and SSSD supplies additional metadata about the -user. The original request along with the metadata are subsequently -forwarded by Apache to the Java EE Container. `Figure 4.`_ illustrates -the processing inside the Java EE Container once it receives the -request on one of its secure connectors. - - -.. figure:: sssd_04.png - :align: center - - _`Figure 4.` - -:Step 1: - One or more Connectors have been configured to listen for requests - being forwarded from a trusted Apache instance. The Connector is - configured to communicate using either the HTTP or AJP protocols. - See `Exporting Environment Variables to the Proxy`_ for more - information on selecting a proxy transport protocol. - -:Step 2: - The identity metadata bound to the request needs to be extracted - differently depending upon whether HTTP or AJP is the transport - protocol. To allow later stages in the pipeline to be ignorant of - the transport protocol semantics the ``SssdFilter`` servlet filter - is introduced. The ``SssdFilter`` wraps the ``HttpServletRequest`` - class and intercepts calls which might return the identity - metadata. The wrapper in the filter looks in protocol specific - locations for the metadata. In this manner users of the - ``HttpServletRequest`` are isolated from protocol differences. - - -:Step 3: - - The ``ClaimAuthFilter`` is responsible for determining if identity - metadata is bound to the request. If so all identity metadata is - packaged into an assertion which is then handed off to - ``SssdClaimAuth`` which will transform the identity metadata in the - assertion into a AAA Claim which is the authorizing token for the user. - -:Step 4: - The ``SssdClaimAuth`` object is responsible for transforming the - external federated identity metadata provided by Apache and SSSD into - a AAA claim. The AAA claim is an authorization token which includes - information about the user plus a set of roles. These roles provide the - authorization to perform AAA tasks. Although how roles are assigned is - flexible the expectation is domain and/or group membership will be the - primary criteria for role assignment. Because deciding how to handle - external federated identity metadata is site and deployment specific - we need a loadable policy mechanism. This is accomplished by a set of - transformation rules which transforms the incoming IdP identity - metadata into a AAA claim. For greater clarity this important step is - broken down into smaller units in the shaded box in `Figure 4.`_. - -:Step 4.1: - `The Mapping Rule Processor`_ is designed to accept a JSON object - (set of key/value pairs) as input and emit a different JSON object - as output effectively operating as a transformation engine on - key/value pairs. - -:Step 4.2: - The input assertion is rewritten as a JSON object in the format - required by the Mapping Rule Processor. The JSON assertion is then - passed into the Mapping Rule Processor. - -:Step 4.3: - `The Mapping Rule Processor`_ identified as ``IdPMapper`` evaluates - the input JSON assertion in the context of the mapping rules defined - for the site deployment. If ``IdPMapper`` is able to successfully - transform the input it will return a JSON object which we called the - *mapped* result. If the input JSON assertion is not compatible with - the site specific rules loaded into the ``IdPMapper`` then NULL is - returned by the ``IdPMapper``. - -:Step 4.4: - If a mapped JSON object is returned by the ``IdPMapper`` the mapping - was successful. The values in the mapped result are re-written into - an AAA Claim token. - -How Apache Identity Metadata is Mapped to AAA Values -==================================================== - -A federated IdP supplies metadata in a form unique to the IdP. This is -called an assertion. That assertion must be transformed into a format -and data understood by AAA. More importantly that assertion needs to -yield *authorization roles specific to AAA*. In `Figure 4.`_ Step 4.3 -the ``IdPMapper`` provides the transformation from an external IdP -assertion to an AAA specific claim. It does this via a Mapping Rule -Processor which reads a site specific set of transformation -rules. These mapping rules define how to transform an external IdP -assertion into a AAA claim. The mapping rules also are responsible for -validating the external IdP claim to make sure it is consistent with -the site specific requirements. The operation of the Mapping Rule -Processor and the syntax of the mapping rules are defined in `The -Mapping Rule Processor`_. - -Below is an example mapping rule which might be loaded into the -Mapping Rule Processor. It is assumed there are two AAA roles which -may be assigned [4]_: - -``user`` - A role granting standard permissions for normal ODL users. - -``admin`` - A special role granting full administrative permissions. - -In this example assigning the ``user`` and ``admin`` roles -will be based on group membership in the following groups: - -``odl_users`` - Members of this group are normal ODL users with restricted permissions. - -``odl_admin`` - Members of this group are ODL administrators with permission to - perform all operations. - -Granting of the ``user`` and/or ``admin`` roles based on -membership in the ``odl_users`` and ``odl_admin`` is illustrated in -the follow mapping rule example which also extracts the user principal -and domain information in the preferred format for the site -(e.g. usernames are lowercase without domain suffixes and the domain -is uppercase and supplied separately). - -_`Mapping Rule Example 1.` - -:: - - 1 [ - 2 {"mapping": {"ClientId": "$client_id", - 3 "UserId": "$user_id", - 4 "User": "$username", - 5 "Domain": "$domain", - 6 "roles": "$roles", - 7 }, - 8 "statement_blocks": [ - 9 [ - 10 ["set", "$groups", []], - 11 ["set", "$roles", []] - 12 ], - 13 [ - 14 ["in", "REMOTE_USER", "$assertion"], - 15 ["exit", "rule_fails", "if_not_success"], - 16 ["regexp", "$assertion[REMOTE_USER]", "(?<username>\\w+)@(?<domain>.+)"], - 17 ["exit", "rule_fails", "if_not_success"], - 18 ["lower", "$username", "$regexp_map[username]"], - 19 ["upper", "$domain", "$regexp_map[domain]"], - 20 ], - 21 [ - 22 ["in", "REMOTE_USER_GROUPS", "$assertion"], - 23 ["exit", "rule_fails", "if_not_success"], - 24 ["split", "$groups", "$assertion[REMOTE_USER_GROUPS]", ":"], - 25 ], - 26 [ - 27 ["in", "odl_users", "$groups"], - 28 ["continue", "if_not_success"], - 29 ["append", "$roles", "user"], - 30 ], - 31 [ - 32 ["in", "odl_admin", "$groups"], - 33 ["continue", "if_not_success"], - 34 ["append", "$roles", "admin"] - 35 ], - 36 [ - 37 ["unique", "$roles", "$roles"], - 38 ["length", "$n_roles", "$roles"], - 39 ["compare", "$n_roles", ">", 0], - 40 ["exit", "rule_fails", "if_not_success"], - 41 ], - 42 ] - 43 } - 44 ] - -:Line 1: - Starts a list of rules. In this example only 1 rule is defined. Each - rule is a JSON object containing a ``mapping`` and a required list - of ``statement_blocks``. The ``mapping`` may either be specified - inside a rule as it is here or may be referenced by name in a table - of mappings (this is easier to manage if you have a large number of - rules and small number of mappings). - -:Lines 2-7: - Defines the JSON mapped result. Each key maps to AAA claim. The - value is a rule variable whose value will be substituted if the rule - succeeds. Thus for example the AAA claim value ``User`` will be - assigned the value from the ``$username`` rule variable. -:Line 8: - Begins the list of statement blocks. A statement must be contained - inside a block. -:Lines 9-12: - The first block usually initializes variables that will be - referenced later. Here we initialize ``$groups`` and ``$roles`` to - empty arrays. These arrays may be appended to in later blocks and - may be referenced in the final ``mapping`` output. -:Lines 13-20: - This block sets the user and domain information based on - ``REMOTE_USER`` and exits the rule if ``REMOTE_USER`` is not defined. -:Lines 14-15: - This test is critical, it assures ``REMOTE_USER`` is defined in the - assertion, if not the rule is skipped because we depend on - ``REMOTE_USER``. -:Lines 16-17: - Performs a regular expression match against ``REMOTE_USER`` to split - the username from the domain. The regular expression uses named - groups, in this instance ``username`` and ``domain``. If the regular - expression does not match the rule is skipped. -:Lines 18-19: - These lines reference the previous result of the regular expression - match which are stored in the special variable ``$regexp_map``. The - username is converted to lower case and stored in ``$username`` and - the domain is converted to upper case and stored in ``$domain``. The - choice of case is purely by convention and site requirements. -:Lines 21-35: - These 3 blocks assign roles based on group membership. -:Lines 21-25: - Assures ``REMOTE_USER_GROUPS`` is defined in the assertion; if not, the - rule is skipped. ``REMOTE_USER_GROUPS`` is colon separated list of group - names. In order to operate on the individual group names appearing - in ``REMOTE_USER_GROUPS`` line 24 splits the string on the colon - separator and stores the result in the ``$groups`` array. -:Lines 27-30: - This block assigns the ``user`` role if the user is a member of the - ``odl_users`` group. -:Lines 31-35: - This block assigns the ``admin`` role if the user is a - member of the ``odl_admin`` group. -:Lines 36-41: - This block performs final clean up actions for the rule. First it - assures there are no duplicates in the ``$roles`` array by calling - the ``unique`` function. Then it gets a count of how many items are - in the ``$roles`` array and tests to see if it's empty. If there are - no roles assigned the rule is skipped. -:Line 43: - This is the end of the rule. If we reach the end of the rule it - succeeds. When a rule succeeds the mapping associated with the rule - is looked up. Any rule variable appearing in the mapping is - substituted with its value. - -Using the rules in `Mapping Rule Example 1.`_ and following example assertion -in JSON format: - -_`Assertion Example 1.` - -:: - - { - "REMOTE_USER": "TestUser@example.com", - "REMOTE_AUTH_TYPE": "Negotiate", - "REMOTE_USER_GROUPS": "odl_users:odl_admin", - "REMOTE_USER_EMAIL": "test.user@example.com", - "REMOTE_USER_FIRSTNAME": "Test", - "REMOTE_USER_LASTNAME": "User" - } - -Then the mapper will return the following mapped JSON document. This -is the ``mapping`` defined on line 2 of `Mapping Rule Example 1.`_ with the -variables substituted after the rule successfully executed. Note any -valid JSON data type can be returned, in this example the ``null`` -value is returned for ``ClientId`` and ``UserId``, normal strings for -``User`` and ``Domain`` and an array of strings for the ``roles`` value. - -_`Mapped Result Example 1.` - -:: - - { - "ClientId": null, - "UserId": null, - "User": "testuser", - "Domain": "EXAMPLE.COM", - "roles": ["user", "admin"] - } - - -************************** -The Mapping Rule Processor -************************** - -The Mapping Rule Processor is designed to be as flexible and generic -as possible. It accepts a JSON object as input and returns a JSON -object as output. JSON was chosen because virtually all data can be -represented in JSON, JSON has extensive support and JSON is human -readable. The rules loaded into the Mapping Rule Processor are also -expressed in JSON. One advantage of this is it makes it easy for a -site administrator to define hardcoded values which are always -returned and/or static tables of white and black listed users or users -who are always mapped into certain roles. - -.. include:: mapping.rst - -*********************** -Security Considerations -*********************** - -Attack Vectors -============== - -A Java EE Container fronted by Apache has by definition 2 major -components: - -* Apache -* Java EE Container - -Each of these needs to be secure in its own right. There is extensive -documentation on securing each of these components and the reader is -encouraged to review this material. For the purpose of this discussion -we are most interested in how Apache and the Java EE -Container cooperate to form an integrated security system. Because -Apache is performing authentication on behalf of the Java EE Container, -it views Apache as a trusted partner. Our primary concern is the -communication channel between Apache and the Java EE Container. We -must assure the Java EE Container knows who it's trusted partner is -and that it only accepts security sensitive data from that partner, -this can best be described as `The Proxy Problem`_. - -Forged REMOTE_USER ------------------- - -HTTP request handling is often implemented as a processing pipeline -where individual handlers are passed the request, they may then attach -additional metadata to the request or transform it in some manner -before handing it off to the next stage in the pipeline. A request -handler may also short circuit the request processing pipeline and -cause a response to be generated. Authentication is typically -implemented an as early stage request handler. If a request gets past -an authentication handler later stage handlers can safely assume the -request belongs to an authenticated user. Authorization metadata may -also have been attached to the request. Later stage handlers use the -authentication/authorization metadata to make decisions as to whether -the operations in the request can be satisfied. - -When a request is fielded by a traditional web server with CGI (Common -Gateway Interface, RFC 3875) the request metadata is passed via CGI -meta-variables. CGI meta-variables are often implemented as environment -variables, but in practical terms CGI metadata is really just a set of -name/value pairs a later stage (i.e. CGI script, servlet, etc.) can -reference to learn information about the request. - -The CGI meta-variables REMOTE_USER and AUTH_TYPE relate to -authentication. REMOTE_USER is the identity of the authenticated user -and AUTH_TYPE is the authentication mechanism that was used to -authenticate the user. - -**If a later stage request handler sees REMOTE_USER and AUTH_TYPE as -non-null values it assumes the user is fully authenticated! Therefore -is it essential REMOTE_USER and AUTH_TYPE can only enter the request -pipeline via a trusted source.** - -The Proxy Problem -================= - -In a traditional monolithic web server the CGI meta-variables are -created and managed by the web server, which then passes them to CGI -scripts and executables in a very controlled environment where they -execute in the context of the web server. Forgery of CGI -meta-variables is generally not possible unless the web server has -been compromised in some fashion. - -However in our configuration the Apache web server acts as an identity -processor, which then forwards (i.e. proxies) the request to the Java -EE container (i.e Tomcat, Jetty, etc.). One could think of the Java -EE container as just another CGI script which receives CGI -meta-variables provided by the Apache web server. Where this analogy -breaks down is how Apache invokes the CGI script. Instead of forking a -child process where the child's environment and input/output pipes are -carefully controlled by Apache the request along with its additional -metadata is forwarded over a transport (typically TCP/IP) to another -process, the proxy, which listens on socket. - -The proxy (in this case the Java EE container) reads the request and -the attached metadata and acts upon it. If the request read by the -proxy contains the REMOTE_USER and AUTH_TYPE CGI meta-variables the -proxy will consider the request **fully authenticated!**. Therefore -when the Java EE container is configured as a proxy it is -**essential** it only reads requests from a **trusted** Apache web -server. If any other client aside from the trusted Apache web server -is permitted to connect to the Java EE container that client could -present forged REMOTE_USER and AUTH_TYPE meta-variables, which would be -automatically accepted as valid thus opening a huge security hole. - - -Possible Approaches to Lock Down a Proxy Channel -================================================ - -Tomcat Valves -------------- - -You can use a `Tomcat Remote Address Valve`_ valve to filter by IP or -hostname to only allow a subset of machines to connect. This can be -configured at the Engine, Host, or Context level in the -conf/server.xml by adding something like the following: - -:: - - <!-- allow only LAN IPs to connect --> - <Valve className="org.apache.catalina.valves.RemoteAddrValve" - allow="192.168.1.*"> - </Valve> - -The problem with valves is they are a Tomcat only concept, the -``RemoteAddrValve`` only checks addresses, not port numbers (although -it should be easy to add port checking) and they don't offer anything -better than what is described in `Locking Down the Apache to Java EE -Container Channel`_, which is not container specific. Servlet filters -are always available regardless of the container the servlet is -running in. A filter can check both the address and port number and -refuse to operate on the request if the address and port are not known to -be a trusted authentication proxy. Also note that if the Java EE -Container is configured to accept connections other than from the -trusted HTTP proxy server (a very likely scenario) then filtering at -the connector level is not sufficient because a servlet which trusts -``REMOTE_USER`` must be assured the request arrived only on a -trusted HTTP proxy server connection, not one of the other possible -connections. - -SSL/TLS with client auth ------------------------- - -SSL with client authentication is the ultimate way to lock down a HTTP -Server to Java EE Container proxy connection. SSL with client -authentication provides authenticity, integrity, and -confidentiality. However those desirable attributes come at a -performance cost which may be excessive. Unless a persistent TCP -connection is established between the HTTP server and the Java EE -Container a SSL handshake will need to occur on each request being -proxied, SSL handshakes are expensive. Given that the HTTP server and -the Java EE Container will likely be deployed on the same compute node -(or at a minimum on a secure subnet) the advantage of SSL for proxy -connections may not be warranted because other options are available -for these configuration scenarios; see `Locking Down the Apache to Java EE -Container Channel`_. Also note that if the Java EE -Container is configured to accept connections other than from the -trusted HTTP proxy server (a very likely scenario), then filtering at -the connector level is not sufficient because a servlet which trusts -``REMOTE_USER`` must be assured that the request arrived only on a -trusted HTTP proxy server connection, not one of the other possible -connections. - - -Java Security Manager Permissions ---------------------------------- - -The Java Security Manager allows you define permissions which are -checked at run time before code executes. -``java.net.SocketPermission`` and ``java.net.NetPermission`` would -appear to offer solutions for restricting which host and port a -request containing ``REMOTE_USER`` will be trusted. However security -permissions are applied *after* a request is accepted by a -connector. They are also more geared towards what connections code can -subsequently utilize as opposed to what connection a request was -presented on. Therefore security manager permissions seem to offer little -value for our purpose. One can simply test to see which host sent the -proxy request and on what port it arrived on by looking at the -connection information in the request. Restricting which proxies can -submit trusted requests is better handled at the level of the -connector, which unfortunately is a container implementation -issue. Tomcat and Jetty have different ways of handling connector -specifications. - -AJP requiredSecret ------------------- - -The AJP protocol includes an attribute called ``requiredSecret``, which -can be used to secure the connection between AJP endpoints. When an -HTTP server sends an AJP proxy request to a Java EE Container it -embeds in the protocol transmission a string (``requiredSecret``) -known only to the HTTP server and the Java EE Container. The AJP -connector on the Java EE Container is configured with the -``requiredSecret`` value and will reject as unauthorized any AJP -requests whose ``requiredSecret`` does not match. - -There are two problems with `requiredSecret``. First of all it's not -particularly secure. In fact, it's fundamentally no different than -sending a cleartext password. If the AJP request is not encrypted it -means the ``requiredSecret`` will be sent in the clear which is -probably one of the most egregious security mistakes. If the AJP -request is transmitted in a manner where the traffic can be sniffed, it -would be trivial to recover the ``requiredSecret`` and forge a request -with it. On the other hand encrypting the communication channel -between the HTTP server and the Java EE Container means using SSL -which is fairly heavyweight. But more to the point, if one is using -SSL to encrypt the channel there is a *far better* mechanism to ensure -the HTTP server is who it claims to be than embedding -``requiredSecret``. If one is using SSL you might as well use SSL -client authentication where the HTTP identifies itself via a client -certificate. SSL client authentication is a very robust authentication -mechanism. But doing SSL client authentication, or for that matter -just SSL encryption, for *every* AJP protocol request is prohibitively -expensive from a performance standpoint. - -The second problem with ``requiredSecret`` is that despite being documented -in a number of places it's not actually implemented in Apache -``mod_proxy_ajp``. This is detailed in `bug 53098`_. You can set -``requiredSecret`` in the ``mod_proxy_ajp`` configuration, but it won't -be included in the wire protocol. There is a patch to implement -``requiredSecret`` but, it hasn't made it into any shipping version of -Apache yet. But even if ``requiredSecret`` was implemented it's not -useful. Also one could construct the equivalent of ``requiredSecret`` -from other AJP attributes and/or an HTTP extension header but those -would suffer from the same security issues ``requiredSecret`` has, -therefore it's mostly pointless. - -Java EE Container Issues -======================== - -Jetty Issues ------------- - -Jetty is a Java EE Container which can be used -as alternative to Tomcat. Jetty is an Eclipse project. Recent versions -of Jetty have dropped support for AJP; this is described in the -`Jetty AJP Configuration Guide`_ which states: - - Configuring AJP13 Using mod_jk or mod_proxy_ajp. Support for this - feature has been dropped with Jetty 9. If you feel this should be - brought back please file a bug. - -Eclipse `Bug 387928`_ *Retire jetty-ajp* was opened to track the -removal of AJP in Jetty and is now closed. - -Tomcat Issues -------------- - -You should refer the `Tomcat Security How-To`_ for a full discussion -of Tomcat security issues. - -The tomcatAuthentication attribute is used with the AJP connectors to -determine if Tomcat should authenticate the user or if authentication -can be delegated to the reverse proxy that will then pass the -authenticated username to Tomcat as part of the AJP protocol. - -The requiredSecret attribute in AJP connectors configures a shared -secret between Tomcat and the reverse proxy in front of Tomcat. It is used -to prevent unauthorized connections over AJP protocol. - -Locking Down the Apache to Java EE Container Channel -==================================================== - -The recommended approach to lock down the proxy channel is: - - * Run both Apache and the servlet container on the same host. - - * Configure Apache to forward the proxy request on the loopback - interface (e.g. 127.0.0.1 also known as ``localhost``). This - prohibits any external IP address from connecting, only processes - running on the locked down host can communicate over - ``localhost``. - - * Reserve one or more ports for communication **exclusively** for - proxy communication between Apache and the servlet container. The - servlet container may listen on other ports for non-critical - non-authenticated requests. - - * The ``ClaimAuthFilter`` that reads the identity metadata **must** - assure that requests have arrived only on a **trusted port**. To - achieve this the ``FederationConfiguration`` defines the - ``secureProxyPorts`` configuration option. ``secureProxyPorts`` is - a space delimited list of ports which during deployment the - administrator has configured such that they are **exclusively** - dedicated for use by the Apache server(s) providing authentication - and identity information. These ports are set in the servlet - container's ``Connector`` declarations. See `Declaring the - Connector Ports for Authentication Proxies`_ for more - information). - - * When the ``ClaimAuthFilter`` receives a request, the first thing - it does is check the ``ServletRequest.getLocalPort()`` value and - verifies it is a member of the ``secureProxyPorts`` configuration - option. If the port is a member of ``secureProxyPorts``, it will - trust every identity assertion found in the request. If the local - port is not a member of ``secureProxyPorts``, a HTTP 401 - (unauthorized) error status will be returned for the request. A - warning message will be logged the first time this occurs. - - -Declaring the Connector Ports for Authentication Proxies --------------------------------------------------------- - -As described in `The Proxy Problem`_ the AAA authentication system -**must** confirm the request it is processing originated from a *trusted -HTTP proxy server*. This is accomplished with port isolation. - -The administrator deploying a federated AAA solution with SSSD -identity lookups must declare in the AAA federation configuration -which ports the proxy requests from the trusted HTTP server will -arrive on by setting the ``secureProxyPorts`` configuration -item. These ports **must** only be used for the trusted HTTP proxy -server. The AAA federation software will not perform authentication -for any request arriving on a port other than those listed in -``secureProxyPorts``. - -.. figure:: sssd_05.png - :align: center - - _`Figure 5.` - -``secureProxyPorts`` configuration option is set either in the -``federation.cfg`` file or in the -``org.opendaylight.aaa.federation.secureProxyPorts`` bundle -configuration. ``secureProxyPorts`` is a space-delimited list of port -numbers on which a trusted HTTP proxy performing authentication -forwards pre-authenticated requests. For example: - -:: - - secureProxyPorts=8383 - -Means a request which arrived on port 8383 is from a trusted HTTP -proxy server and the value of ``REMOTE_USER`` and other authentication -metadata in request can be trusted. - -######## -Appendix -######## - -***************** -CGI Export Issues -***************** - -Apache processes requests as a series of steps in a pipeline -fashion. The ordering of these steps is important. Core Apache is -fairly minimal, most of Apache's features are supplied by loadable -modules. When a module is loaded it registers a set of *hooks* -(function pointers) which are to be run at specific stages in the -Apache request processing pipeline. Thus a module can execute code at -any of a number of stages in the request pipeline. - -The user metadata supplied by Apache is initialized in two distinct -parts of Apache. - - 1. an authentication module (e.g. mod_auth_kerb) - 2. the ``mod_lookup_identity`` module. - -After successful authentication the authentication module will set the -name of the user principal and the mechanism used for authentication -in the request structure. - - * ``request->user`` - * ``request->ap_auth_type`` - -Authentication hooks run early in the request pipeline for the obvious -reason a request should not be processed if not authenticated. The -specific authentication module that runs is defined by ``Location`` -directive in the Apache configuration which binds specific -authentication to specific URL's. The ``mod_lookup_identity`` module -must run *after* authentication module runs because it depends on -knowing who the authenticated principal is so it can lookup the data -on that principal. - -When reading ``mod_lookup_identity`` documentation one often sees -references to the ``REMOTE_USER`` CGI environment variable with the -implication ``REMOTE_USER`` is how one accesses the name of the -authenticated principal. This is a bit misleading, ``REMOTE_USER`` is -a CGI environment variable. CGI environment variables are only set by -Apache when it believes the request is going to be processed by a CGI -implementation. In this case ``REMOTE_USER`` is initialized from the -``request->user`` value. - -How is the authenticated principal actually forwarded to our proxy? -=================================================================== - -If we are using the AJP proxy protocol the ``mod_proxy_ajp`` module -when preparing the proxy request will read the value of -``request->user`` and insert it into the ``SC_A_REMOTE_USER`` AJP -attribute. On the receiving end ``SC_A_REMOTE_USER`` will be extracted -from the AJP request and used to populate the value returned -by``HttpServletRequest.getRemoteUser()``. The exchange of the -authenticated principal when using AJP is transparent to both the -sender and receiver, nothing special needs to be done. See -`Transporting Identity Metadata from Apache to a Java EE Servlet`_ -for details on how metadata can be exchanged with the proxy. - -However, if AJP is not being used to proxy the request the -authenticated principal must be passed through some other mechanism, -an HTTP extension header is the obvious solution. The Apache -``mod_headers`` module can be used to add HTTP request headers to the -proxy request, for example: - -:: - - RequestHeader set MY_HEADER MY_VALUE - -Where does the value MY_VALUE come from? It can be hardcoded into the -``RequestHeader`` statement or it can reference an existing -environment variable like this: - -:: - - RequestHeader set MY_HEADER %{FOOBAR}e - -where the notation ``%{FOOBAR}e`` is the contents of the environment -variable FOOBAR. Thus we might expect we could do this: - -:: - - RequestHeader set REMOTE_USER %{REMOTE_USER}e - -The conundrum is the presumption the ``REMOTE_USER`` environment -variable has already been set at the time ``mod_headers`` executes the -``RequestHeader`` statement. Unfortunately this often is not the -case. - -The Apache environment variables ``REMOTE_USER`` and ``AUTH_TYPE`` are -set by the Apache function ``ap_add_common_vars()`` defined in -server/util_script.c. ``ap_add_common_vars()`` and is called by the -following modules: - - * mod_authnz_fcgi - * mod_proxy_fcgi - * mod_proxy_scgi - * mod_isapi - * mod_ext_filter - * mod_include - * mod_cgi - * mod_cgid - -Apache variables -================ - -Apache modules provide access to variables which can be referenced by -configuration directives. Unfortunately there isn't a lot of -uniformity to what the variables are and how they're referenced; it -mostly depends on how a given Apache module was implemented. As you -might imagine a bit of inconsistent historical cruft has accumulated -over the years, it can be confusing. The Apache Foundation is trying -to clean some of this up bringing uniformity to modules by utilizing -the common ``expr`` (expression) module `ap_expr`_. The idea being modules will -forgo their home grown expression syntax with its numerous quirks and -instead expose the common ``expr`` language. However this is a work in -progress and at the time of this writing only a few modules have acquired -``expr`` expression support. - -Among the existing Apache modules there currently are three different -sets of variables. - - 1. Server variables. - 2. Environment variables. - 3. SSL variables. - -Server variables (item 1) are names given to internal values. The set -of names for server variables and what they map to are defined by the -module implementing the server variable lookup. For example -``mod_rewrite`` has its own variable lookup implementation. - -Environment variables (item 2) are variables *exported* to a -subprocess. Internally they are stored in -``request->subprocess_env``. The most common use of environment -variables exported to a subprocess are the CGI variables. - -SSL variables are connection specific values describing the SSL -connection. The lookup is implemented by ``ssl_var_lookup()``, which -given a variable name looks in a variety of internal data structures to -find the matching value. - -The important thing to remember is **server variables != environment -variables**. This can be confusing because they often share the same -name. For example, there is the server variable ``REMOTE_USER`` and -there is the environment variable ``REMOTE_USER``. The environment -variable ``REMOTE_USER`` only exists if some module has called -``ap_add_common_vars()``. To complicate matters, some modules allow you -to access *server variables*, other modules allow you to access -*environment variables* and some modules provide access to both -*server variables* and *environment variables*. - -Coming back to our goal of setting an HTTP extension header to the -value of ``REMOTE_USER``, we observe that ``mod_headers`` provides the -needed ``RequestHeader`` operation to set a HTTP header in the -request. Looking at the documentation for ``RequestHeader`` we see a -value can be specified with one of the following lookups: - -%{VARNAME}e - The contents of the environment variable VARNAME. - -%{VARNAME}s - The contents of the SSL environment variable VARNAME, if mod_ssl is enabled. - -But wait! This only gives us access to *environment variables* and the -``REMOTE_USER`` environment variable is only set if -``ap_add_common_vars()`` is called by a module **after** an -authentication module runs! ``ap_add_common_vars()`` is usually only -invoked if the request is going to be passed to a CGI script. But -we're not doing CGI; instead we're proxying the request. The -likelihood the ``REMOTE_USER`` environment variable will be set is -quite low. See `Setting the REMOTE_USER environment variable`_. - -``mod_headers`` is the only way to set a HTTP extension header and -``mod_headers`` only gives you access to environment variables and the -``REMOTE_USER`` environment variable is not set. Therefore if we're -not using AJP and must depend on setting a HTTP extension header for -``REMOTE_USER``, we have a **serious problem**. - -But there is a solution; you can either try the machinations described -in `Setting the REMOTE_USER environment variable`_ or assure you're -running at least Apache version 2.4.10. In Apache 2.4.10 the -``mod_headers`` module added support for `ap_expr`_. `ap_expr`_ -provides access to *server variables* by using the ``%{VARIABLE}`` -notation. `ap_expr`_ also can lookup subprocess environment variables -and operating system environment variables using its ``reqenv()`` and -``osenv()`` functions respectively. - -Thus the simple solution for exporting the ``REMOTE_USER`` HTTP -extension header if you're running Apache 2.4.10 or later is: - -:: - - RequestHeader set X-SSSD-REMOTE_USER expr=%{REMOTE_USER} - -The ``expr=%{REMOTE_USER}`` in the above statement says pass -``%{REMOTE_USER}`` as an expression to `ap_expr`_, evaluate the -expression and return the value. In this case the expression -``%{REMOTE_USER}`` is very simple, just the value of the server -variables ``REMOTE_USER``. Because ``RequestHeader`` runs after -authentication ``request->user`` will have been set. - -Setting the REMOTE_USER environment variable -============================================ - -If you do a web search on how to export ``REMOTE_USER`` in a HTTP -extension header for a proxy you will discover this is a common -problem that has frustrated a lot of people [2]_. The usual advice seems to -be to use ``mod_rewrite`` with a look-ahead. In fact this is even -documented in the `mod_rewrite documentation for REMOTE_USER`_ which says: - - %{LA-U:variable} can be used for look-aheads which perform an - internal (URL-based) sub-request to determine the final value of - variable. This can be used to access variable for rewriting which is - not available at the current stage, but will be set in a later - phase. - - For instance, to rewrite according to the REMOTE_USER variable from - within the per-server context (httpd.conf file) you must use - %{LA-U:REMOTE_USER} - this variable is set by the authorization - phases, which come after the URL translation phase (during which - mod_rewrite operates). - -One suggested solution is this: - -:: - - RewriteCond %{LA-U:REMOTE_USER} (.+) - RewriteRule .* - [E=RU:%1] - RequestHeader set X_REMOTE_USER %{RU}e - -1. The RewriteCond with the %{LA-U:} construct performs an internal - redirect to obtain the value of ``REMOTE_USER`` *server variable*, - if that value is non-empty because the (.+) regular expression - matched the rewrite condition succeeds and the following - RewriteRule executes. - -2. The RewriteRule executes, the first parameter is a pattern, the - second parameter is the replacement which can be followed by - optional flags inside brackets. The .* pattern is a regular - expression that matches anything, the - replacement is a special - value which indicates no replacement is to be performed. In other - words the pattern and replacement are no-ops and the RewriteRule is - just being used for it's side effect defined in the flags. The - E=NAME:VALUE notation says set the NAME environment variable to - VALUE. In this case the environment variable is RU and the value is - %1. The documentation for RewriteRule tells us that %N are - back-references to the last matched RewriteCond pattern, in this - case it's the value of ``REMOTE_USER``. - -3. Finally ``RequestHeader`` sets the request header - ``X_REMOTE_USER`` to the value of the ``RU`` environment variable. - -Another suggested solution is this: - -:: - - RewriteRule .* - [E=REMOTE_USER:%{LA-U:REMOTE_USER}] - -The Problem with mod_rewrite lookahead --------------------------------------- - -I **do not recommend** using mod_rewrite's lookahead to gain access to -authentication data values. Although the above suggestions will work -to get access to ``REMOTE_USER`` it is *extremely inefficient* because -it causes Apache to reprocess the request with an internal -redirect. The documentation suggests a lookahead reference will cause -one internal redirect. However from examining Apache debug logs the -``mod_rewite`` lookahead caused ``mod_lookup_identity`` to be invoked -**11 times** while handling one request. If the ``mod_rewrite`` -lookahead is removed and another technique is used to get access to -``REMOTE_USER`` then ``mod_lookup_identity`` is invoked exactly once -as expected. - -But it's not just ``REMOTE_USER`` which we need access to, we also need -to reference ``AUTH_TYPE`` which has the identical issues associated -with ``REMOTE_USER``. If an equivalent ``mod_rewrite`` block is added -to the configuration for ``AUTH_TYPE`` so that both ``REMOTE_USER`` -and ``auth_type`` are resolved using a lookahead Apache appears to go -into an infinite loop and the request stalls. - -I tried to debug what was occurring when Apache was configured this way -and why it seemed to be executing the same code over and over but I -was not able to figure it out. My conclusion is **using mod_rewrite -lookahead's is not a viable solution!** Other web posts also make -reference to the inefficiency but they seem to be unaware of just how -bad it is. - -.. [1] - Tomcat has a bug/feature, not all attributes are enumerated by - getAttributeNames() therefore getAttributeNames() cannot be used to - obtain the full set of attributes. However if you know the name of - the attribute a priori you can call getAttribute() and obtain the - value. Therefore we maintain a list of attribute names - (httpAttributes) which will be used to call getAttribute() with so we - don't miss essential attributes. - - This is the Tomcat bug, note it is marked WONTFIX. Bug 25363 - - request.getAttributeNames() not working properly Status: RESOLVED - WONTFIX https://issues.apache.org/bugzilla/show_bug.cgi?id=25363 - - The solution adopted by Tomcat is to document the behavior in the - "The Apache Tomcat Connector - Reference Guide" under the JkEnvVar - property where is says: - - You can retrieve the variables on Tomcat as request attributes via - request.getAttribute(attributeName). Note that the variables send via - JkEnvVar will not be listed in request.getAttributeNames(). - -.. [2] - Some examples of posts concerning the export of ``REMOTE_USER`` include: - http://www.jaddog.org/2010/03/22/how-to-proxy-pass-remote_user/ and - http://serverfault.com/questions/23273/apache-proxy-passing-on-remote-user-to-backend-server/ - -.. [3] - The ``mod_lookup_identity`` ``LookupUserGroups`` option accepts an - optional parameter to specify the separator used to separate group - names. By convention this is normally the colon (:) character. In - our examples we explicitly specify the colon separator because the - mapping rules split the value found in ``REMOTE_USER_GROUPS`` on - the colon character. - -.. [4] - The example of using the `The Mapping Rule Processor`_ to establish - the set of roles assigned to a user based on group membership is - for illustrative purposes in order to show features of the - federated IdP and mapping mechanism. Role assignment in AAA may be - done in other ways. For example an unscoped token without roles can - be used to acquire a scoped token with roles by presenting it to - the appropriate REST API endpoint. In actual deployments this may - be preferable because it places the responsibility of deciding who - has what role/permission on what part of the controller/network - resources more in the hands of the SDN controller administrator - than the IdP administrator. - -.. _FreeIPA: http://www.freeipa.org/ - -.. _SSSD: https://fedorahosted.org/sssd/ - -.. _mod_identity_lookup: http://www.adelton.com/apache/mod_lookup_identity/ - -.. _AJP: http://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html - -.. _Tomcat Security How-To: http://tomcat.apache.org/tomcat-7.0-doc/security-howto.html - -.. _The Apache Tomcat Connector - Generic HowTo: http://tomcat.apache.org/connectors-doc/generic_howto/printer/proxy.html - -.. _CGI RFC: http://www.ietf.org/rfc/rfc3875 - -.. _ap_expr: http://httpd.apache.org/docs/current/expr.html - -.. _mod_rewrite documentation for REMOTE_USER: http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritecond - -.. _bug 53098: https://issues.apache.org/bugzilla/show_bug.cgi?id=53098 - -.. _Jetty AJP Configuration Guide: http://wiki.eclipse.org/Jetty/Howto/Configure_AJP13 - -.. _Bug 387928: https://bugs.eclipse.org/bugs/show_bug.cgi?id=387928 - -.. _Tomcat Remote Address Valve: http://tomcat.apache.org/tomcat-7.0-doc/config/valve.html#Remote_Address_Filter |