XACML trying to pull any of a list of values from azure roles - authorization

I've looked at a lot of XACML questions on here but I just can't get this to resolve right. I'm in a policy using WSO2 Identity, and I'm trying to allow access if a person is in a few of a collection of roles. My rules are:
<Rule Effect="Permit" RuleId="permit_by_claims">
<Condition>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of">
<AttributeDesignator AttributeId="http://schemas.microsoft.com/ws/2008/06/identity/claims/role" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"></AttributeDesignator>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-bag">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">AG-ROLE-STAFF</AttributeValue>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">AG-ROLE-FACULTY</AttributeValue>
</Apply>
</Apply>
</Condition>
</Rule>
<Rule Effect="Deny" RuleId="deny_others"></Rule>
And in the saml response to my auth request is:
<saml2:Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">AG-ROLE-STUDENT</saml2:AttributeValue>
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">AG-ROLE-STAFF</saml2:AttributeValue>
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">AG-DEPT-ITS</saml2:AttributeValue>
</saml2:Attribute>
I don't know why that first rule is not being applied. It's just giving me a policy deny when I try to log in.
Thank you.
EDIT: Adding the policy line.
<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="authn_user_claim_based_policy_template" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable" Version="1.0">

First of all, we'd need to see how the 2 rules are combined. If it's a deny-overrides then the first rule will be masked.
Secondly, you don't need a condition (and therefore a rule) to do the check. A simple target would have done the trick given you are comparing a potentially multi-valued attribute to 2 values. Just do a=="..." OR a=="...". XML is hard to read so use alfa instead.
Thirdly, we need to see how the attributes are extracted from the SAML request and used in the XACML request because it's the latter that matters when comparing against a policy.
Finally, I find it a bit odd that the category is urn:oasis:names:tc:xacml:3.0:attribute-category:resource. I would expect a subject category for attributes coming from a SAML request.

Related

How do I make .dnn manifest file to create parent node in web.config for my child not if parent node doesn't exist?

I'm working on a DNN module. I need to edit web.config via .dnn manifest file. I need to add rule for url rewrite. I need it to look like this:
<rewrite>
<rules>
<rule name="rule1">
{some content here}
</rule>
<rule name="rule2">
{some content here}
</rule>
</rules>
</rewrite>
So main goal is actually to add 1 rule on install and delete it on module deletion. Here is the code from .dnn file that I tried first:
<component type="Config">
<config>
<configFile>web.config</configFile>
<install>
<configuration>
<nodes>
<!--<node path="/configuration/system.webServer" action="add" collision="overwrite">
<rewrite>
<rules>
</rules>
</rewrite>
</node>-->
<node path="/configuration/system.webServer/rewrite/rules" action="add" collision="overwrite">
<rule name="rule1">
{some content here}
</rule>
</node>
</nodes>
</configuration>
</install>
<uninstall>
<configuration>
<nodes>
<node path="/configuration/system.webServer/rewrite/rules/rule[#name='rule1']" action="remove">
</node>
</nodes>
</configuration>
</uninstall>
</config>
</component>
Problem is that if nodes "rewrite" and "rules" don't exist they are not created and nothing is happening at all on install.
So I tried to add the code that is commented above to create node "rewrite" and "rules" inside of it with collision="ignore" to avoid duplicates. But it doesn't work properly. If "rewrite/rules" exists and it contains already some rules - then DNN thinks that those nodes are different because the existing one contains children and the one that needs to be created has no children. And duplicated "rewrite" is created. Like this:
<rewrite>
<rules>
<rule name="rule_existing_before_module_install">
{some content here}
</rule>
<rule name="rule_added_on_module_install">
{some content here}
</rule>
</rules>
</rewrite>
<rewrite> <!--duplicated nod created by uncommented code-->
<rules>
</rules>
</rewrite>
If I try to add all the nodes at once by wrapping my rule inside "rewrite" and "rules" then it's not merged with existing "rewrite" but instead creates second one and I end up with web.config like this:
<rewrite>
<rules>
<rule name="rule1">
{some content here}
</rule>
</rules>
</rewrite>
<rewrite>
<rules>
<rule name="rule2">
{some content here}
</rule>
</rules>
</rewrite>
So eventually if there was a way to create "rewrite/rules" nodes on condition only if they don't exist and make it work both for node with and without children or make my "rewrite/rules" to merge with existing one - it would solve the problem.
Tried to google - didn't find anything helpful for this case.
Overwriting existing rules with mine and deleting existing rules is not an option.
Currently I'm thinking of manual "rewrite/rules" creation and the rest to leave for module's .dnn manifest file but it's not the best option.
Any suggestions?
P.S. I tried to add existing tag "dnn-module" but editor doesn't find it in tag search for some reason. Maybe a bug because it exists but has no questions so far?
I don't believe that this scenario, is really the targeted goal, as not all installations will actually support this section. (Rewrites is an optional IIS feature, adding this section without it enabled will take a site down)
As such, the current configuration merge functionality doesn't support this exact pathway as you are actually potentially introducing new features/breaking changes so the behavior that it only works with those sections existing is expected.
If you feel that you MUST do this, you could use IUpgradable to have your own custom code modify this, but again, be aware if building for public consumption you run the risk of doing real harm to a site.

