ZXID.org Identity Management toolkit implements standalone SAML 2.0 and Liberty ID-WSF 2.0 stacks and aims at implementing all popular federation and ID Web Services protocols. Other more general documents are available, here we document the "simple" API which is good for most Single Sign-On use cases. Other APIs described elsewhere may be more appropriate for other use cases. The ZXID Simple API is the most stable API available for the SSO functionality.
The ZXID library provides two main APIs: the Simple and the Raw. The ZXID Simple API is meant to get you going with minimal understanding about SAML or SSO. It tries to encapsulate as much of the control flow as possible. You only need to learn this API, not the underlying protocol.
If you do not want to program or learn any API at all, you should look at the Apache module mod_auth_saml which will, in 80% of the cases, give all the benefits with the minimal effort of just configuring your web server.
mod_auth_saml Apache module documentation: SSO without programming.
zxid_simple() Easy API for SAML
ZXID Raw API: Program like the pros (and fix your own problems). See also Function Reference
ZXID ID-WSF API: Make Identity Web Services Calls using ID-WSF
ZXID Compilation and Installation: Compile and install from source or package. See also INSTALL.zxid for quick overview.
ZXID Configuration Reference: Nitty gritty on all options.
ZXID Circle of Trust Reference: How to set up the Circle of Trust, i.e. the partners your web site works with.
ZXID Logging Reference: ZXID digitally signed logging facility
javazxid: Using ZXID from Java
Net::SAML: Using ZXID from Perl
php_zxid: Using ZXID from PHP
zxididp: Using ZXID IdP and Discovery
README.smime: Crypto and Cert Tutorial
FAQ: Frequently Asked Questions
README.zxid: ZXID project overview
Consider the following "Hello World" SSO CGI example in C
(the zxid_simple() API is available in all language bindings):
01 #include <zx/zxid.h>
02 #define CONF "PATH=/var/zxid/&URL=https://sp1.zxidsp.org:8443/zxid"
03 void main() {
04 char* res = zxid_simple(CONF, 0, 255);
05 switch (res[0]) {
06 case 'd': /* Logged in case */
07 my_parse_ldif(res);
08 my_render_content();
09 exit(0);
10 default:
11 ERR("Unknown zxid_simple() response(%s)", res);
12 }
13 }
What happens here:
The CGI script calls zxid_simple() to handle SAML protocol according to the configuration
The last argument with value 255 tells zxid_simple() to automatically handle redirections, login screen and any other protocol interaction needed to make SSO happen.
If zxid_simple() returns, we have either succeeded in SSO or we have failed (all other cases are handled internally by zxid_simple() which calls exit(2) so it never returns).
In the success case, zxid_simple() returns an LDIF entry (as a nul terminated C string) describing the SSO and the attributes received. For example
dn: idpnid=Pa45XAs2332SDS2asFs,affid=https://idp.demo.com/idp.xml
objectclass: zxidsession
affid: https://idp.demo.com/idp.xml
idpnid: Pa45XAs2332SDS2asFs
authnctxlevel: password
sesid: S12aF3Xi4A
cn: Joe Doe
where
LDAP distinguished name (part of LDIF format). Always first.
Part of LDIF format.
Specifies which IdP was used for SSO
The federated ID, or pseudonym (IdP assigned NameID)
Rough indication of how IdP authenticated user
Session ID, as may be stored in cookie or used for file name in the session cache (/var/zxid/ses)
If this field is not empty and not equal to '-' (single dash), then the controlling application should take the necessary actions to set the cookie as specified. Namely, the controlling application should create 'Set-Cookie' HTTP response header whose value is the value of the setcookie field. How this is done is environment dependent.
The ZXIDSES (or other, as configured) cookie value. For reference.
Common Name. This attribute just exemplifies how any additional attributes the IdP may have set will appear. Typically the LDAP attribute names are used.
The dn line will always be the first. All other lines may appear in any order. String representation of LDIF was chosen as it is easy to parse in most programming languages.
The zxid_simple() can be configured in the following ways (later ways can override earlier ones).
Built in default configuration
Configuration file, usually /var/zxid/zxid.conf, if any
Configuration string passed as first argument. While configuration string can override all other options (i.e. it is processed last), the PATH specification is parsed before the configuration file is looked up.
Turns out that often the default configuration modified by the configurations string is all you need - you do not need to prepare configuration file.
See section "Configuring and Running" for complete list of configuration options, but generally it is sufficient to specify only a handful:
Where files are kept and configuration file is found.
The URL of the SP
The Common Domain URL (optional, if omitted the Common Domain Cookie processing is disabled)
The auto_flags argument allows you to control which operations should be performed automatically and which should be passed to the calling application, see "Gaining More Control" section, below, for full description of this case.
The auto options can be added together.
Table 1:zxid_simple() AUTO options
| Dec | Hex | Symbol | Description |
|---|---|---|---|
| 1 | 0x01 | ZXID_AUTO_EXIT | Call exit(), 0=return "n", even if auto CGI |
| 2 | 0x02 | ZXID_AUTO_REDIR | Automatic. handle redirects, assume CGI (calls exit(2)) |
| 4 | 0x04 | ZXID_AUTO_SOAPC | SOAP response handling, content gen |
| 8 | 0x08 | ZXID_AUTO_SOAPH | SOAP response handling, header gen |
| 16 | 0x10 | ZXID_AUTO_METAC | Metadata response handling, content gen |
| 32 | 0x20 | ZXID_AUTO_METAH | Metadata response handling, header gen |
| 64 | 0x40 | ZXID_AUTO_LOGINC | IdP select / Login page handling, content gen |
| 128 | 0x80 | ZXID_AUTO_LOGINH | IdP select / Login page handling, header gen |
| 256 | 0x100 | ZXID_AUTO_MGMTC | Management page handling, content gen |
| 512 | 0x200 | ZXID_AUTO_MGMTH | Management page handling, header gen |
| 1024 | 0x400 | ZXID_AUTO_FORMF | In idp list and mgmt screen, generate form fields |
| 2048 | 0x800 | ZXID_AUTO_FORMT | In idp list & mgmt screen, wrap in |
| 4095 | 0xfff | ZXID_AUTO_ALL | Enable all automatic CGI behaviour. |
| 4096 | 0x1000 | ZXID_AUTO_DEBUG | Enable debugging output to stderr. |
| 8192 | 0x2000 | ZXID_AUTO_OFMTQ | Output Format Query String |
| 16384 | 0x4000 | ZXID_AUTO_OFMTJ | Output Format JSON |
If the AUTO_REDIR flag is true, the LOCATION header is sent to stdout and exit(0) may be called, depending on the AUTO_NOEXIT flag.
The SOAP, META, LOGIN, and MGMT flags follow convention:
HC
00 No automation. Only action letter is returned ("e"=login, "b"=meta, etc.)
01 Content, not wrapped in headers, is returned as a string
10 Headers and content is returned as a string
11 Headers and content are sent to stdout, CGI style and
exit(0) may be called, depending on AUTO_EXIT. Otherwise "n" is returned.
Whether exit(0) is called in 11 case depends on ZXID_AUTO_NOEXIT flag.
How much HTML is generated for Login page and Mgmt page in 01 (content only) mode depends on AUTO_PAGE and AUTO_FORM flags
TF 00 reserved / nothing is generated 01 Only form fields (but not form tag itself) are generated. 10 Complete form is generated 11 Whole page is generated (best support)
The output format in the successful SSO case depends on OFMT bits as follows
JQ == 00 LDIF (default) 01 Query String 10 JSON 11 Reserved
When whole page is generated, some templating information is taken from the configuration.
All the HTML before
The HTML fragment to allow login using a new IdP (Auto CoT using IdP URL). Set to empty to hide this possibility.
Message displaying SP Entity ID, in case (technically minded) user needs to know this to establish relationship with an IdP.
Technical parameters that user might want to set, and typically would be allowed to set. May be hidden (not user controllable) or visible.
Create federation (AllowCreate flag)
Name ID format
Persistent (pseudonym)
Transient, temporary pseudonym
Technical parameters that the site administrator should decide and set. Usually hidden fields:
Affiliation ID (usually empty)
Consent obtained by SP for the federation or SSO
No statement about consent
Has been obtained (unspecified way)
Obtained prior to present transaction, e.g. user signed terms and conditions of service
Consent is implicit in the situation where user came to invoke service
Obtained explicitly
Consent can not be obtained
Obtaining consent is not relevant for the SP or service.
Authentication Context (strength of authentication) needed by the SP
Matching rule for authentication strength (usually empty, IdP decides)
Forbid IdP from interacting with the user (IsPassive flag)
Request reauthentication of user (ForceAuthn flag)
The fully automated interface works well for CGI deployment but probably is not appropriate in more complex situations. You can use zxid_simple() without automation and prevent it from accessing the system layer too directly. Consider
01 #define CONF "PATH=/var/zxid/&URL=https://sp1.zxidsp.org:8443/zxid"
02 int main() {
03 char* res;
04 res = zxid_simple(CONF, getenv("QUERY_STRING"), 0);
05 switch (res[0]) {
06 case 'L': printf("%s", res); exit(0); /* Redirect */
07 case 'C': printf("%s", res); exit(0); /* Content-type + content */
08 case '<': printf("Content-Type: text/html\r\n\r\n%s", res); exit(0);
09 case 'n': exit(0);
10 case 'b': my_send_metadata();
11 case 'e': my_render_login_screen();
12 case 'd': /* Logged in case */
13 my_parse_ldif(res);
14 my_render_content();
15 exit(1);
16 default:
17 ERR("Unknown zxid_simple() response(%s)", res);
18 }
19 }
Here we specify zero as auto_flags, thus all automation is disabled. This means that the res can take more varied shape and the calling application has to be prepared to handle them. The different cases are distinguished by the first character of the res string:
Redirection request (L as in Location header). The full contents of the res is the redirection request, ready to be printed to stdout of a CGI. If you want to handle the redirection some other way, you can parse the string to extract the URL and do your thing. This res is only returned if you did not set ZXID_AUTO_REDIR.
Example:
Location: https://sp1.zxidsp.org:8443/zxid?o=C
Content with Content-type header. The res is ready to be printed to the stdout of a CGI, but if you want to handle it some other way, you can parse the res to extract the header and the actual body.
Example:
CONTENT-TYPE: text/html
<title>Login page</title>
...
Example (metadata):
CONTENT-TYPE: text/xml
<m:EntityDescriptor>
...
Content without headers. This could be HTML content for login page or metadata XML. To know which (and set content type correctly), you would have to parse the content. This res format is only applicable if you did not specify ZXID_AUTO_CTYPE (but did specify ZXID_AUTO_CONTENT).
Do nothing. The operation was somehow handled internally but the exit(2) was not called (e.g. ZXID_AUTO_SOAP was NOT specified). The application should NOT attempt generating any output.
Indication that the application should send SP metadata to the client. This res is only returned if you did not set ZXID_AUTO_META.
Indication that the application should send SP CARML declaration to the client. This res is only returned if you did not set ZXID_AUTO_META.
Indication that the application should display the IdP selection page. Application may use zxid_idp_list() to render the IdP selection area. This res is only returned if you did not set ZXID_AUTO_CONTENT.
Indication that the application should display the authentication page (usually this happens on IdP).
Indication that SSO has been completed or that there was an existing valid session in place. The res is an LDIF entry containing attributes that describe the SSO or session. See "Hello World" section for description of the LDIF data.
Usually your application would parse the attributes and then render its application specific content. If you want to render the SSO management form (with logout and defederate buttons), you can call zxid_fed_mgmt().
SSO completed, if JSON output was chosen. Processing should be same as for "d".
Authorization failure. Application MUST NOT display protected content. Instead, it should offer user interface where the user can understand what happened and possibly gain the extra credentials needed.
Although any unknown letter should be interpreted as an error, we follow convention of prefixing errors with an asterisk ("*").
The simplest APIs are easy to use and suitable for CGIs where the program is restarted anew every time. However in situations where the script engine stays alive persistently, it is wasteful to reparse (and reallocate) the configuration every time. Consider following PHP snippet designed to be used with mod_php:
01 # Put this in the PHP initialization (it only needs to run once)
02 dl("php_zxid.so");
03 $conf = "PATH=/var/zxid/&URL=https://sp1.zxidsp.org:8443/zxiddemo.php";
04 $cf = zxid_new_conf_to_cf($conf);
05 <? # For every page that is accessed
06 $qs = $_SERVER['REQUEST_METHOD'] == 'GET'
07 ? $_SERVER['QUERY_STRING']
08 : file_get_contents('php://input');
09 $res = zxid_simple_cf($cf, -1, $qs, null, 0x1800);
10 switch (substr($res, 0, 1)) {
11 case 'L': header($res); exit; # Redirect
12 case 'n': exit; # already handled
13 case 'b': my_send_metadata();
14 case 'e': my_render_login_screen();
15 case 'd': break; # Logged in case -- fall through
16 default: error_log("Unknown zxid_simple() res(%s)", res); exit;
17 }
18 # *** Parse the LDIF in $res into a hash of attributes (see zxidhlo.php)
19
20 ?>
21 <html><title>Protected content, logged in as <$=$attr['cn']$></title>
22 ...
23 </html>
24 <?
25 function my_render_login_screen()
26 {
27 ?>
28 <html><title>Please Login Using IdP</title>
29 ...
30 <?=zxid_idp_select_cf($cf, null, 0x1800)?>
31 ...</html>
32 <? exit; }?>
Notes
Line 4 creates a system-wide configuration object that is later used by the other API calls
On line 9 we call zxid_simple_cf() with the created object. The second and third argument specify a buffer or string that contains the CGI form data to parse. This may come from QUERY_STRING of a GET request or from HTTP body of a POST request, as determined on line 8. The -1 means the length of the data should be determined using strlen(3), i.e. C string nul termination. The auto_flags == 0x1800 enables form tag wrapping and debug prints, but otherwise automation is disabled.
Since automation was disabled, we need to handle several cases of possible outcomes from zxid_simple_cf(), on lines 10-17.
From line 18 onwards we handle the login successful or already logged in case. First we split the LDIF entry into a hash so that we can access the attributes easily (e.g. cn on line 20).
On line 30 we call zxid_idp_list_cf() to create the form for choosing which IdP to use for login (remember that auto_flags == 0xc0 enabled the form wrapper). As can be seen the same configuration object, $cf, is used through out.
Consider
01 import zxidjava.*;
02 import java.io.*;
03 import javax.servlet.*;
04 import javax.servlet.http.*;
05 public class zxidhlo extends HttpServlet {
06 static { System.loadLibrary("zxidjni"); }
07 static final String conf
08 = "PATH=/var/zxid/&URL=http://sp1.zxidsp.org:8080/zxidservlet/zxidHLO";
09 public void do_zxid(HttpServletRequest req, HttpServletResponse res, String qs)
10 throws ServletException, IOException {
11 String ret = zxidjni.simple(conf, qs, 0xd54);
12 switch (ret.charAt(0)) {
13 case 'L': /* Redirect: ret == "LOCATION: urlCRLF2" */
14 res.sendRedirect(ret.substring(10, ret.length() - 4));
15 return;
16 case '<':
17 switch (ret.charAt(1)) {
18 case 's': /* <se: SOAP envelope */
19 case 'm': /* <m20: metadata */
20 res.setContentType("text/xml");
21 break;
22 default:
23 res.setContentType("text/html");
24 break;
25 }
26 res.setContentLength(ret.length());
27 res.getOutputStream().print(ret);
28 break;
29 case 'd': /* Logged in case */
30 //my_parse_ldif(ret);
31 res.setContentType("text/html");
32 res.getOutputStream().print(zxidjni.fed_mgmt(conf, sesid, 0xd54));
33 break;
34 default:
35 System.err.print("Unknown zxid_simple() response:");
36 System.err.print(ret);
37 }
38 }
39 public void doGet(HttpServletRequest req, HttpServletResponse res)
40 throws ServletException, IOException {
41 // LECP/ECP PAOS header checks
42 do_zxid(req, res, req.getQueryString());
43 }
44 public void doPost(HttpServletRequest req, HttpServletResponse res)
45 throws ServletException, IOException {
46 String qs;
47 int len = req.getContentLength();
48 byte[] b = new byte[len];
49 int got = req.getInputStream().read(b, 0, len);
50 qs = new String(b, 0, got);
51 do_zxid(req, res, qs);
52 }
53 }
Any Bourne shell (Unix shell) shell script can be converted to a SAML SSO enabled CGI script using zxidsimple(1) helper utility. The program simply wraps the zxid_simple() API function so that the inputs can be provided as command line arguments, or in case of qs as stdin, and the output is returned on stdout.
Synopsis
zxidsimple -o ldif CONF AUTO_FLAGS <cgi-input
Typical usage (see also zxidhlo.sh):
01 CONF="PATH=/var/zxid/&URL=https://sp1.zxidsp.org:8443/zxidhlo.sh"
02 ./zxidsimple -o /tmp/zxidhlo.sh.$$ $CONF 4094 || exit;
03 IFS="
04 "
05 res=`cat /tmp/zxidhlo.sh.$$`
06 case "$res" in
07 dn*) # SSO successful case
08 for x in $res; do
09 case "$x" in
10 sesid:*) SID=${x##*sesid: } ;;
11 idpnid:*) NID=${x##*idpnid: } ;;
12 cn:*) CN=${x##*cn: } ;;
13 esac
14 done
15 ;;
16 *) echo "ERROR($res)" >>/tmp/hlo.err; exit ;;
17 esac
18
19 cat << EOF
20 Content-Type: text/html
21
22 <title>ZXID HELLO SP Mgmt (Logged In)</title>
23 <h1>ZXID HELLO SP Management (user $CN logged in, session active)</h1>
24 <form method=post action="zxidhlo.sh?o=P">
25 <input type=hidden name=s value="$SID">
26 <input type=submit name=gl value=" Local Logout ">
27 <input type=submit name=gr value=" Single Logout (Redir) ">
28 </form>
29 EOF
The zxidsimple(1) utility will return exit value 1 if it handled a SAML protocol operation (by outputting to stdout whatever was appropriate). The shell script should not do any further processing and just exit.
If the exit value is 0 (success) then SSO has been done. Since the attributes from the SAML assertion are usually interesting, you can capture them to a temporary file using the -o option.
First we split the result of the backtick into a list on (literal) newline. Then we process the list with for loop and look with case for the interesting attributes and capture them into local variables.
Finally the protected content page is output.
The ZXID cgi interface assumes certain hardwired form field names. These are not configurable (and there is no intent to make them configurable). The cgi fields may appear either in query string (GET method) or as POST content (though depending on your programming environment and language, you may need to read the POST data in yourself prior to calling zxid_simple()).
These fields appear often in requests and have universal meaning.
Operation. In particular o=P means that form uses POST method.
Session ID
SAML 2.0 mandated field name for relay state
SAML 2.0 mandated field name for SAML artifact
SAML 2.0 mandated field name for SAML response, especially in POST profile
SAML 2.0 mandated field name for SAML request
SAML 2.0 mandated field name for signature algorithm in redirect binding
SAML 2.0 mandated field name for signature in redirect binding
These are typically embdedded or visible fields of the IdP Selection screen.
User (local login)
Password (local login)
Common Domain Cookie
Entity ID (manual entry field)
Entity ID (from popup or radio box)
Protocol index
Login using artifact profile (same as i=1)
Login using POST profile (same as i=2)
Login using specified IdP (artifact profile), same as e=EID&i=1
Login using specified IdP (POST profile), same as e=EID&i=2
Allow Create flag
IsPassive flag
Force Authentication flag
NameID format
Affiliation ID
Consent field
Matching rule
Authentication Context Class
Relay State
Please understand that a significant part of any SSO configuration is realized via f* fields, which will typically be hidden fields in the IdP selection form. Some of these configuration options can not be set or overridden from the configuration file. You must provide them as (hidden) fields of the HTML form.
The DEFAULTQS option often will emulate the IdP Selection form submission and set some f* options.
The IdP selection form (aka Login) screen can be implemented, using the above documented form interface, in many ways as following examples illustrate.
Example IdP Selection Form: Popup menu method
***
Example IdP Selection Form: Separate IdP buttons method
<form method=post
action="http://sp1.zxidsp.org:8080/zxidservlet/zxidHLO?o=P">
<h3>Login Using New IdP</h3>
<p>IdP URL <input name=e size=80>
<input type=submit name=l1 value=" Login (A2) ">
<input type=submit name=l2 value=" Login (P2) "><br>
<h3>Login Using Known IdP</h3>
<input type=submit name="l1https://a-idp.liberty-iop.org:8881/idp.xml"
value=" Login to https://a-idp.liberty-iop.org:8881/idp.xml (A2) ">
<input type=submit name="l2https://a-idp.liberty-iop.org:8881/idp.xml"
value=" Login to https://a-idp.liberty-iop.org:8881/idp.xml (P2) ">
<h3>Technical options</h3>
<input type=checkbox name=fc value=1 checked> Create federation,
NID Format: <select name=fn>
<option value=prstnt>Persistent
<option value=trnsnt>Transient
<option value="">(none)
</select><br>
<input type=hidden name=fq value="">
<input type=hidden name=fy value="">
<input type=hidden name=fa value="">
<input type=hidden name=fm value="">
<input type=hidden name=fp value=0>
<input type=hidden name=ff value=0>
</form>
Example IdP Selection Form: IdP links method
***
Following fields typically appear in form implementing logout button. You will usually need to embed them to your application's screens where logout button or link appears. Typically you would include one of them and teh s argument in the query string.
Local Logout
Single Logout using redirection
Single Logout using SOAP
NameID Managment (redirect)
NameID Management (SOAP)
Example Management Form
<form method=post action="zxid?o=P"> <input type=hidden name=s value=""> <input type=submit name=gl value=" Local Logout "> <input type=submit name=gr value=" Single Logout (Redir) "> <input type=submit name=gs value=" Single Logout (SOAP) "> <input type=submit name=gt value=" Defederate (Redir) "> <input type=submit name=gu value=" Defederate (SOAP) "> </form>
Sometimes you will see in the IdP Selection screen a small abbreviation like "(A2)". This indicates the protocol binding that will be used (if supported in metadata). The button without such legend will automatically pick binding that is best among available. If both POST and artifact are available, it will pick artifact.
A2 = SAML 2.0 Artifact Profile P2 = SAML 2.0 POST Profile '' = SAML 2.0 POST Simple Sign A12 = Liberty ID-FF 1.2 Artifact Profile P12 = Liberty ID-FF 1.2 POST Profile A1 = Bare SAML 1.x Artifact Profile P1 = Base SAML 1.x POST Profile A0 = WS-Federation Artifact Profile P0 = WS-Federation POST Profile
N.B. The IdP functionality is not fully developed as of Nov 2008.
<form method=post action="zxididp?o=P"> <input type=hidden name=s value=""> <input name=au> <input type=password name=ap> <input type=submit name=alp value=" Login "> <input type=submit name=gl value=" Local Logout "> <input type=submit name=gr value=" Single Logout (Redir) "> <input type=submit name=gs value=" Single Logout (SOAP) "> <input type=submit name=gt value=" Defederate (Redir) "> <input type=submit name=gu value=" Defederate (SOAP) "> </form>
See also ref/html/index.html:Function reference
int zxid_conf_to_cf_len(struct zxid_conf* cf, int conf_len, char* conf) struct zxid_conf* zxid_new_conf_to_cf(char* conf)
/* Simple handler that assumes the configuration has already been read in. * The memory for result is grabbed from ZX_ALLOC(), usually malloc(3) * and is "given" away to the caller, i.e. caller must free it. The * return value is LDIF of attributes in success case. * res_len, if non-null, will receive the length of the response. */ /* Process simple configuration and then call simple handler. Strings * are length + pointer (no C string nul termination needed). */ char* zxid_simple_cf(struct zxid_conf* cf, int qs_len, char* qs, int* res_len, int auto_flags) char* zxid_simple_len(int conf_len, char* conf, int qs_len, char* qs, int* res_len, int auto_flags) char* zxid_simple(char* conf, char* qs, int auto_flags)
/* ------------ zxid_idp_list() ------------ */ char* zxid_idp_list_cf_cgi(struct zxid_conf* cf, struct zxid_cgi* cgi, int* res_len, int auto_flags) char* zxid_idp_list_cf(struct zxid_conf* cf, int* res_len, int auto_flags) char* zxid_idp_list_len(int conf_len, char* conf, int* res_len, int auto_flags) char* zxid_idp_list(char* conf, int auto_flags) struct zx_str* zxid_idp_select_zxstr_cf_cgi(struct zxid_conf* cf, struct zxid_cgi* cgi, int auto_flags) struct zx_str* zxid_idp_select_zxstr_cf(struct zxid_conf* cf, int auto_flags) char* zxid_idp_select_cf(struct zxid_conf* cf, int* res_len, int auto_flags) char* zxid_idp_select_len(int conf_len, char* conf, int* res_len, int auto_flags) char* zxid_idp_select(char* conf, int auto_flags) struct zx_str* zxid_ses_to_ldif(struct zxid_conf* cf, struct zxid_ses* ses) char* zxid_simple_render_ses(struct zxid_conf* cf, struct zxid_ses* ses, int* res_len, int auto_flags) static char* zxid_simple_show_meta(struct zxid_conf* cf, struct zxid_cgi* cgi, int* res_len, int auto_flags) /* NULL return means the not logged in processing is needed, see zxid_simple_no_ses_cf() */ char* zxid_simple_ses_active_cf(struct zxid_conf* cf, struct zxid_cgi* cgi, struct zxid_ses* ses, int* res_len, int auto_flags) char* zxid_simple_no_ses_cf(struct zxid_conf* cf, struct zxid_cgi* cgi, struct zxid_ses* ses, int* res_len, int auto_flags)
char* zxid_fed_mgmt_cf(struct zxid_conf* cf, int* res_len, int sid_len, char* sid, int auto_flags) char* zxid_fed_mgmt_len(int conf_len, char* conf, int* res_len, char* sid, int auto_flags) char* zxid_fed_mgmt(char* conf, char* sid, int auto_flags)
Although a simple PEP functionality is built-in to zxid_simple() API through configuration options like PEPMAP, LOCALPDP_*~ family, and ~PDP_URL, it is sometimes desireable to implement a Policy Enforcement Point at application layer where full particluars of the request or response are available. To assist in this, the simple API provides authrorization client, which we term PEP because at protocol layer it is a XACML PEP, which your application code can call to implement the protocols specifics of a PDP. However, your own code still needs to implement the actual enforcement or filtering logic.
the configuration will need to have PEPMAP and PDP_URL options set according to your situation.
if supplied, any CGI variables are imported to session environment as attributes (according to INMAP). Format is CGI Query String.
attributes are obtained from the session, if supplied (see also CGI). The session ID is supplied as a string. If none is supplied, then session will be entirely defined by the CGI attributes.
0 if deny (for any reason, e.g. indeterminate), or 1 if permit
This function calls underlying zxid_pep_az_soap() with the difference that it is possible to import attributes to the session via CGI string.
The XACML request is constructed by applying PEPMAP configuration to the attributes in the session. For this to work, the PEPMAP MUST have subj, rsrc, and act stanzas and should have env stanza if you have environment attributes to pass. See zxid-conf.pd for further information and default values.
Variants
zxid_az_cf(cf, qs, sesid)
The configuration is received as binary object, usually obtained from zxid_conf_to_cf_len(). This avoids reparsing configuration in case multiple calls are made. Typically the same configuration object might have been used with zxid_simple_cf().
zxid_az_cf_ses(cf, qs, ses)
Both configuration and session are supplied as binary objects, such as may have been received from zxid_conf_to_cf_len() and zxid_alloc_ses() as used with zxid_simple_cf_ses().
Example Pseudocode
cf = zxid_new_conf();
ses = zxid_alloc_ses(cf);
ret = zxid_simple_cf_ses(cf, 0, $QUERY_STRING, ses, 0, 0x1800);
if (ret =~ /^d/) {
perr "SSO ok, now checking authorization";
if (zxid_az(cf, "", ses))
perr "Permit, add code to deliver application content";
else
perr "Deny, send back an error";
}
The simple PEP is based on this function:
int zxid_pep_az_soap(struct zxid_conf* cf, struct zxid_cgi* cgi, struct zxid_ses* ses)
In particular
the configuration will need to have PEPMAP and PDP_URL options set according to your situation.
if non-null, will resceive error and status codes
all attributes are obtained from the session. You may wish to add additional attributes that are not known by SSO.
0 if deny (for any reason, e.g. indeterminate), or 1 if permit
The XACML request is constructed by applying PEPMAP configuration to the attributes in the session.