Shibboleth - How to read attributes? - attributes

I'm successfully logging into my Service Provider test page with Shibboleth. I then go to the /Shibboleth.sso/Session page and I see the following:
Attributes
affiliation: 1 value(s)
entitlement: 1 value(s)
eppn: 1 value(s)
persistent-id: 1 value(s)
unscoped-affiliation: 1 value(s)
My question is... how do I go about reading these values? I don't see them in the HTTP Request header in Fiddler.
My web application will be implemented in ASP.NET MVC 4 (C#).

You can also set showAttributeValues to true in the Session handler in shibboleth2.xml. Note, this is not recommended in a production environment. Then restart the shibboleth service; the Attributes section of the Session page will include the actual values.
<!-- Session diagnostic service. -->
<Handler type="Session" Location="/Session" showAttributeValues="true"/>

You can read Shibboleth SAML attributes sent by the IdP using Request.ServerVariables object:
string server = Request.ServerVariables["HTTP_FIRSTNAME"];
See this if you want to list and print all the attributes in session.
Remember to configure Shibboleth attribute-map.xml to handle the custom attributes your IdP may send:
<Attribute name="firstname" id="firstname" nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<AttributeDecoder xsi:type="StringAttributeDecoder"/>
</Attribute>

since you mentioned fiddler, i'll go ahead and add (years after the question) that there is a really nice firefox browser add-on called "SAML tracer". (just search for "saml tracer" and you'll find the mozilla addons page for it.) once installed in firefox, you can open its window and it will show all http requests and responses. if anything has saml in it, it will indicate that with a "SAML" tag next to the url; then you can click on that url, choose the "SAML" tab, and read all of the saml that was sent between the idp or sp and your browser. it's a really great in-line troubleshooting tool, so you don't have to mess with anything on the sp and/or idp (or even have access to them).

Related

Can't see all response header cookies in jmeter

I am trying to load test an application which uses azure AD B2C authentication. I have replicated all requests. However there is authorize endpoint which when inspected in browser I can see few cookies from response header.
This has openidconnect cookie, another couple of cookies. However when running this request in jmeter, I can see only openidconnect cookie but not others.
I need to send other cookies in subsequent request. I have cookie manager and also turned on save cookie flag in user.properties and jmeter.properties files.
Any help is much appreciated.
Most probably it indicates some problem with cookies, i.e. domain/path mismatch or the cookie is expired or something like this so it sounds like your system under test issue.
If you don't care about correctness of functional behaviour of your application and just want to send all the incoming cookies no matter of their validity - you can try the following workarounds:
Disable JMeter's mechanism for checking cookies so everything will be stored in the Cookie Manager no matter if there are any issues. It can be done by adding the next line to user.properties file:
CookieManager.check.cookies=false
Switch to less restrictive implementation, i.e. netscape in the HTTP Cookie Manager itself:
More information: HTTP Cookie Manager Advanced Usage - A Guide
You can also enable debug logging for the Cookie Manager by adding the next line to log4j2.xml file:
<Logger name="org.apache.jmeter.protocol.http.control" level="debug" />
once done you will be able to see what's going on with each and every incoming/outgoing cookie in jmeter.log file

Web Security: Preventing CSRF attack

