How to use file-based config for Saml2SecurityTokenHandler? - federated-identity

Using Saml2SecurityTokenHandler to validate SAML2 bearer token from internal provider or from ACS. Able to programmatically configure the handler to validate just fine, but it doesn't seem to want to pick up configuration from the microsoft.IdentityModel section in my config file. Constructing a SecurityTokenHandlerCollectionManager seems to have no notion of the named configuration section either so I can't seem to use mySaml2SecurityTokenHandler .Configuration - mySecurityTokenHandlerCollectionManager["NAME"].Configuration.
Is there a good sample of setting this up somewhere?

To use file-based config, it turns out you simply rely on the FederatedAuthentication context, rather than explicitly constructing the Saml2SecurityTokenHandler:
var handlers = FederatedAuthentication.ServiceConfiguration.SecurityTokenHandlers;
var token = handlers.ReadToken(xmlReader);
var collection = handlers.ValidateToken(token);

This seems to be a known problem.
Have you tried FederatedClientCredentials --> SecurityTokenHandlerCollectionManager property --> SecurityTokenHandlerCollection --> replace the standard Saml2SecurityTokenHandler with whatever?

Related

How to load VM_global_library.vm for Velocity in Spring Boot?

We're using a VelocityLayoutServlet as the view resolver in Spring Boot.
#Bean(name = "velocityViewResolver")
public VelocityLayoutViewResolver velocityViewResolver() {
VelocityLayoutViewResolver resolver = new VelocityLayoutViewResolver();
this.properties.applyToViewResolver(resolver);
resolver.setLayoutUrl("layout/default.vm");
return resolver;}
We want to load global macros from a VM_global_library.vm file, as described in the Velocity User Guide. Expected Velocity to load that default file from /templates directory, but not happening.
Adding theexplicit setting mentioned in the Velocity User Guide did not work either:
spring.velocity.velocimacro.library=VM_global_library.vm
velocimacro.library - A comma-separated list of all Velocimacro template libraries. By default, Velocity looks for a single library: VM_global_library.vm. The configured template path is used to find the Velocimacro libraries.
Are we missing some magic, or is this missing from the integration?
Velocity properties can be set with "spring.velocity.properties.*" attribute.
This configuration works for me:
spring.velocity.properties.velocimacro.library=templates/VM_global_library.vm

Grails Spring Security Static Rules

