We are using spring-social to integrate our application to facebook.
In OAuth2AuthenticationService, scope is empty.
We set scope as a input on form.But it was not work and scope could not be set .
We could not get user email.
Are there any way to override "OAuth2AuthenticationService" scope variable ?
Not: Spring social verison is 1.1.0.BUILD-SNAPSHOT
We used spring social sample which contains security xml version
<form name="fb_signin" id="fb_signin" action="../auth/facebook"
method="post">
<input type="hidden" name="scope"
value="email,publish_stream,read_stream,offline_access" />
<button type="submit"> <img src="../images/social/facebook/sign-in-with-facebook.png" /> </button>
<!--
<input
type="image"
src="../images/social/facebook/sign-in-with-facebook.png"
align="right" />
-->
</form>
In your configuration, you need to specify scope as a property of the FacebookAuthenticationService. This is the service that handles calls to auth/facebook
In XML configuration, instead of:
<facebook:config app-id="${facebook.clientId}" app-secret="${facebook.clientSecret}"/>
use:
<bean id="connectionFactoryLocator" class="org.springframework.social.security.SocialAuthenticationServiceRegistry">
<property name="authenticationServices">
<list>
<bean class="org.springframework.social.facebook.security.FacebookAuthenticationService">
<constructor-arg value="${facebook.clientId}" />
<constructor-arg value="${facebook.clientSecret}" />
<property name="scope" value="email" />
</bean>
</list>
</property>
</bean>
This works with Spring Social 1.1.0.M3
To use the above XML config with Spring Social 1.1.0.RELEASE, use the minor edited version:
<bean id="connectionFactoryLocator" class="org.springframework.social.security.SocialAuthenticationServiceRegistry">
<property name="authenticationServices">
<list>
<bean class="org.springframework.social.facebook.security.FacebookAuthenticationService">
<constructor-arg value="${facebook.app.id}" />
<constructor-arg value="${facebook.app.secret}" />
<!-- Important: The next property name changed from "scope" to "defaultScope" in 1.1.0.M4 -->
<property name="defaultScope" value="email,user_friends" />
</bean>
</list>
</property>
</bean>
Only difference is in the property 'scope' which has been renamed to 'defaultScope' in the latest Spring Social version. Thanks to Victor Lyuboslavsky for sharing the initial config.
Related
Is it possible to have property resolution on the factory-bean field of a Spring bean declaration?
Example:
<bean factory-bean="$APP{some.factory.bean}" factory-method="...">
Spring version: 3.2.4
Adding a PropertyPlaceholderConfigurer to your spring context should work:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:yourfile.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="false" />
<property name="ignoreUnresolvablePlaceholders" value="false" />
</bean>
You can declare your propertyName in the file and then use it like:
<bean factory-bean="${propertyName}" factory-method="...">
Just encountered the same issue (using Spring 4.2.0). It seems that property resolution for factory beans does not work despite what they say in SPR-12638. I've ended up using ProxyFactoryBean as a workaround.
The desired configuration, which does not work:
<!-- The bean to be created: factory type determined in runtime -->
<bean id="..." factory-bean="factory-${factory.type}" factory-method="..." />
<!-- Possible factories -->
<bean id="factory-A" class="..." />
<bean id="factory-B" class="..." />
<bean id="factory-C" class="..." />
The workaround that I've found:
<!-- The bean to be created: use factory proxy -->
<bean id="..." factory-bean="factory-proxy" factory-method="..." />
<!-- The factory proxy: real factory type determined in runtime -->
<bean id="factory-proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="factory-${factory-type}" />
</bean>
<!-- Possible factories -->
<bean id="factory-A" class="..." />
<bean id="factory-B" class="..." />
<bean id="factory-C" class="..." />
Enjoy :)
I have one Spring WS servlet with two endpoints and two wsdl files. Requests/responses are being validated with PayloadValidatingInterceptor. Content of spring-ws-servlet.xml:
<context:component-scan base-package="cz.legend.mzv.spi.ws.ei.endpoints" />
<context:component-scan base-package="cz.legend.mzv.spi.ws.de.endpoints" />
<sws:annotation-driven />
<sws:static-wsdl id="entityImport" location="classpath:/wsdl/entityImport.wsdl" />
<sws:static-wsdl id="documentEvidence"
location="classpath:/wsdl/documentEvidence.wsdl" />
<oxm:jaxb2-marshaller id="jaxb2Marshaller"
contextPath="cz.legend.mzv.spi.ws.jaxb.generated" />
<bean id="endpointAdapter" class="org.springframework.ws.server.endpoint.adapter.MarshallingMethodEndpointAdapter">
<constructor-arg ref="jaxb2Marshaller" />
</bean>
<sws:interceptors>
<bean
class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
<property name="schema" value="classpath:/xsd/vums_spi_de.xsd" />
<property name="validateRequest" value="true" />
<property name="validateResponse" value="true" />
</bean>
</sws:interceptors>
Interceptor is applied on both services. I need the interceptor to be applied only on service described by documentEvidence.wsdl. One option is to make two separate spring servlets. But I want to use only one servlet.
Solution:
Alternatively, you can use or
elements to specify for which payload root name or SOAP action the
interceptor should apply:
<sws:interceptors>
<bean class="samples.MyGlobalInterceptor"/>
<sws:payloadRoot namespaceUri="http://www.example.com">
<bean class="samples.MyPayloadRootInterceptor"/>
</sws:payloadRoot>
<sws:soapAction value="http://www.example.com/SoapAction">
<bean class="samples.MySoapActionInterceptor1"/>
<ref bean="mySoapActionInterceptor2"/>
</sws:soapAction>
</sws:interceptors>
I am trying to enable role hierarchy voting in Spring Security when authenticating using Waffle NTML but having some unknown issues in that the inherited roles do not appear as authorities on the principal as expected preventing hasRole expressions in both the intercept urls and using the authorize jsp taglibs.
I have been integrating waffle based on the following guide: https://github.com/dblock/waffle/blob/master/Docs/spring/SpringSecuritySingleSignOnFilter.md
This works within the application as expected on its own using the standard RoleVoter but the problem starts when I try to customise it to use the RoleHierarchyVoter which I have also tested on its own (using an LDAP Authentication Provider) and the role hierarchies work exactly as expected.
The config for the combined Waffle and RoleHierarchyVoter approach is as follows:
Waffle Specfic Config
<!-- windows authentication provider -->
<bean id="waffleWindowsAuthProvider" class="waffle.windows.auth.impl.WindowsAuthProviderImpl" />
<!-- collection of security filters -->
<bean id="negotiateSecurityFilterProvider" class="waffle.servlet.spi.NegotiateSecurityFilterProvider">
<constructor-arg ref="waffleWindowsAuthProvider" />
</bean>
<bean id="basicSecurityFilterProvider" class="waffle.servlet.spi.BasicSecurityFilterProvider">
<constructor-arg ref="waffleWindowsAuthProvider" />
</bean>
<bean id="waffleSecurityFilterProviderCollection" class="waffle.servlet.spi.SecurityFilterProviderCollection">
<constructor-arg>
<list>
<ref bean="negotiateSecurityFilterProvider" />
<ref bean="basicSecurityFilterProvider" />
</list>
</constructor-arg>
</bean>
<bean id="negotiateSecurityFilterEntryPoint" class="waffle.spring.NegotiateSecurityFilterEntryPoint">
<property name="Provider" ref="waffleSecurityFilterProviderCollection" />
</bean>
<!-- spring security filter -->
<bean id="waffleNegotiateSecurityFilter" class="waffle.spring.NegotiateSecurityFilter">
<property name="Provider" ref="waffleSecurityFilterProviderCollection" />
<property name="AllowGuestLogin" value="false" />
<property name="PrincipalFormat" value="fqn" />
<property name="RoleFormat" value="fqn" />
<property name="GrantedAuthorityFactory" ref="simpleGrantedAuthorityFactory" />
<!-- set the default granted authority to null as we don't need to assign a default role of ROLE_USER -->
<property name="defaultGrantedAuthority"><null/></property>
</bean>
<!-- custom granted authority factory so the roles created are based on the name rather than the fqn-->
<bean id="simpleGrantedAuthorityFactory" class="xx.yy.zz.SimpleGrantedAuthorityFactory">
<constructor-arg name="prefix" value="ROLE_"/>
<constructor-arg name="convertToUpperCase" value="true"/>
</bean>
Familiar Spring Security Config
<!-- declare the entry point ref as the waffle defined entry point -->
<sec:http use-expressions="true"
disable-url-rewriting="true"
access-decision-manager-ref="accessDecisionManager"
entry-point-ref="negotiateSecurityFilterEntryPoint" >
<sec:intercept-url pattern="/**" access="isAuthenticated()" requires-channel="any"/>
.
. access denied handlers, concurrency control, port mappings etc
.
<sec:custom-filter ref="waffleNegotiateSecurityFilter" position="BASIC_AUTH_FILTER" />
</sec:http>
<!-- spring authentication provider -->
<sec:authentication-manager alias="authenticationProvider" />
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<property name="decisionVoters">
<list>
<ref bean="roleHierarchyVoter" />
<bean class="org.springframework.security.web.access.expression.WebExpressionVoter">
<property name="expressionHandler">
<bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
<property name="roleHierarchy" ref="roleHierarchy"/>
</bean>
</property>
</bean>
</list>
</property>
</bean>
<bean id="roleHierarchy" class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
<property name="hierarchy">
<value>
ROLE_TEST_1 > ROLE_TEST_2
ROLE_TEST_2 > ROLE_TEST_3
ROLE_TEST_3 > ROLE_TEST_4
</value>
</property>
</bean>
<bean id="roleHierarchyVoter"
class="org.springframework.security.access.vote.RoleHierarchyVoter">
<constructor-arg ref="roleHierarchy"/>
</bean>
Managed to fix my issues which was down to an omission in my http namespace configuration which I found from hours of debugging the spring security source.
The issue was how the DefaultWebSecurityExpressionHandler was created. In the snipped above it had created it as inner bean inside the bean definition of the accessDecisionManager:
<bean class="org.springframework.security.web.access.expression.WebExpressionVoter">
<property name="expressionHandler">
<bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
<property name="roleHierarchy" ref="roleHierarchy"/>
</bean>
</property>
</bean>
With this the role heirachies are used to determine whether access should be granted when processing rules defined as intercept urls such as:
<sec:intercept-url pattern="/**" access="isAuthenticated()" requires-channel="any"/>
But if you want to check authorisation using the JSP Authorize taglib as below (this is in freemarker) it will not work as the roleHeirachies do not get taken into account:
<#security.authorize access="hasRole('ROLE_TEST_1)">
<p>You have role 1</p>
</#security.authorize>
<#security.authorize access="hasRole('ROLE_TEST_4')">
<p>You have role 4</p>
</#security.authorize>
This is because the DefaultWebSecurityExpressionHandler created as an inner bean is only used within the access decision manager but for taglib expressions a NEW default bean will be created (which doesn't use the RoleHierarchy) unless an security http namespace expression-handler is defined.
So, to resolve my issues I created the bean DefaultWebSecurityExpressionHandler and referenced it within my WebExpressionVoter bean definition and also used it as the expression handler as follows:
<sec:http ... >
.
. access denied handlers, concurrency control, port mappings etc
.
<sec:expression-handler ref="defaultWebSecurityExpressionHandler" />
</sec:http>
<bean id="defaultWebSecurityExpressionHandler"
class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
<property name="roleHierarchy" ref="roleHierarchy"/>
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<property name="decisionVoters">
<list>
<ref bean="roleHierarchyVoter" />
<bean class="org.springframework.security.web.access.expression.WebExpressionVoter">
<property name="expressionHandler" ref="defaultWebSecurityExpressionHandler"/>
</bean>
</list>
</property>
</bean>
Making these changes ensures the roleHeirarchies are taken into account for both Web Security Expressions defined as intercept URLs via the http namespace and also expressions using the JSP Authorize taglib.
I read the Restlet documentation on how to implement Basic HTTP Authentication but mine is not working when I make a request to a resource. Any reason why mine is not working?
Application Context:
<!-- Used to map routes to Restlet resources -->
<bean id="router" class="org.restlet.ext.spring.SpringRouter">
<property name="attachments">
<map>
<!-- I removed the actual values because it references a company -->
<entry key="/getCompanies" value="ClassResource" />
<entry key="/getList" value="ClassResource" />
<entry key="/getFile" value="ClassResource" />
<entry key="/archiveFile" value="ClassResource" />
</map>
</property>
</bean>
<!-- Used to have login authentication for requests -->
<bean id="challengeAuthenticator" class="org.restlet.security.ChallengeAuthenticator">
<constructor-arg><null /></constructor-arg>
<!-- Sets the Challenge scheme parameter to the static class member -->
<constructor-arg value="#{ T(org.restlet.data.ChallengeScheme).HTTP_BASIC }" />
<constructor-arg value="WSRealm" />
<property name="next" ref="router" />
</bean>
<!-- Creates a restlet component that contains the server and attachs the application -->
<bean id="restletComponent" class="org.restlet.ext.spring.SpringComponent">
<!-- Sets the server in the Restlet component -->
<property name="server" ref="server" />
<!-- Attachs the application to the virtual host -->
<property name="defaultTarget" ref="application" />
</bean>
I was assuming that since I set the challenge Authenticator next method to the router when I make a request it hits the router and hits the authenticator before going to the resource.
Java Code:
ApplicationContext springContext = new GenericXmlApplicationContext("applicationContext.xml");
Component restletComponent = (Component) springContext.getBean("restletComponent");
GetFilesApplication application = (GetFilesApplication) springContext.getBean("application");
ChallengeAuthenticator challengeAuthenticator =
(ChallengeAuthenticator) springContext.getBean("challengeAuthenticator");
Config config = application.getConfig();
MapVerifier mapVerifier = new MapVerifier();
// Puts the user name and password (encrypted) in the map verifier
mapVerifier.getLocalSecrets().put(config.getUsername(), StringCipher.encrypt(
config.getPassword()).toCharArray());
challengeAuthenticator.setVerifier(mapVerifier);
restletComponent.getDefaultHost().attachDefault(challengeAuthenticator);
// Start the component
restletComponent.start();
Like I said earlier, the only thing I can see wrong with it is, I am unsure about setting challenge authenticator next method value to the router.
Also for the client side added:
clientResource.setChallengeResponse(ChallengeScheme.HTTP_BASIC, "correctUser", StringCipher.encrypt("password"));
Forgot to mention that I am testing this on my local machine the client and the web service.
Solved it. It took so long to figure out but here is how I got it to work.
Java Code on Server Side:
// Removed and added to Application Context
restletComponent.getDefaultHost().attachDefault(challengeAuthenticator);
Application Context:
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>configuration.properties</value>
<value>log4j.properties</value>
</list>
</property>
</bean>
<bean id="config" class="Config class path location">
<property name="filePath" value="${Properties entry value}"/>
<property name="archivePath" value="${Properties entry value}"/>
<property name="username" value="${Properties entry value}"/>
<property name="password" value="${Properties entry value}"/>
</bean>
<!-- Restlet application -->
<bean id="application" class="Application class path location" scope="singleton">
<!-- Sets the router for the application -->
<property name="root" ref="router" />
<property name="config" ref="config" />
</bean>
<!-- Sets up the server -->
<bean id="server" class="org.restlet.ext.spring.SpringServer">
<constructor-arg value="${Properties entry value}" />
<constructor-arg value="${Properties entry value}" />
</bean>
<!-- Used to map routes to Restlet resources -->
<bean id="router" class="org.restlet.ext.spring.SpringRouter">
<property name="attachments">
<map>
<entry key="/getCompanies" value="Resource class path location" />
<entry key="/getList" value="Resource class path location" />
<entry key="/getFile" value="Resource class path location" />
<entry key="/archiveFile" value="Resource class path location" />
</map>
</property>
</bean>
<!-- Creates a restlet component that contains the server and attachs the application -->
<bean id="restletComponent" class="org.restlet.ext.spring.SpringComponent">
<!-- Sets the server in the Restlet component -->
<property name="server" ref="server" />
<!-- Attachs the application to the virtual host -->
<property name="defaultTarget" ref="application" />
<property name="defaultHost" ref="defaultHost" />
</bean>
<!-- Used to have login authentication for requests -->
<bean id="challengeAuthenticator" class="org.restlet.security.ChallengeAuthenticator">
<constructor-arg><null /></constructor-arg>
<!-- Sets the Challenge scheme parameter to the static class member -->
<constructor-arg value="#{ T(org.restlet.data.ChallengeScheme).HTTP_BASIC }" />
<constructor-arg value="GetWSRealm" />
<property name="next" ref="application" />
</bean>
<bean id="defaultHost" class="org.restlet.ext.spring.SpringHost">
<constructor-arg ref="restletComponent" />
<property name="defaultAttachment" ref="challengeAuthenticator" />
</bean>
Hope this helps others trying to get their application working. It took me a while to get this to work. :)
I am working on a web app where I have most of my pages making use of apache tiles (2.1.2), but a few of them need to just be plain jsps.
I am having a problem in that both an InternalResourceViewResolver and a UrlBasedViewResolver will try to resolve the view no matter what, so that no matter which ordering I use, it will either fail on the plain JSP pages, or on the tiles pages.
Here is the config:
<bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
<property name="order" value="0"/>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="1"/>
</bean>
To make it more clear what I am trying to do, I need to be able to have view states like this:
<view-state id="someState" view="/someDir/foo"><!--render foo.jsp -->
<transition on="foo" to="bar"/>
</view-state>
<view-state id="someState" view="something.core"><!--render tile defintion named 'something.core' -->
<transition on="foo" to="bar"/>
</view-state>
Does anyone know how to configure things so that I can get it to render tiles definitions and plain jsps?
As you say, you cannot chain these together. The javadoc for both states clearly that they must both be at the end of the resolver chain.
I suggest that if you really need to use these togather, then you write a simple custom implementation of ViewResolver which takes the view name, and decides which of your two "real" view resolvers to delegate to. This assumes that you can tell which resolver to call based on the view name.
So you'd define a custom ViewResolver like this:
public class MyViewResolver implements ViewResolver {
private ViewResolver tilesResolver;
private ViewResolver jspResolver;
public void setJspResolver(ViewResolver jspResolver) {
this.jspResolver = jspResolver;
}
public void setTilesResolver(ViewResolver tilesResolver) {
this.tilesResolver = tilesResolver;
}
public View resolveViewName(String viewName, Locale locale) throws Exception {
if (isTilesView(viewName)) {
return tilesResolver.resolveViewName(viewName, locale);
} else {
return jspResolver.resolveViewName(viewName, locale);
}
}
private boolean isTilesView(String viewName) {
.....
}
}
You'd need to implement the isTilesView method to decide which resolver to delegate to.
In the XML config, define this new view resolver, and make sure it appears before the other ones.
<bean class="MyViewResolver">
<property name="tilesResolver" ref="tilesViewResolver"/>
<property name="jspResolver" ref="viewResolver"/>
</bean>
I've just solved the same problem by splitting the *-servlet.xml config file in two; in my case the main application uses Tiles, but I want QUnit tests to be simple JSPs.
app-servlet.xml contains only the Tiles view resolver, tests-servlet.xml only contains the JSP view resolver and web.xml mappings are dispatching requests to the correct servlet basing on the URL.
<servlet-mapping>
<servlet-name>app</servlet-name> <!-- will reach app-servlet.xml -->
<url-pattern>/foo</url-pattern> <!-- will use "foo" Tile -->
<url-pattern>/bar</url-pattern> <!-- will use "bar" Tile -->
</servlet-mapping>
<servlet-mapping>
<servlet-name>tests</servlet-name> <!-- will reach tests-servlet.xml -->
<url-pattern>/foo-test</url-pattern> <!-- will use foo-test.jsp -->
<url-pattern>/bar-test</url-pattern> <!-- will use bar-test.jsp -->
</servlet-mapping>
It looks like you're on the right track, but the thing to bear in mind is that some view resolvers behave as if they have always resolved the view. You need to make sure to put such resolvers last in your ordering. I believe the Tiles view is one such.
Edit: whoops... yes, the other poster is correct, both of these resolvers will do 'always match' so you can't use them both in a chain. Another alterative would be to try to extend the TilesView to do a simple JSP render if it cant find a configured tile view.
Yes you can use any number of view resolver in your your project.
So you can use both 'tiles View resolver' and 'Internal view resolver' in same project. .
you have to configure a ContentNegotiatingViewResolver . .
and give order value in your view resolvers.
<property name="order" value="int Value here" />
like I have given tiles view resolver 2 and internalviewresolver 3. .It will first check in tiles definitions if a view is not found in tiles it will be checked in InternaiViewResolver
here is some configurations that works for me.
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1" />
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
<entry key="html" value="text/html" />
</map>
</property>
<property name="parameterName" value="accept"></property>
<property name="favorParameter" value="true"></property>
<property name="defaultContentType" value="text/html"></property>
<property name="viewResolvers">
<list>
<ref bean="tilesViewResolver" />
<ref bean="internalViewResolver" />
</list>
</property>
<property name="defaultViews">
<list>
<bean
class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
</list>
</property>
<property name="ignoreAcceptHeader" value="true" />
</bean>
<!-- Configures the Tiles layout system -->
<bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer"
id="tilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/layouts/layouts.xml</value>
<!-- Scan views directory for Tiles configurations -->
<value>/WEB-INF/views/**/views.xml</value>
</list>
</property>
</bean>
<bean id="tilesViewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver"
p:viewClass="org.springframework.web.servlet.view.tiles2.TilesView">
<property name="order" value="3" />
</bean>
<bean id="internalViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="order" value="2" />
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
I resolved this issue by simply adding tiles definition for plain jsp's layout, like this:
<definition name="plain-jsp.layout" template="/WEB-INF/layouts/plainJsp.jspx" >
<put-attribute name="content" value=""/>
</definition>
Then you just can use this layout as template for including your simple jsp files.
<definition name="catalog/details" extends="plain-jsp.layout">
<put-attribute name="content" value="/WEB-INF/views/catalog/details.jspx"/>
</definition>
And layout template file:
<html xmlns:tiles="http://tiles.apache.org/tags-tiles"
xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
<jsp:output doctype-root-element="HTML"/>
<jsp:directive.page contentType="text/html;charset=UTF-8" />
<jsp:directive.page pageEncoding="UTF-8" />
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=8" />
</head>
<body>
<div id="content">
<tiles:insertAttribute name="content"/>
</div>
</body>
</html>