IIS Rewrite very confusing

concerning IIS Rewrites.
I want to change this url on my local IIS Instance
http://localhost/MySite/health?key=BczI5MyulpRLxI2kiJmIXwLOm78r3qr8z2gwcsYTGR4=&c
to redirect to this url:
http://localhost/MySite/Health.svc/BczI5MyulpRLxI2kiJmIXwLOm78r3qr8z2gwcsYTGR4=/c
As you can see I don't want the incoming request to use
Health.svc/BczI5MyulpRLxI2kiJmIXwLOm78r3qr8z2gwcsYTGR4=/c
instead to use
health?key=BczI5MyulpRLxI2kiJmIXwLOm78r3qr8z2gwcsYTGR4=&c
The Health.svc is the WCF endpoint name, so I just want /health with the key and filter parameter at the end as shown.
Whatever I put in my web config rewrite it still doesn't work. I am rather confused what bit of the url to put in, as the regex seems to be valid as I can test it in IIS and online regex validators.
<rewrite>
<rules>
<rule name="HealthRewrite" stopProcessing="true" enabled="true">
<match url="MySite\/health\?key=([0-9a-zA-Z=]+)&([a-z])" />
<action type="Rewrite" url="MySite/Health.svc/{R:1}/{R:2}" appendQueryString="false" />
</rule>
</rules>
</rewrite>
How can I get this to work? I have got the rewrite module installed as can see it in IIS an also can see the dll is registered.
If you want to match the value of the query string in IIS, you need to use {QUERY_STRING}. Here is a demo:
<rewrite>
<rules>
<rule name="Test">
<match url="(Service1)" />
<conditions>
<add input="{QUERY_STRING}" pattern="(key)=(.*)" />
</conditions>
<action type="Rewrite" url="Service1.svc/{C:2}" />
</rule>
</rules>
</rewrite>
This is my web.config.
This URL:
http://localhost/Service1?key=getdata
will redirect to this url:
http://localhost/Service1.svc/GetData
For your last question, why add the MySite prefix? This is because the URL in the Rewrite URL will be used as the redirect URL. Notice that it uses back-references to preserve and rearrange the original URL pieces captured during pattern match. For Rewrite, all prefixes other than localhost must be provided in the Rewrite URL.
I managed to get it working with going to all sorts of sites as its not obvious at all.
They key seemed to put the conditions in and then a {QUERY_STRING} with regex which can then create the {C:1} and {C:2} groups that are pushed into the new rewrite
<rewrite>
<rules>
<rule name="HealthRewrite" stopProcessing="true" enabled="true">
<match url="^health" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{QUERY_STRING}" pattern="key=([0-9a-zA-Z=]+)&([a-z])" />
</conditions>
<action type="Rewrite" url="/MySite/Health.svc/{C:1}/{C:2}" appendQueryString="false"/>
</rule>
</rules>
</rewrite>
I found it confusing knowing what url to match but with a few simplified tests of just ^health I could see more easily and play around with getting the query string parameters. I had to provide the Rewrite with the /MySite/ prefix which is confusing as the match didn't need that!

How to do logical AND for Rule combining for XACML

My scenario is I have a Policy with several rules and all the rules need to be true for the policy to be true. For example:
Policy A
- Rule 1
- Rule 2
- Rule 3
For Policy A to be applicable, i need all three Rules to return true, and if even one of them return false, It should go check the other policies in my policyset
What i have right now is
<!-- shortened for brevity -->
<Policy RuleCombiningAlgId="...:deny-overrides">
<Rule id="1" Effect="Permit">
...
</Rule>
<Rule id="2" Effect="Permit">
...
</Rule>
<Rule id="3" Effect="Permit">
...
</Rule>
</Policy>
I think my problem is that the none of my rules return "Deny" but i initially thought that if it's not permit, it should be deny. I thought of putting a not on all of my rules but that would make it inelegant.
If it's relevant, I am using the Authzforce library.
all the rules need to be true for the policy to be true
In terms of XACML, I guess you mean: Policy must return Permit if and only if all Rules inside return Permit. I can't think of any rule combining algorithm in XACML standard that simply does that. So I suggest two options:
Option A: Wrap each Rule in a deny-unless-permit Policy, and use permit-unless-deny at the top-level (Policy A becomes PolicySet A).
<?xml version="1.0" encoding="utf-8"?>
<PolicySet PolicySetId="A" PolicyCombiningAlgId="...:permit-unless-deny">
<Policy RuleCombiningAlgId="...:deny-unless-permit">
<Rule id="1" Effect="Permit">
...
</Rule>
</Policy>
<Policy RuleCombiningAlgId="...:deny-unless-permit">
<Rule id="2" Effect="Permit">
...
</Rule>
</Policy>
<Policy RuleCombiningAlgId="...:deny-unless-permit">
<Rule id="3" Effect="Permit">
...
</Rule>
</Policy>
</PolicySet>
In this case, PolicySet A returns Permit if and only if (iff) no Policy returns Deny (by definition of permit-unless-deny algorithm). Since each Policy returns Permit iff the Rule returns Permit, else Deny (by definition of deny-unless-permit algorithm), this is equivalent to:
Policy A returns Permit iff all Policies return Permit, i.e. iff all Rules return Permit.
Option B: Implement a new Combining Algorithm extension for AuthzForce.

