I'm acting as a service provider in a Shibboleth SSO interaction. I'm successfully getting back the SAML response with the expected attributes inside. However, these attributes are not showing up in the /Shibboleth.sso/Session Attributes list.
I have the <MetadataProvider> tag in the shibboleth.xml file. I'm wondering what else I could be doing wrong?
In the shibd.log I see the following:
skipping unmapped SAML 2.0 Attribute with Name: xxxx, Format:urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified
skipping unmapped SAML 2.0 Attribute with Name: yyyy
EDIT - I also added to attribute-map.xml:
<Attribute Name="xxxx" id="xxxx" />
<Attribute Name="yyyy" id="yyyy" />
The attributes do not have fully qualified names in the IdP's metadata.xml. The names are just "xxxx" and "yyyy". Does this matter?
Finally, in the IdP's metadata.xml, they have this:
<saml:Attribute Name="xxxx" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"/>
<saml:Attribute Name="yyyy" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"/>
From Shibboleth documentation:
The SAML V2.0 LDAP/X.500 Attribute Profile specifies that X.500/LDAP
attributes be named by utilizing the urn:oid namespace. These names
are simply constructed using the string urn:oid followed by the OID
defined for the attribute.
So definitely you need to use OID for attribute names, attribute-map.xml has lots of examples.
For custom attributes that are specific to some IdP they will have to supply you with OIDs to use.
I believe I have solved it. In the attribute-map.xml I had to add:
<Attribute name="xxxx" id="xxxx">
<AttributeDecoder xsi:type="NameIDAttributeDecoder" formatter="$Name" defaultQualifiers="true"/>
</Attribute>
<Attribute name="yyyy" id="yyyy">
<AttributeDecoder xsi:type="NameIDAttributeDecoder" formatter="$Name" defaultQualifiers="true"/>
</Attribute>
See here: NativeSPAttributeDecoder
Related
I'm trying to invoke ProfileFormHandler's create handle using ATG rest client as shown below.
mSession = RestSession.createSession(mHost, mPort,"kim#example.com","password");
mSession.setUseHttpsForLogin(false);
mSession.login();
Map<String,Object> params = new HashMap<String,Object>();
params.put("value.login", "buddha#oracle.com");
params.put("value.email", "buddha#oracle.com");
params.put("value.password", "password");
RestResult result = RestComponentHelper.executeMethod("/atg/userprofiling/ProfileFormHandler","create",null,params,mSession);
I'm getting form exceptions that says, I'm not passing Login and Password Fields.
["Missing value for the required property Password",
"Missing value for the required property Login name"]
I've tried all combinations of login and password fields like value.login, Login, login, value.Login etc., but nothing seemed to work. All combinations giving the same form exceptions.
How do I invoke an ATG form handler using ATG REST Client and pass parameters to it?
Definitely need more information but looking at your code I can see that you have a value.login which is not configured ootb and believe this is causing the NPE. Assuming you have not customized the ootb ATG RegistrationFormHandler and the required field in the repository the only values you need to pass to the form handler are:
value.email
value.password
value.confirmPassword
value.firstName
value.lastName
Also, the help is specific that the data-type of the value property needs to be java.util.Dictionary
Add the following to /atg/rest/security/restSecurityConfiguration.xml
<resource component="/atg/userprofiling/ProfileFormHandler" secure="false">
<method name="handleCreate" secure="false">
<acl value="EVERYONE:read,write,execute" />
</method>
<property name="value.login" secure="false" />
<property name="value.password" secure="false" />
</resource>
I came to know that in any SSO Solution if SP needs any additional attributes it can publish them in its metadata using AttributeConsumingService argument. The required attributes can now be added like as below:
<md:AttributeConsumingService index="0"
xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<md:ServiceName xml:lang="en">ABC</md:ServiceName>
<md:ServiceDescription xml:lang="en">ABC</md:ServiceDescription>
<md:RequestedAttribute isRequired="true"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
Name="urn:oid:2.5.4.42"
FriendlyName="FirstName"/>
</md:AttributeConsumingService>
Now, if I want to add a custom attribute in my SP metadata, lets say "Role" of a user, how should I add it in the metadata? I mean, what would be its Name(this is what I'm unable to find!), NameFormat(is it urn:oasis:names:tc:SAML:2.0:attrname-format:uri?) and FriendlyName(can I give it as "Role" here?). I've not found anything related to this in the SAML2Core document.
Any suggestions please!
Thanks,
Abhilash
There is no universal answer as it depends on which IDP/federation you use and what is supported by it.
Generally, the friendly name is just a human-readable identifier for the attribute and the value can be freely defined.
The NameFormat and Name are defined based on Attribute Profile used by your IDP (e.g. Basic profile, X.500/LDAP Profile, ...). The expected values can be found in SAML 2.0 profiles document chapter 8.
You can find an example of how this is employed in practice for e.g. inCommon federation in their documentation.
[WCS 7, FixPack 7, Feature Pack 6]
I need to generate a feed with certain catalog entry (product) information such as name, image(s), category, price, seo-url, descriptive attributes and so on.
To generate this feed i will use the scheduler framework and created a controller command which will be invoked after a certain time has passed.
Now i need to receive the catalog entry data of each item in a specific store/catalog.
As far as i know there are several ways to achieve this:
Access Beans
SOA (new Access Profile with specific SQL)
I tried to use Access Beans to get all necessary information but I got stuck with seo-url, price etc.
Are there more ways and what is the best practice to get a specific set of catalog entry attributes?
I suggest you study/investigate in your WCS Development environment how site map generation schedule command is implemented (SitemapGenerateCmd) and how it is calling the JSP template file (sitemap.jsp)
you need to modify a bit in your command to create a jsp template for your feed and call that template from your scheduler command you've created .
calling template command for messaging system, make sure to use following properties in ActionForward tag to register the JSP for messaging from back-end:
example:
<forward className="com.ibm.commerce.struts.ECActionForward"
name="SitemapIndexView" path="/SitemapIndex.jsp">
<set-property property="direct" value="true"/>
<set-property property="resourceClassName" value="com.ibm.commerce.messaging.viewcommands.MessagingViewCommandImpl"/>
<set-property property="interfaceName" value="com.ibm.commerce.messaging.viewcommands.MessagingViewCommand"/>
<set-property property="properties" value="storeDir=no"/>
<set-property property="implClassName" value="com.ibm.commerce.messaging.viewcommands.MessagingViewCommandImpl"/>
</forward>
then the logic for extracting data from your product/catalog beans will be handled inside the JSP and you can easily form the output data as you want (XML, CSV, JSON .. etc)
the advantages and benefits of using this way are you can leverage Commerce Server OOTB JSTL tags , WCF tags for retrieving all information and using wcf:url for SEO URLS OOTB even you can call BOD/SOA commands using <wcf:getData tag and finally your will get more structured design that can easily maintain and reuse in future .
sitemap.jsp is a good resource for you how to iterate through catalog and sub-catalog to extract product info.
hope that those help you find your solution. need some search and understanding of existing sitemap generation utility .
Thanks.
Abed
I've created a REST API in an Area of my ASP.NET MVC 4 web application. The API is working properly, and I'd now like to secure it.
Is there a very simple example of how I can do this? I'm going through the samples that came with the DotNetOpenAuth download and I'm completely lost on it.
I had the same problem a couple of days ago. This answer is ridiculously long, maybe there's an easier way.
Personally, I don't use DNOA anymore because it is designed towards self-validating (i.e. encrypted tokens) so you don't need to hit the DB with every request. A very important side effect of this is that an access revocation will not become effective immediately, but only after the token must be renewed. Also, access tokens will become quite long (around 500 bytes).
As a very first step, make sure you know what you need:
OAuth / OAuth2 look easy at first, but it's important to understand how the authorization workflows are designed. Also, their terminology can be irritating, for instance 'Client' refers to what I would naively call client application. It's not the user (who is called 'resource owner' in OAuth terms). My suggestion: Read RFC 6749. It looks dull, but it's an interesting read (and you can skip half of it...)
A key question is: Do you need 2-legged OAuth or 3-legged OAuth (or both?). Which grant types do you need to support?
If you basically want to replace HTTP Basic Auth, the simple "Resource owner password credentials flow" will do. The facebook/twitter kind type of "have this application access my profile information" is 3-legged OAuth.
There's an IBM Documentation that comes with nice grant type diagrams.
Now to DNOA, take a look at Samples/OAuthAuthorizationServer.
A good entry point is the OAuthController.cs file. Note that the Authorize and AuthorizeResponse actions are required only if you want to enable your users to give access to third party applications (3-legged OAuth).
In a 2-legged scenario, users access the OAuth token endpoint directly and simply request an access token. In any case you will need such a controller in your REST application.
The key to the inner workings is the OAuth2AuthorizationServer class (NOT the AuthorizationServer class). Look at Code/OAuth2AuthorizationServer.cs. It implements IAuthorizationServerHost.
Half of that class deals with data storage (which you might want to modify if you're working with a different datastore), and half of it deals with the encryption of the access tokens. You will need to implement IAuthorizationServerHost for your application, too.
Make sure you have a line #define SAMPLESONLY in your code, so it will accept the hardcoded certificate.
To actually authorize the request, it is helpful to write a custom ActionFilterAttribute. Here's some super condensed code, not production ready:
public sealed class BasicAuthenticationAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
private readonly OAuthResourceServer _authServer;
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.Request.Headers.Authorization.Scheme == "Bearer"
|| actionContext.Request.Properties.ContainsKey("access_token"))
{
authenticatedUser = _authServer.VerifyOAuth2(request, required_claims);
HttpContext.Current.User = authenticatedUser;
Thread.CurrentPrincipal = authenticatedUser;
}
}
}
// See OAuthResourceServer/Code/OAuthAuthorizationManager.cs in DNOA samples
public sealed class OAuthResourceServer
{
public IPrincipal VerifyOAuth2(HttpRequestMessage httpDetails, params string[] requiredScopes)
{
// for this sample where the auth server and resource server are the same site,
// we use the same public/private key.
using (var signing = CreateAuthorizationServerSigningServiceProvider())
{
using (var encrypting = CreateResourceServerEncryptionServiceProvider())
{
var tokenAnalyzer = new StandardAccessTokenAnalyzer(signing, encrypting);
var resourceServer = new ResourceServer(_myUserService, tokenAnalyzer);
return resourceServer.GetPrincipal(httpDetails, requiredScopes);
}
}
}
}
The resource server is still missing
public sealed class MyResourceServer : ResourceServer
{
public override System.Security.Principal.IPrincipal GetPrincipal([System.Runtime.InteropServices.OptionalAttribute]
[System.Runtime.InteropServices.DefaultParameterValueAttribute(null)]
HttpRequestBase httpRequestInfo, params string[] requiredScopes)
{
AccessToken accessToken = this.GetAccessToken(httpRequestInfo, requiredScopes);
string principalUserName = !string.IsNullOrEmpty(accessToken.User)
? this.ResourceOwnerPrincipalPrefix + accessToken.User
: this.ClientPrincipalPrefix + accessToken.ClientIdentifier;
string[] principalScope = accessToken.Scope != null ? accessToken.Scope.ToArray() : new string[0];
// Now your own code that retrieves the user
// based on principalUserName from the DB:
return myUserService.GetUser(userName);
}
}
Next, modify web.config so DNOA doesn't complain about missing SSL connections in development:
<configSections>
<sectionGroup name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection, DotNetOpenAuth">
<section name="openid" type="DotNetOpenAuth.Configuration.OpenIdElement, DotNetOpenAuth" requirePermission="false" allowLocation="true" />
<section name="oauth" type="DotNetOpenAuth.Configuration.OAuthElement, DotNetOpenAuth" requirePermission="false" allowLocation="true" />
<sectionGroup name="oauth2" type="DotNetOpenAuth.Configuration.OAuth2SectionGroup, DotNetOpenAuth">
<section name="authorizationServer" type="DotNetOpenAuth.Configuration.OAuth2AuthorizationServerSection, DotNetOpenAuth" requirePermission="false" allowLocation="true" />
</sectionGroup>
<section name="messaging" type="DotNetOpenAuth.Configuration.MessagingElement, DotNetOpenAuth" requirePermission="false" allowLocation="true" />
<section name="reporting" type="DotNetOpenAuth.Configuration.ReportingElement, DotNetOpenAuth" requirePermission="false" allowLocation="true" />
</sectionGroup>
</configSections>
<dotNetOpenAuth>
<!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. -->
<reporting enabled="true" />
<openid>
<provider>
<security requireSsl="false">
</security>
</provider>
</openid>
<oauth2>
<authorizationServer >
</authorizationServer>
</oauth2>
<!-- Relaxing SSL requirements is useful for simple samples, but NOT a good idea in production. -->
<messaging relaxSslRequirements="true">
<untrustedWebRequest>
<whitelistHosts>
<!-- since this is a sample, and will often be used with localhost -->
<add name="localhost"/>
</whitelistHosts>
</untrustedWebRequest>
</messaging>
</dotNetOpenAuth>
We have a SAML 2.0 federated environment (IDP and SP). I would like to generate a custom attribute for assertions created only for one SP. As such, I will not modify the IDP configuration.
The snippet of the SAML Assertion we need to create:
< saml:Attribute NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" >
Name="urn:oasis:names:tc:SAML:2.0:profiles:attribute:DCE:groups">
< saml:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
xsi:type="xsd:string">ABCD
According to SAML2 specifications, we need to modify the SP extended metadata to provide this attribute. The constant string "ABCD" is the attribute we want to send. I've modified as such, but no results. Can anyone provide insight?
< Attribute name="urn:oasis:names:tc:SAML:2.0:profiles:attribute:DCE:groups">
< Value>urn:oasis:names:tc:SAML:2.0:attrname-format:uri|ABCD</Value>
< /Attribute>
Also tried:
< Attribute name="urn:oasis:names:tc:SAML:2.0:profiles:attribute:DCE:groups"
nameformat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
< Value>"ABCD"</Value>
< /Attribute>
Looking at the metadata spec it seems like you use the following syntax to define what attributes you want from the IDP. Of course the IDP must be configured to allow the export of such attribute to..
<AttributeConsumingService>
<ServiceName xml:lang="en">youname</ServiceName>
<RequestedAttribute
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:theformat"
Name="theAttributeName"
FriendlyName="humanReadableName"/>
</AttributeConsumingService>
The spec of this is here at page 21
https://www.oasis-open.org/committees/download.php/35391/sstc-saml-metadata-errata-2.0-wd-04-diff.pdf