I am following this tutorial for an application based in spring framework 3.2.4
http://springdiaries.blogspot.be/2012/12/web-security-preventing-csrf-attack.html#comment-form
The point is that I've checked all the objects in the session and I haven't found any object with the Key OWASP_CSRFTOKEN, and that is susposius that in not working well ?
This is not exactly an answer to your question, which is unfortunately too vague to answer without a magical crystal ball ^^, but here are some things you should try:
Check out your request is not coming from an URL matching one of the
the unprotected patterns defined in the
Owasp.CsrfGuard.properties configuration file (These values are
from the OWASP docs; you should have set up different ones):
.
org.owasp.csrfguard.unprotected.Tag=/Owasp.CsrfGuard.Test/tag.jsp
org.owasp.csrfguard.unprotected.JavaScriptServlet=/Owasp.CsrfGuard.Test/JavaScriptServlet
org.owasp.csrfguard.unprotected.Html=*.html
org.owasp.csrfguard.unprotected.Public=/MySite/Public/*
Check your web server / servlet container log for errors, both on startup / application load and upon receiving a client request.
Set breakpoints here and here and launch the application in
debug mode to make sure your class is being loaded and the token is
being requested.
Review one by one all the configuration parameters.
Read the project wiki and the docs carefully:
Configuration
Installation
User Manual
You won't have to modify your DB schema in anyway. That's not how OWASP CRSF guard works (the generated tokens are stored in-session, not persisted in the database).
It's also worth mention that you are following an outdated blog post: If you are using Spring you don't need to be using OWASP CSRF guard at all. You should be using spring-security authentication which has built in CSRF protection, which is much easier to set-up.
Check out the tutorial on this page on how to set up HTML form + SQL database based authentication with CSRF protection (Also, don't miss out the bcrypt password hashing one; It is very easy to set up and at some point you'll be glad you are storing safe hashes instead of clear text passwords).
You'll see you also won't have to modify the db at all to add CSRF protection using spring-security because the CSRF protection token is session-stored.
The set up takes 5-15 minutes; 30 minutes tops for a Spring neophite. In a nutshell, the framework takes care of generating and validating the token and returning an authentication error on invalid requests.
You just have to include the <csrf /> tag inside your spring-security.xml configuration file <http> tag.
If you are using html form based authentication, you'll also have to include the following hidden input inside the form:
<input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}" />

OWASP Application Security Verification Standard - V3 and using with JSF

At the moment I'm dealing with implementing everything is to be safe against the security risks of the Top 10 Project
For #4 of the Top 10 - Insecure Direct Object References the OWASP refers to the OWASP Application Security Verification Standard
So I was reading all the suff in V3, but I have now some questions implementing it.
I'm using JBoss-AS 7.0.1 with Java EE6 and JSF 2.0
V3.4 Verify that the session id is never disclosed other than in cookie headers; particularly in URLs, error messages, or logs. This includes verifying that the application does not support URL rewriting of session cookies.
I read some articles here on stackoverflow how to avoid that the jesssion is in the URL for the first time a user is visiting the side...
But many answers are like: use the URL rewriting ... what does this means in contrast to the does not support URL rewriting of session cookies
What is the normal way to deal with jsessions on the first entry? What is a save way to handle it?
V3.10: Verify that only session ids generated by the application framework are recognized as valid by the application.
How you do this in JSF2.0 / JavaEE?
V3.12: Verify that cookies which contain authenticated session tokens/ids have their domain and path set to an appropriately restrictive value for that site.
What does this mean? When i look with my Firebug into the the cookie, I run the webapp from the URL http://localhost:8080/projectname/
and in the cookie i get: Path: /projectname
is this what the OWASP means with have their domain and path set to an appropriately restrictive value for that site. ?
Thank you!
V3.4 Verify that the session id is never disclosed other than in cookie headers; particularly in URLs, error messages, or logs. This includes verifying that the application does not support URL rewriting of session cookies.
The servlet container is by default configured to support session tracking by cookies and URLs. The session tracking by URL is also known as "URL rewriting" wherein you see the ;jsessionid=[session id] to appear in URLs. This will be triggered automatically when the client has cookies disabled. To disable tracking by URL, you need to explicitly specify a tracking mode by cookie only. Add this to the webapp's web.xml:
<session-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
Further you need to make sure that the JSF code is nowhere printing the session ID to the HTML output by among others <h:outputText value="#{session.id}" />.
V3.10: Verify that only session ids generated by the application framework are recognized as valid by the application.
The servlet container will by default already do that. Only Tomcat 6.x (and inherently thus also JBoss 5.x) had the security issue that when the server-wide session sharing is been enabled, then the server will use exactly the session ID as supplied by the client in the Cookie request header. Tomcat 7.x (and inherently thus also JBoss 6.x/7.x) will not do that anymore. See also among others the Tomcat 6.x <Connector> documentation for some more background information (check the emptySessionPath attribute description).
V3.12: Verify that cookies which contain authenticated session tokens/ids have their domain and path set to an appropriately restrictive value for that site.
The servlet container will by default already do that. Only when you configure the servlet container to use server-wide session sharing (thus, the same session is been shared between all deployed applications), then it violates the rule. See also the previous point.
Please note that most of those rules have very little to do with JSF. They have more to do with general server and webapp configuration. JSF is merely a component based MVC framework.

How To Become a SAML Service Provider

My company currently develops a Java web application. A couple of our clients have internal SAML servers (identity providers?) and have requested that we integrate with them. So recently I've been reading up on it and playing around with OpenAM. After about 3 days of this, I have a general understanding of it, but there are still some gaps in my knowledge. My hope is that someone can clear this up for me.
So here's how I imagine the workflow of a user logging in.
Let's define our customers SAML server as https://their.samlserver.com. So a user comes to our web application for a resource that's protected. Let's say that URL is http://my.app.com/something.
So if I'm correct, my.app.com is what SAML defines as a Service Provider. Our application realizes that this user needs to log in. We then present a page like this to the user...
<script>JQuery Script to auto submit this form on ready</script>
<form method="post" action="https://their.samlserver.com/Post/Servlet">
<input type="hidden" name="SAMLRequest" value="someBase64Data" />
<input type="submit" value="Submit" />
</form>
And that someBase64Data should be base64 encoded version of this...
<samlp:AuthnRequest
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="identifier_1"
Version="2.0"
IssueInstant="2004-12-05T09:21:59Z"
AssertionConsumerServiceIndex="0">
<saml:Issuer>http://my.app.com</saml:Issuer>
<samlp:NameIDPolicy
AllowCreate="true"
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/>
</samlp:AuthnRequest>
So my first couple questions.
What is the ID value suppose to be?
And why can I declare myself as an Issuer?
Does the Identity Provider know about me? Maybe this is that Circle of trust I've been seeing on OpenAM. And if it does know about me, how does it know about me and what does it need to know?
So after the user is forwarded that page, they are taken to a page provided by the IDP https://their.samlserver.com. They authenticate on that page and the IDP does it's magic to validate the authentication and look up the user. After the authentication is successful, the IDP sends back a <samlp:Response> defined here.
A few more questions.
First, how does the <samlp:Response> get back to my web application so I can check it?
And what should I be looking for in that response to validate that it was successful? What does a failure look like?
We currently use the email address (LDAP) to identify users, so we'll probably grab that from the response and use that in the same way we do now. Anything else I should be mindful of in that response?
So now that we've checked that response for validity, we can grant the user a session like we do currently. But when they want to log out, is there a workflow for that? Do I have to notify the IDP that the user has left?
And finally, there are a couple of topics that have been thrown around in my reading and I'm not sure how they fit into this workflow. They are Circle of trust, Tokens, and Artifacts.
Thanks for any help everyone. I've found a lot of information in the last couple days, and it's possible that I could piece them together after a bit more playing. But I have yet to find a straightforward "Here's the Post" workflow article yet. Maybe that's because I'm wrong on how this works. Maybe it's because this isn't that popular. But I really wanted to make sure that I got the workflow so I didn't miss a crucial step in something as important as user authentication.
In response to your specific questions:
1.) What is the "ID" value supposed to be?
This should be a unique identifier for the SAML request. The SAML 2.0 specification states that it's really implementation specific how this is done, but makes the following recommendations:
The mechanism by which a SAML system entity ensures that the
identifier is unique is left to the implementation. In the case that a
random or pseudorandom technique is employed, the probability of two
randomly chosen identifiers being identical MUST be less than or equal
to 2 ^ -128 and SHOULD be less than or equal to 2 ^-160 in length.
This requirement MAY be met by encoding a randomly chosen value
between 128 and 160 bits in length.
2.) How does the IdP know about you?
Your SP needs to be registered with the IdP. To accomplish this, the SAML specification defines a format for "SAML Metadata" which tells the IdP where your SAML receivers are, what your certificates are, attributes you exchange, etc. OpenAM likely dictates some minimum requirements for configuring a trusted SP. This varies in each product.
3.) Where's the Response go, and what to check?
The Response will go to your Assertion Consumer Service (ACS) URL usually defined in the SAML Metadata you exchange from your SP with the IdP for initial setup. When you receive a SAML Response, you need to check many things - but most importantly, the SAML Status code should be "success", the inResponseTo ID's should match the request's sent ones and you must validate the digital signature on the Assertion. For that, you'll need to trust the IdP's public verification certificate, and you'll probably also want to do revocation checking.
4.) What about Logout?
SAML 2.0 also defines a profile for Single LogOut (SLO). This will not only log you out of the SP, but also the IdP and potentially any other SP's you've established a session with. It has a similar request/response flow as Single Sign-On (SSO), and thus similar things to set up and check (status codes, signatures, etc.).
So in short - this can be quite complex to implement from scratch. It's best to use tried & true libraries and/or products like Ian suggests. Companies like his have invested hundreds of hours of developer time to implement according to the spec and test interoperability with other vendors.
If you're just trying to set a single Java application up as a Service Provider, you should consider using a Fedlet from either Oracle (as a standalone ) or ForgeRock ( bundled with OpenAM ). The ForgeRock Fedlet has some issues interacting with Shibboleth 2.2.1 as an Identity Provider, but I find it to be somewhat simpler to configure and more informative.
Each has explicit instructions contained in the README to help you deploy. Once the Fedlet is configured and communicating with the IDP, the success page shows you all the code you need to integrate federated SSO into your application. It does the background work of sending and receiving AuthnRequests and Responses.
Scott's answer responds quite well to the questions you had, but I think that trying to write code on your own that generates the SAML is reinventing the wheel. The Fedlet was designed with precisely this use case in mind.

Secure only Login.aspx for a site

Is it possible to secure only the Login.aspx page (and the postback) and not the whole site in IIS?
We are looking to do this specifically with a SharePoint site running Forms Based Authentication against our Active Directory.
Links to this will be helpful.
This is what we have done so far:
1. Setup SharePoint to use FBA against AD.
2. Moved Login Page to Secure/Login.aspx
3. Set the appropriate Login url in web.config as https://..../Secure/Login.aspx
This is not working and help is needed here.
However even if this works, how do we get the user back to http from https?
There's not a whole lot of point. If the only thing that's encrypted is the Login.aspx page, that would mean that someone could sniff all the traffic that was not sent through the login page.
Which might prevent people from getting user:pass, but all your other data is exposed.
Besides all the data which is exposed, and the user's operation which can be changed en route, the user's session id (or other authentication data) is sent in the clear. This means that an attacker can steal your cookie (...) and impersonate you to the system, even without getting your password. (If I remember correctly SPSv.3 also supports builtin password changing module...)
So I would say that this is not a Great Idea, unless you dont care about that system very much anyway.... But then, why bother with authentication at all? just make it anonymous?
I agree with AviD and Dan Williams that securing only the login page isn't a great idea because it exposes other data after leaving the password page. However, you can require SSL for only the login.aspx page via the IIS Manger. If you navigate to the login.aspx page in IIS Manager (I believe it's under /_layouts), you can right-click on the individual file and select Properties. From there, go to the File Security tab and click on the Edit... button under Secure communications. There, you can check the Require secure channel (SSL) box, and SSL will be required for that page only.
I'm not positive about getting the user back to http from there, but I believe its default behavior is to send you to the requested page if the login is successful. If not, I would think you could customize where the login page sends you on a successful login.

Resources