Sitefinity Blog URL Format

I am looking for guidance on an issue trying to change the blog url format to make the categories SEO friendly.
ISSUE
I am trying to have our blog categories URL changed from
https://example.com/blog/-in-category/categories/automotive
to
https://example.com/blog/automotive
Format: [domain]/[blogname]/[category]
I’ve added a custom blog provider and can access the categories with the above format, however, the hierarchical widget still shows the original url.
I did add an outbound rewrite rule that did update the widgets URLs to the correct format, however, it killed the Sitefinity backend (can’t access Pages, Blog Post Content). Scriptresource.axd and Webresource.axd through a 404.
Here is the out bound rule..
<outboundRules>
<rule name="Cat Rewrite Rule">
<match filterByTags="A" pattern="/blog/-in-category/categories/([^$]+)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{URL}" pattern="\.axd" negate="true" />
</conditions>
<action type="Rewrite" value="/blog/{R:1}" />
</rule>
<preConditions>
<preCondition name="IsHtml">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html"/>
</preCondition>
</preConditions>
</outboundRules>
Errors from backend when trying to access the Pages:
Will a custom blog taxonomy evaluator solve what I am needing to accomplish (which I’m not sure how to do)?
Thanks for your help!
In your case, problem is that you forgot to use precondition. Working example is:
<outboundRules>
<rule name="Cat Rewrite Rule" preCondition="IsHtml">
<match filterByTags="A" pattern="/blog/-in-category/categories/([^$]+)" />
<action type="Rewrite" value="/blog/{R:1}" />
</rule>
<preConditions>
<preCondition name="IsHtml">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html"/>
</preCondition>
</preConditions>
</outboundRules>
P.S. But I am totally agree with #Veselin Vasilev, that cleaner approach is to build custom widget.
You can find source code of built-in widgets here:
Blogs: https://github.com/Sitefinity/feather-widgets/tree/master/Telerik.Sitefinity.Frontend.Blogs
Taxonomies: https://github.com/Sitefinity/feather-widgets/tree/master/Telerik.Sitefinity.Frontend.Taxonomies
I would probably create 2 custom MVC widgets that will handle this scenario:
First would be one that gets all categories and renders the links using the format you want, e.g. BlogCategories widget.
It will just generate a list of categories with links of the likes of "/blog/[category]"
Second widget would be a blog list controller that will have the category as a parameter and will get all blog posts that have that category.
It is a bit of work, but much cleaner than having url rewrite rules I think.

Hide Azure Blob Url

I have a large amount of files stored in a public Azure blob container, all of which are referenced directly via the HTML in my ASP.NET MVC web application. As an example a path to one of the images in blob storage looks like so:
//<my-storage-account-name>.blob.core.windows.net/public/logo.png
I want to avoid displaying my storage account name in my HTML source code so rather than:
<img src="//<my-storage-account-name>.blob.core.windows.net/public/logo.png"/>
I'd prefer to use this:
<img src="/images/logo.png"/>
I want to avoid setting up an MVC route and using the blob API to load the file into the response stream so thought a web.config solution might be the simplest solution, i.e.
<rule name="Image Redirect" stopProcessing="true">
<match url="^images/(.*)$" ignoreCase="false" />
<action type="Redirect" url="//<my-storage-account-name>.blob.core.windows.net/public/{R:1}" redirectType="Permanent" />
</rule>
QUESTION: Is this the most efficient method given that any page could be loading 30+ images at a time? Or should I just use the public blob URL despite my concerns for performance gains?
I found a Microsoft Hands-on Lab where they recommend the web.config URL rewrite rule option:
Hands on Lab: Maintainable Azure Websites: Managing Change and Scale (July 16, 2014)
(Code Snippet - WebSitesInProduction - Ex4 - UrlRewriteRule)
<system.webServer>
<rewrite>
<rules>
<rule name="redirect-images" stopProcessing="true">
<match url="img/(.*)"/>
<action type="Redirect" url="http://[YOUR-STORAGE-ACCOUNT].blob.core.windows.net/images/{R:1}"></action>
</rule>
</rules>
</rewrite>
"Note: URL rewriting is the process of intercepting an incoming Web request and redirecting the request to a different resource. The URL rewriting rules tells the rewriting engine when a request needs to be redirected, and where should they be redirected. A rewriting rule is composed of two strings: the pattern to look for in the requested URL (usually, using regular expressions), and the string to replace the pattern with, if found. For more information, see URL Rewriting in ASP.NET."