I want all users to be authenticated before accessing my application. Following is the setting in Config.groovy:
grails.plugin.springsecurity.controllerAnnotations.staticRules=[
"/**": ["ROLE_ADMIN"],
"/login/auth": ["permitAll"]
]
The reason I put "/login/auth": ["permitAll"] is that any user can have a chance to log in and be authenticated. However, when I access http://localhost:8080/myapp/, it redirects to http://localhost:8080/myapp/login/auth and throws the error: The page isn't redirecting properly. Can you please advise what mistake I have committed here?
For first you must say to spring security what type of mapping you will be use.
grails.plugins.springsecurity.securityConfigType = 'InterceptUrlMap'
For second 'permitAll' changed to 'IS_AUTHENTICATED_ANONYMOUSLY'
And for third, if spring security find /** he didn't see another under this line. So your code must be like this:
grails.plugins.springsecurity.securityConfigType = SecurityConfigType.InterceptUrlMap
grails.plugins.springsecurity.interceptUrlMap = [
"/login/auth": ["permitAll"],
"/**": ["ROLE_ADMIN"]
]
TrongBang and Koloritnij are on the right track. But they're not completely correct in the context of your question. They're suggesting that you switch to a different authentication setup. (Which that will work but it doesn't solve the problem in the context of your setup.)
If you wish to keep the annotations, you're going to have to call out the controller that OAuth uses.
‘/springSecurityOAuth/**’: [‘permitAll’]
The plugin maps that controller path, but the static rules still interprets the controller and methods from that.
This took some digging for me to find this out. I had your same issue, and I blogged about this (and it includes some of the details about how the Spring Security Oauth plugin works.
http://theexceptioncatcher.com/blog/2015/04/spring-security-oauth-the-missing-instructions/
The solution from Koloritnij is correct. However, it threw the following error when using SecurityConfigType.InterceptUrlMap:
ERROR: the 'securityConfigType' property must be one of
'Annotation', 'Requestmap', or 'InterceptUrlMap' or left unspecified
to default to 'Annotation'; setting value to 'Annotation'
I have changed it to 'InterceptUrlMap' only and it worked:
grails.plugins.springsecurity.securityConfigType = 'InterceptUrlMap'
grails.plugins.springsecurity.interceptUrlMap = [
"/login/auth": ["permitAll"],
"/**": ["ROLE_ADMIN"]
]

Oracle Service Bus - Assign expression

I have this problem and I am not sure why it's happening and how to fix it. I have created an OSB peject. In the proxy service pipeline I am doing a Service Callout to a sync SOAP service in another application. The other service needs the request body as below:
<RequestSelectionValues xmlns="http://www.camstar.com/WebService/WSShopFloor">
<inputServiceData xmlns:q1="http://www.camstar.com/WebService/DataTypes" q1:type="OnlineQuery">
<OnlineQuerySetup>
<__CDOTypeName/>
<__name>xLot By FabLotNumber</__name>
</OnlineQuerySetup>
<Parameters>
<__listItem>
<Name>FabLotNumber</Name>
<DefaultValue>FAB_Lot_1</DefaultValue>
</__listItem>
<__listItem>
<Name>BLOCKOF200ROWS</Name>
<DefaultValue>1</DefaultValue>
</__listItem>
</Parameters>
</inputServiceData>
<queryOption xmlns:q2="http://www.camstar.com/WebService/DataTypes" q2:type="QueryOption">
<RowSetSize>1000</RowSetSize>
<StartRow>1</StartRow>
<QueryType>user</QueryType>
<ChangeCount>0</ChangeCount>
<RequestRecordCount>false</RequestRecordCount>
<RequestRecordSetAndCount>false</RequestRecordSetAndCount>
</queryOption>
<serviceInfo xmlns:q3="http://www.camstar.com/WebService/DataTypes" q3:type="OnlineQuery_Info">
<OnlineQuerySelection>
<RequestValue>false</RequestValue>
<RequestMetadata>false</RequestMetadata>
<RequestSubFieldValues>false</RequestSubFieldValues>
<RequestSelectionValues>true</RequestSelectionValues>
</OnlineQuerySelection>
</serviceInfo>
</RequestSelectionValues>
I am using an Assign to put the above expression in a variable.
Notice the line:
<serviceInfo xmlns:q3="http://www.camstar.com/WebService/DataTypes" q3:type="OnlineQuery_Info">
xmlns:q3="http://www.camstar.com/WebService/DataTypes" needs to be before q3:type="OnlineQuery_Info" for the other service to be called successfully otherwise the service call fails.
In the development it looks fine. I can test the assign of expression as well.
When I go to the OSB console to test the service I notice that in the Assign variable the namespace place switches and it becomes like this:
<serviceInfo q3:type="OnlineQuery_Info" xmlns:q3="http://www.camstar.com/WebService/DataTypes">
This makes the service calls to fail. I have tried putting the body payload in an xslt. Result is the same. I am not sure why it switches the type before namespace. The end result is that the service is not working as expected.
Any idea what I can do to fix this issue. How can I prevent the switching?
Thanks
I haven't found any settings in OSB that can prevent reordering of attributes for you. However, the above OSB behavior is completely XML standard compliant. In fact, the target service side should be XML compliant and treat the two variants mentioned above as the same, because according to XML standard, tow XML documents with only difference in attribute ordering should be treated as the same.
EDIT:
Please go here to download a modified config. My thoughts are:
Specify the business service to invoke in 'Text as Request' mode, as "CamstarLotQuery/business/CSWSShopFloor_Txt" shown below:
Manipulate messages as text, not XML, in your proxy service, as specified in "CamstarLotQuery/proxy/CamstarLotQueryTxt_Txt":
You might need to specify a SOAP Action in http header when calling a business service, depending on the target service.
One solution i can think of is to assign all the namespaces at the Parent Tag Level, and keep the attributes where they are applicable.
Example:
<RequestSelectionValues xmlns:q1="http://www.camstar.com/WebService/DataTypes" xmlns="http://www.camstar.com/WebService/WSShopFloor" xmlns:q2="http://www.camstar.com/WebService/DataTypes" xmlns:q3="http://www.camstar.com/WebService/DataTypes">
But the problem with this implementation is that since the namespace declaration is now Global, you have to declare your namespace prefixes (q1, q2, q3) to the blocks where the namespaces were previously defined.
Example:
<q3:serviceInfo q3:type="OnlineQuery_Info">
<q3:OnlineQuerySelection>
<q3:RequestValue>false</q3:RequestValue>
<q3:RequestMetadata>false</q3:RequestMetadata>
<q3:RequestSubFieldValues>false</q3:RequestSubFieldValues>
<q3:RequestSelectionValues>true</q3:RequestSelectionValues>
</q3:OnlineQuerySelection>
</q3:serviceInfo>
if this namespace prefix is not declared, then as per XML standards, the tag assume the 'default' namespace value - which will be the namespace of the parent.
However, even though this solution has a round-about way of implementation, this solution will definitely work.

Spring, property file, empty values

I have configured spring security with a ldap server (but continue reading, it's not a problem if you have no knowledge about it, this is really a spring problem). All runs like a charm. Here is the line I use for that:
<ldap-server ldif="" root="" manager-dn="" manager-password="" url="" id="ldapServer" />
If I fill ldif and root attributes, it will run an embeded server:
<ldap-server ldif="classpath://ldap.ldif" root="dc=springframework,dc=org" manager-dn="" manager-password="" url="" id="ldapServer" />
If I fill other fields, it will run a distant server:
<ldap-server ldif="" root="" manager-dn="dc=admin,dc=springframeworg,dc=org" manager-password="password" url="ldap://myldapserver.com/dc=springframeworg,dc=org" id="ldapServer" />
All this stuff run correctly. Now I want to use Spring mechanism to load such parameters from a property file:
So I replace attribute values like this:
<ldap-server ldif="${ldap.ldif.path}" root="${ldap.ldif.root}" manager-dn="${ldap.server.manager.dn}" manager-password="${ldap.server.manager.password}" url="${ldap.server.url}" id="ldapServer" />
and create a property file with:
ldap.server.url=
ldap.server.manager.dn=
ldap.server.manager.password=
ldap.ldif.path=
ldap.ldif.root=
Now, the funny part of the problem. If I fill the following properties in the file:
ldap.server.url=ldap://myldapserver.com/dc=springframeworg,dc=org
ldap.server.manager.dn=dc=admin,dc=springframeworg,dc=org
ldap.server.manager.password=password
ldap.ldif.path=
ldap.ldif.root=
It runs a distant server as expected.
If I fill the property file like this:
ldap.server.url=
ldap.server.manager.dn=
ldap.server.manager.password=
ldap.ldif.path= classpath:ldap.ldif
ldap.ldif.root= dc=springframeworg,dc=org
It does not run, complaining that the ldap url is missing. But the problem is that if I change the spring configuration from:
<ldap-server ldif="${ldap.ldif.path}" root="${ldap.ldif.root}" manager-dn="${ldap.server.manager.dn}" manager-password="${ldap.server.manager.password}" url="${ldap.server.url}" id="ldapServer" />
to (by just removing the reference to the variable ${ldap.server.url})
<ldap-server ldif="${ldap.ldif.path}" root="${ldap.ldif.root}" manager-dn="${ldap.server.manager.dn}" manager-password="${ldap.server.manager.password}" url="" id="ldapServer" />
It runs !
My thoughs are that spring does not replace the attribute value with the property config one if this one is empty. But I find it strange.
Can you give me some clue to understand that ? And what's the best to do to configure my ldap server via a property file ?
EDIT: this is due to a poor design choice (look at accepted answer), an issue has been opened on jira :
https://jira.springsource.org/browse/SEC-1966
Ok, I think this is a spring security bug.
If I debug and look at the class LdapServerBeanDefinition, there is a method called "parse". Here is an extract:
public BeanDefinition parse(Element elt, ParserContext parserContext) {
String url = elt.getAttribute(ATT_URL);
RootBeanDefinition contextSource;
if (!StringUtils.hasText(url)) {
contextSource = createEmbeddedServer(elt, parserContext);
} else {
contextSource = new RootBeanDefinition();
contextSource.setBeanClassName(CONTEXT_SOURCE_CLASS);
contextSource.getConstructorArgumentValues().addIndexedArgumentValue(0, url);
}
contextSource.setSource(parserContext.extractSource(elt));
String managerDn = elt.getAttribute(ATT_PRINCIPAL);
String managerPassword = elt.getAttribute(ATT_PASSWORD);
if (StringUtils.hasText(managerDn)) {
if(!StringUtils.hasText(managerPassword)) {
parserContext.getReaderContext().error("You must specify the " + ATT_PASSWORD +
" if you supply a " + managerDn, elt);
}
contextSource.getPropertyValues().addPropertyValue("userDn", managerDn);
contextSource.getPropertyValues().addPropertyValue("password", managerPassword);
}
...
}
If I debug here, all variables (url, managerDn, managerPassword...) are not replaced by the value specified in the property file. And so, url has the value ${ldap.server.url}, managerDn has the value ${ldap.server.manager.dn} and so on.
The method parse creates a bean, a context source that will be used further. And when this bean will be used, place holders will be replaced.
Here, we got the bug. The parse method check if url is empty or not. The problem is that url is not empty here because it has the value ${ldap.server.url}. So, the parse method creates a context source as a distant server.
When the created source will be used, it will replace the ${ldap.server.url} by empty value (like specified in the property file). And....... Bug !
I don't know really how to solve this for the moment, but I now understand why it bugs ;)
I cannot explain it, but I think you can fix your problem using defaulting syntax, available since Spring 3.0.0.RC1 (see).
In the chageg log you can read: PropertyPlaceholderConfigurer supports "${myKey:myDefaultValue}" defaulting syntax
Anyway, I think that the problem is because "" is valid value, but no value in the property file don't.
I think that url="" works because url attribute is of type xs:token in spring-security XSD and empty string is converted to null (xs:token is removing any leading or trailing spaces, so "" can be recognized as no value). Maybe the value of ${ldap.server.url} is resolved as empty string and that is why you've got an error.
You can try use Spring profiles to define different configurations of ldap server (see Spring Team Blog for details about profiles)
I believe there is an issue here while using place holders. The following will most probably solve the problem:
Create a class which extends PropertyPlaceHolderConfigurer and override its method convertPropertyValue()
in the method you can return the property as empty string if you find anything other than a string which is of type LDAP url i.e. ldap://myldapserver.com/dc=springframeworg,dc=org
Also you need to configure your new specialization of class PropertyPlaceHolderConfigurer in the context file.
Hope this helps.
You can define empty String in the application.properties file as following:
com.core.estimation.stopwords=\ \

Controlling WriteProfileString

Is it possible to specify the application name which is used by CWinApp::WriteProfileString()?
If I use CWinApp::SetRegistryKey to set the name of my company to "MyCompany", and I call AfxGetApp()->WriteProfileString in my application called "SomeApp", my string will be stored under the following registry key:
HKEY_CURRENT_USER\Software\MyCompany\SomeApp\...
The problem is that my users want to run multiple versions of SomeApp. So in order that the registry settings don't conflict I want to store them in keys like this:
HKEY_CURRENT_USER\Software\MyCompany\SomeApp 1.1\...
HKEY_CURRENT_USER\Software\MyCompany\SomeApp 2.0\...
etc.
I could replace all instances of WriteProfileString with my own function, but this would be quite difficult as it is used extensively in both our source code and some of the third-party libraries that we use.
Is there some way to force WriteProfileString to use a different string for the application name?
This code in the app constructor worked well:
free((void*)m_pszProfileName);
free((void*)m_pszRegistryKey);
m_pszRegistryKey = _tcsdup(L"nobugz");
m_pszProfileName = _tcsdup(L"myapp\\1.0");

Resources