
{"id":2072,"date":"2016-07-29T14:00:38","date_gmt":"2016-07-29T18:00:38","guid":{"rendered":"http:\/\/www.ikriv.com\/blog\/?p=2072"},"modified":"2016-07-29T14:00:38","modified_gmt":"2016-07-29T18:00:38","slug":"shibboleth-controlling-access-to-resources","status":"publish","type":"post","link":"https:\/\/ikriv.com\/blog\/?p=2072","title":{"rendered":"Shibboleth: controlling access to resources"},"content":{"rendered":"<p>Previous: <a href=\"http:\/\/www.ikriv.com\/blog\/?p=2031\">Shibboleth installation and configuration<\/a>.<br \/>\nNext: <a href=\"http:\/\/www.ikriv.com\/blog\/?p=2087\">Shibboleth: Integration issues<\/a>.<\/p>\n<p><b>SAML attributes<\/b><\/p>\n<p><a href=\"https:\/\/shibboleth.net\/\">Shibboleth<\/a> allows or denies access to a directory based on the attributes of the user it receives from the Identity Provider. If Identity Provider cannot authenticate the user, Shibboleth will show an ugly looking exception page. If Identity Provider can authenticate the user, Shibboleth will make the access decision based on user&#8217;s attributes returned by the IdP. Attributes come back as part of the IdP authentication response and contain a name and a value:<\/p>\n<p><code>&lt;saml:Attribute Name=\"mycompany.securityClearance\"&gt;&lt;saml:AttributeValue&gt;TopSecret&lt;\/saml:AttributeValue&gt;&lt;\/saml:Attribute&gt;<\/code><\/p>\n<p>Attribute names and values are not part of the SAML standard and are IdP specific, although there are some <a href=\"https:\/\/wiki.oasis-open.org\/security\/SstcSaml2AttributeX500Profile\">semi-standard attribute names<\/a> on the Internet.<\/p>\n<p><b>Mapping SAML attribute names to Shibboleth attribute IDs<\/b><\/p>\n<p>In order for Shibboleth to consider an attribute, its name must be <b>mapped<\/b> to an internal id using <code>attribute-map.xml<\/code> file typically located at <code>C:\\opt\\shibboleth-sp\\etc\\shibboleth\\attribute-map.xml<\/code>. Attributes that are not mapped cannot participate in the authorization decision. For each attribute, add the following line to the <code>attribute-map.xml<\/code> file:<\/p>\n<p><code>&lt;Attribute name=\"<i>nameAsSeenOnTheWire<\/i>\" id=\"<i>internalShibbolethId<\/i>\" \/&gt;<\/code><\/p>\n<p>Internal Shibboleth ID is arbitrary and does not have to match the name on the wire. E.g., you may have<\/p>\n<p><code>&lt;Attribute name=\"myCompany:securityClearance\" id=\"clearance\" \/&gt;<\/code><\/p>\n<p><b>Static access control<\/b><\/p>\n<p>Once you have attribute IDs defined, you can control access to protected resources using <code>&lt;RequestMapper&gt;<\/code> section of <code>shibboleth2.xml<\/code> configuration file. The following snippet gives access only to the users with Secret or TopSecret clearance:<\/p>\n<p><code><\/p>\n<pre>    &lt;RequestMapper type=\"Native\"&gt;\n        &lt;RequestMap&gt;\n            &lt;Host name=\"ikrivpc\"&gt;\n              &lt;Path name=\"secure\" authType=\"shibboleth\" requireSession=\"true\"&gt;\n                &lt;AccessControl&gt;\n                  &lt;OR&gt;\n                    &lt;Rule require=\"clearance\"&gt;Secret&lt;\/Rule&gt;\n                    &lt;Rule require=\"clearance\"&gt;TopSecret&lt;\/Rule&gt;\n                  &lt;\/OR&gt;\n                &lt;\/AccessControl&gt;\n              &lt;\/Path&gt;\n            &lt;\/Host&gt;\n        &lt;\/RequestMap&gt;\n    &lt;\/RequestMapper&gt;<\/pre>\n<p><\/code><\/p>\n<p>In theory you can have different rules for different paths, but I have not tried that. Full documentation for RequestMap rules can be found <a href=\"https:\/\/wiki.shibboleth.net\/confluence\/display\/SHIB2\/NativeSPRequestMap\">in Shibboleth wiki<\/a>.<\/p>\n<p>Users who are authenticated by not authorized to access the resource will get error 401 (Unauthorized).<\/p>\n<p><b>Dynamic access control<\/b><\/p>\n<p>Being an ISAPI extension, Shibboleth injects mapped attribute values as pseudo-headers into the HTTP request. Dynamic content such as .aspx files can access those values and make finer-grained authorization decisions based on that, or use the attributes in any other way the see fit. For attribute ID <code>fooBar<\/code> corresponding header name is <code>SHIB_FOOBAR<\/code> (capitalized). Note, that these are not real headers, you will not see them on the wire. They exist only between the IIS web server and the code of the .aspx page.<\/p>\n<p>In ASP.NET one retrieves the attribute value using expression <code>Request.ServerVariables[\"SHIB_FOOBAR\"]<\/code>. It then can be used for information purposes or to show\/hide parts of the web side, etc.<\/p>\n<p><code><\/p>\n<pre>&lt;% if (Request.ServerVariables[\"SHIB_CLEARANCE\"] == \"TopSecret\") { %&gt;\n    &lt;!-- show top secret stuff here --&gt;\n&lt;% } %&gt;<\/pre>\n<p><\/code><\/p>\n<p>Note that this comes on top of any static protection that you might have: users whose attributes don&#8217;t match the rules from <code>&lt;RequestMap&gt;<\/code> in <code>shibboleth2.xml<\/code> will have their access denied and the dynamic application code won&#8217;t have a chance to run.<\/p>\n<p><b>What&#8217;s next<\/b><br \/>\nI will discuss interesting issues I ran into when integrating my IdP with Shibboleth.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Previous: Shibboleth installation and configuration. Next: Shibboleth: Integration issues. SAML attributes Shibboleth allows or denies access to a directory based on the attributes of the user it receives from the <a href=\"https:\/\/ikriv.com\/blog\/?p=2072\" class=\"more-link\">[&hellip;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"Layout":"","footnotes":""},"categories":[24],"tags":[],"class_list":["entry","author-ikriv","post-2072","post","type-post","status-publish","format-standard","category-saml"],"_links":{"self":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2072","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2072"}],"version-history":[{"count":0,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2072\/revisions"}],"wp:attachment":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2072"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2072"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2072"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}