Transforming spring-ws implementation to spring-integration-ws implementation - spring-ws

I have an implementation of web service (server side) using spring-ws. I would like to change my code to use spring-integration-ws (ws:inbound-gateway and channels). I have tried examples but still not sure if it is possible to transform my implementation. In short my I am using #Endpoint, #PayloadRoot, PayloadRootAnnotationMethodEndpointMapping and JMS (as transport). Please find below my implementation:
The endpoint class (MyEndpoint.java):
#Endpoint
public class MyEndpoint {
#PayloadRoot(localPart="getUserRequest", namespace="http://play.zahid.springint/Jibx")
public GetUserResponse getUserResponse(GetUserRequest request){
log.info("Start getUserResponse " + request);
GetUserResponse response = new GetUserResponse();
User user = new User();
user.setFirstName(request.getFirstName());
user.setLastName(request.getFirstName() + " Last");
response.setUser(user);
log.info("End getUserResponse " + response);
return response;
}
#PayloadRoot(localPart="sayHiUserRequest", namespace="http://play.zahid.springint/Jibx")
public SayHiResponse sayHiUserResponse(SayHiUserRequest request){
log.info("Start sayHiUserResponse " + request);
SayHiUserResponse response = new SayHiUserResponse();
response.setResponse("Hi " + request.getFirstName() + " " + request.getLastName());
log.info("End sayHiUserResponse " + response);
return response;
}
}
The spring xml file (applicationContext.xml):
<bean id="listenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="mqCachedConnectionFactory" />
<property name="destination" ref="defaultDestination" />
<property name="messageListener">
<bean class="org.springframework.ws.transport.jms.WebServiceMessageListener">
<property name="messageFactory" ref="messageFactory"/>
<property name="messageReceiver" ref="messageReceiver" />
</bean>
</property>
<property name="concurrentConsumers" value="1" />
<property name="acceptMessagesWhileStopping" value="false" />
<property name="recoveryInterval" value="10000" />
<property name="cacheLevelName" value="CACHE_CONSUMER" />
</bean>
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory" />
<bean id="messageReceiver" class="org.springframework.ws.soap.server.SoapMessageDispatcher">
<property name="endpointAdapters">
<list>
<bean id="endpointAdapter" class="org.springframework.ws.server.endpoint.adapter.GenericMarshallingMethodEndpointAdapter">
<constructor-arg ref="marshaller" />
</bean>
</list>
</property>
</bean>
<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping" />
For simplicity purpose I have removed the unnecessary codes and xml configuration.
Is there anyway to keep my endpoint class (MyEndpoint.java) as it is and use spring-integration-ws support (ws:inbound-gateway and channel)?
Let me know if you need any more information.
Thanks

Is there anyway to keep my endpoint class (MyEndpoint.java) as it is and use spring-integration-ws support (ws:inbound-gateway and channel)?
Yes you can.
I'll try to explain a simple integration-ws implementation for your situation:
applicationContext.xml:
<bean id="endpointMappings"
class="org.springframework.beans.factory.config.ListFactoryBean"
lazy-init="true">
<property name="sourceList">
<list>
<ref bean="uriEndpointMapping"/>
</list>
</property>
</bean>
<bean id="uriEndpointMapping"
class="org.springframework.ws.server.endpoint.mapping.UriEndpointMapping"
p:defaultEndpoint-ref="ws-inbound-gateway">
<property name="mappings">
<props>
<prop key="${yourEndPointUrl}">ws-inbound-gateway</prop>
</props>
</property>
</bean>
<int-ws:inbound-gateway id="ws-inbound-gateway"
request-channel="ws-request-channel"
reply-channel="ws-response-channel"
error-channel="ws-error-channel"
marshaller="marshaller"
unmarshaller="marshaller"/>
<int:channel id="ws-request-channel"/>
<int:channel id="ws-response-channel"/>
<int:channel id="ws-error-channel"/>
<int:chain input-channel="ws-request-channel" output-channel="ws-response-channel">
<int:service-activator ref="yourBean" method="getUserResponse"/>
</int:chain>
There are some points here.
You need to define a bean, MyEndpoint type, I named it yourBean here.
yourEndPointUrl defines your end point URL for getUserResponse method.
I've defined service-activator inside a chain, you can add logging or another thing inside this chain to enrich your handling mechanism.
You also need to have a router for routing your requests in to different methods of your bean.

Related

CAS attributes in wsfederation not being forwarded to CAS client

I am implementing an authentication system for a Tomcat web application that gets authenticated against ADFS using CAS. I am using unicon's CAS server with ADFS integration.
I have reached to the state where I can see that the required attributes reach the CAS server. But these attributes are not getting forwarded to the client. check the figure below:
In the above image, the attribute map is empty after authentication. Also, when the client application validates the ticket, the attribute map is empty. Ref picture below:
After getting authenticated, the attributes are visible in the logs, but they are not being loaded into attribute Map.
The deployerConfigContext.xml is as follows. The attributeRepository bean and allowed attributes property in serviceRegistryDao bean are the probably the main focus areas.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<bean id="authenticationManager"
class="org.jasig.cas.authentication.AuthenticationManagerImpl">
<property name="authenticationMetaDataPopulators">
<list>
<bean class="net.unicon.cas.support.wsfederation.authentication.WsFederationAuthenticationMetaDataPopulator" />
</list>
</property>
<property name="credentialsToPrincipalResolvers">
<list>
<bean class="net.unicon.cas.support.wsfederation.authentication.principal.WsFederationCredentialsToPrincipalResolver">
<property name="configuration" ref="wsFedConfig" />
</bean>
<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" >
<property name="attributeRepository" ref="attributeRepository" />
</bean>
<bean class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver" />
</list>
</property>
<property name="authenticationHandlers">
<list>
<bean class="net.unicon.cas.support.wsfederation.authentication.handler.support.WsFederationAuthenticationHandler" />
<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
p:httpClient-ref="httpClient" />
</list>
</property>
</bean>
<sec:user-service id="userDetailsService">
<sec:user name="##THIS SHOULD BE REPLACED##" password="notused" authorities="ROLE_ADMIN" />
</sec:user-service>
<bean id="attributeRepository"
class="org.jasig.services.persondir.support.StubPersonAttributeDao">
<property name="backingMap">
<map>
<entry key="emailaddress" value="upn" />
<!--<entry key="FirstName" value="username" />-->
<entry key="name" value="LastName" />
<entry key="costcent" value="costcent" />
<entry key="title" value="FirstName" />
</map>
</property>
</bean>
<bean
id="serviceRegistryDao"
class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl">
<property name="registeredServices">
<list>
<bean class="org.jasig.cas.services.RegexRegisteredService">
<property name="id" value="0" />
<property name="name" value="HTTP and IMAP" />
<property name="description" value="Allows HTTP(S) and IMAP(S) protocols" />
<property name="serviceId" value="^(https?|imaps?)://.*" />
<property name="evaluationOrder" value="10000001" />
<property name="allowedAttributes">
<list>
<value>upn</value>
<value>Department</value>
<value>costcent</value>
<value>LastName</value>
<value>FirstName</value>
<value>name</value>
<value>emailaddress</value>
<value>title</value>
<value>SAM-Account-Name</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
<bean id="auditTrailManager" class="com.github.inspektr.audit.support.Slf4jLoggingAuditTrailManager" />
<bean id="healthCheckMonitor" class="org.jasig.cas.monitor.HealthCheckMonitor">
<property name="monitors">
<list>
<bean class="org.jasig.cas.monitor.MemoryMonitor"
p:freeMemoryWarnThreshold="10" />
<bean class="org.jasig.cas.monitor.SessionMonitor"
p:ticketRegistry-ref="ticketRegistry"
p:serviceTicketCountWarnThreshold="5000"
p:sessionCountWarnThreshold="100000" />
</list>
</property>
</bean>
</beans>
The rest of the at CAS server is same as in the sample implementation of unicon's CAS-server implementation here
I've tried a lot of combinations in the mentioned beans. Being new to Spring I could not understand how to load the credentials in the attributeMap. Kindly guide me in forwarding the attributes sent by CAS server during authentication to the client application.
It looks like the WsFederationCredentialsToPrincipalResolver only extracts the principal id from the collection of attributes received, and ignores other attributes. So you only get the identity attribute defined in your configuration. You could for the time being, connect that resolver to your attribute repository and have it consume and retrieve attributes from there.
Note that CAS 4.2 supports and fixes this behavior and has built-in support for the ADFS integration. Your other option would be to extend WsFederationCredentialsToPrincipalResolver and have it process attributes and stuff them into the final principal created there by overriding the appropriate method.

CAS with Spring Security - Redirect loop

I've been configuring SSO solution using CAS for existing application with Spring Security integrated. I went through many answers on Stackoverflow but unfortunately anyone could help me. Could you please assist me with this issue from perspective of my configuration? Thank you in advance!
Here is my core security configuration:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<description>This context sets up security configurations of the core module.</description>
<!-- Enabled support for #Secured annotations on Spring bean methods -->
<security:global-method-security secured-annotations="enabled"
access-decision-manager-ref="accessDecisionManager"/>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="casAuthenticationProvider"/>
</security:authentication-manager>
<bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<property name="authenticationUserDetailsService">
<bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<constructor-arg ref="userDetailsService"/>
</bean>
</property>
<property name="serviceProperties" ref="serviceProperties"/>
<property name="ticketValidator">
<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<constructor-arg index="0" value="https://localhost:8443/cas"/>
</bean>
</property>
<property name="key" value="an_id_for_this_auth_provider_only"/>
</bean>
<security:http entry-point-ref="casEntryPoint">
<security:custom-filter ref="casFilter" position="CAS_FILTER"/>
</security:http>
<bean id="casFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
<bean id="casEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<property name="loginUrl" value="https://localhost:8443/cas/login"/>
<property name="serviceProperties" ref="serviceProperties"/>
</bean>
<bean id="exceptionTranslationFilter"
class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="casEntryPoint"/>
</bean>
<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
<property name="service" value="http://localhost:8080/myApp/j_spring_cas_security_check"/>
<property name="sendRenew" value="false"/>
</bean>
<!-- Service that retrieves UserDetails from DB for authentication -->
<bean id="userDetailsService" class="com.xxx.yyy.core.security.userdetails.DefaultUserDetailsService">
<property name="pmUserService" ref="pmUserService"/>
</bean>
<bean class="org.springframework.security.authentication.dao.ReflectionSaltSource" id="randomSaltSource">
<property name="userPropertyToUse" value="salt"/>
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<property name="decisionVoters">
<!-- At least one voter must agree that the user can access a resource -->
<bean class="org.springframework.security.access.vote.RoleVoter">
<!-- Override the default is 'ROLE_' prefix for role names -->
<property name="rolePrefix">
<util:constant static-field="com.xxx.yyy.core.security.SecurityConstants.AUTHORITY_PREFIX"/>
</property>
</bean>
</property>
</bean>
...and additional security module:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring- util-3.0.xsd">
<description>This context sets up security configurations of the web module</description>
<import resource="web-security-urls.xml"/>
<!-- Spring Security Filter Chain -->
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<security:filter-chain-map path-type="ant">
<security:filter-chain pattern="/**"
filters="securityContextPersistenceFilter,
logoutFilter,
authenticationFilter,
anonymousAuthenticationFilter,
exceptionTranslationFilter,
filterSecurityInterceptor"/>
</security:filter-chain-map>
</bean>
<!-- Responsible for propagation of SecurityContext on ThreadLocal from HttpSession -->
<bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>
<!-- define the logout exit point -->
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<!-- go to login page upon successful logout -->
<constructor-arg value="/"/>
<!-- Classes that get run when a user logs out -->
<constructor-arg>
<list>
<bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
</list>
</constructor-arg>
<property name="filterProcessesUrl" value="/j_spring_security_logout"/>
</bean>
<!-- Enable expression evaluation for Spring Security -->
<bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/>
<bean class="org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator">
<constructor-arg ref="filterSecurityInterceptor"/>
</bean>
And also we have separate module web-security-urls.xml where o.s.s.web.access.intercept.FilterSecurityInterceptor is configured to declare secure URLs
I am not sure if this is the exact problem, but looks like you might be missing a filter url here due to which you are getting a infinite redirect loop.
<bean id="casFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
you can add the filter url to filter only a particular url pattern
<property name="filterProcessesUrl" value="/j_spring_cas_security_check"/>
This helped me when i was stuck in the same type of problem.
I dont know if you still have this problem. I was facing the same and it is nerve-wracking. The issue of infinite redirect results when CasAuthenticationFilter is not able to determine if the incoming URL ( redirected URL from CAS server ) needs authentication.
if (!requiresAuthentication(request, response)) {
chain.doFilter(request, response);
return;
}
The requires authentication checks if the request is identified as "filterable" URL.
private static final class FilterProcessUrlRequestMatcher implements RequestMatcher {
private final String filterProcessesUrl;
private FilterProcessUrlRequestMatcher(String filterProcessesUrl) {
Assert.hasLength(filterProcessesUrl, "filterProcessesUrl must be specified");
Assert.isTrue(UrlUtils.isValidRedirectUrl(filterProcessesUrl), filterProcessesUrl + " isn't a valid redirect URL");
this.filterProcessesUrl = filterProcessesUrl;
}
public boolean matches(HttpServletRequest request) {
String uri = request.getRequestURI();
int pathParamIndex = uri.indexOf(';');
if (pathParamIndex > 0) {
// strip everything after the first semi-colon
uri = uri.substring(0, pathParamIndex);
}
if ("".equals(request.getContextPath())) {
return uri.endsWith(filterProcessesUrl);
}
return uri.endsWith(request.getContextPath() + filterProcessesUrl);
}
}
With a context path , the check basically checks if the "service URL" ends with request.getContextPath() + filterProcessesUrl
So, URL in the "service" property of ServiceProperties object needs to match to what is provided in filterProcessesUrl.
For example :
<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
<property name="service"
value="https://localhost:9444/SpringSecurity2.5/tbr/j_spring_cas_security_check" />
<property name="sendRenew" value="false" />
</bean>
<bean id="casFilter"
class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationSuccessHandler">
<bean
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler" />
</property>
<property name="filterProcessesUrl" value="/tbr/j_spring_cas_security_check"/>
</bean>
Note the matching pattern for /tbr/j_spring_cas_security_check in both these configurations.

Spring Security OAuth2 event log

We have required to include OAuth2 in our application. For that we have chosen spring security as an approach. I have checked out the Spraklr2 & Tonr2 sample projects from spring security projects page. It is working fine.
Our new requirement is, as a outh2 provider we have to save each request log (request from resource owner).. We have to save client id, resource owner username, requested url (a resource on resource server), grant etc..
I have googled for some time, but didn't find any clue.
Can some one help me with any idea to achieve this..
Thanks in advance
When user is authenticated using Spring Oauth, it publishes an event to AuthenticationEventPublisher. You can create a component that implements AuthenticationEventPublisher as follows:
#Component
public class AuditEvent implements AuthenticationEventPublisher{
#Override
public void publishAuthenticationSuccess(Authentication authentication) {
if(authentication instanceof UsernamePasswordAuthenticationToken) {
log(authentication.getName(), "Authentication successful");
}
}
#Override
public void publishAuthenticationFailure(AuthenticationException exception, Authentication authentication) {
log(authentication.getName(),"Authentication Failure:");
}
}
And check if authentication is of type UsernamePasswordAuthenticationToken. This will provide you with login event which you can log as required.
if you mean that you want to log all requests to /oauth/authorize, and /oauth/token, you can do so by implementing your own endpoints, that will delegate the calls to AuthorizationEndpoint and TokenEndpoint respectively.
you will have to configure it in your XML files, of course...
In the case if you havent found the answer, below is the approach I used to Intercept requests..
<http path-type="regex"
create-session="never" entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager"
use-expressions="true"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="myFilterSecurityInterceptor" />
<intercept-url pattern="/soap/*" access="isAnonymous()" method="GET" />
<intercept-url pattern="/advisor/[0-9a-zA-Z_]/all/clients/[0-9]/[0-9]" access="isFullyAuthenticated()"/>
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
<expression-handler ref="oauthWebExpressionHandler" />
</http>
<bean id="myFilterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="affirmativeBasedAccessDecisionManager"/>
<property name="securityMetadataSource" ref="myCustomBean"/>
</bean>
<bean id="affirmativeBasedAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<constructor-arg>
<list>
<bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter"/>
<bean id="authenticatedVoter" class="org.springframework.security.access.vote.AuthenticatedVoter"/>
</list>
</constructor-arg>
</bean>
<bean id="myCustomBean" class="MyCustomClass">
<constructor-arg>
<util:map />
</constructor-arg>
</bean>
<authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query=
"select username,password, enabled from oauth_users where username=?"
authorities-by-username-query=
"select username, role from oauth_user_roles where username =? " />
</authentication-provider>
</authentication-manager>
<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="realm" />
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased" xmlns="http://www.springframework.org/schema/beans">
<constructor-arg>
<list>
<bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
<bean class="org.springframework.security.web.access.expression.WebExpressionVoter"/>
</list>
</constructor-arg>
</bean>
<bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
public class MyCustomClass extends DefaultFilterInvocationSecurityMetadataSource {
public APILibSecurityMetadataSource(
LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap) {
super(requestMap);
}
#Override
public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
System.out.println(" My code in MyCustomClass Interceptor");
}
}

Spring WS "The security token could not be authenticated or authorized"

I'm creating a java client consumer for a web service using SpringWS-Security.
My Request SOAP (That I use in SOAP UI)
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:sch="http://myws.mycompany.com/myws/schema">
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="1"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken xmlns:wsu="http://schemas.xmlsoap.org/ws/2003/06/utility">
<wsse:Username>myUsernameString</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">123</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<sch:GetUserDetails idSender="5"/>
</soapenv:Body>
</soapenv:Envelope>
My servlet.xml in the WS.
<bean name="endpointMapping"
class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
<property name="interceptors">
<list>
<ref local="wsSecurityInterceptor" />
</list>
</property>
<bean id="wsSecurityInterceptor"
class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
<property name="validationActions" value="UsernameToken" />
<property name="validationCallbackHandler" ref="springSecurityCallbackHandler" />
</bean>
<bean id="springSecurityCallbackHandler"
class="org.springframework.ws.soap.security.wss4j.callback.SpringPlainTextPasswordValidationCallbackHandler">
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
<bean id="authenticationProvider" class="ws.security.CustomAuthenticationProviderImpl">
<property name="userCommonService" ref="userCommonService" />
<security:custom-authentication-provider/>
</bean>
<security:authentication-manager alias="authenticationManager" />.
In my Java Client - applicationContext.xml
<bean name="webserviceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<property name="defaultUri" value="http:/localhost:8080/myws-ws/" />
<property name="marshaller" ref="marshaller" />
<property name="unmarshaller" ref="unmarshaller" />
<property name="interceptors">
<list>
<ref local="wsSecurityInterceptor" />
</list>
</property>
</bean>
<oxm:jaxb2-marshaller id="marshaller"
contextPath="org.example.bean.schema" />
<oxm:jaxb2-marshaller id="unmarshaller"
contextPath="org.example.org.bean.schema" />
<bean id="client" class="example.client.impl.EfactClientImpl">
<property name="webServiceTemplate" ref="webserviceTemplate" />
</bean>
<bean id="wsSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
<property name="securementActions" value="UsernameToken"/>
</bean>
When I use SOAP UI to consume the service everything is going fine, I think I need a little help at the Java Client and its context because when I run it I got this error:
The security token could not be authenticated or authorized; nested exception is:
javax.security.auth.callback.UnsupportedCallbackException; nested exception is org.apache.ws.security.WSSecurityException: The security token could not be authenticated or authorized; nested exception is:
javax.security.auth.callback.UnsupportedCallbackException
When I debug my app I can notice that this element is crashing:
GetUserRequest request = new GetUserRequest();
request.setIdentifier(user.getIdentifier());
request.setPassword(user.getPassword());
GetUserResponse response = new GetUserResponse();
/* Crashing here. */
response = (GetUserResponse) getWebServiceTemplate().marshalSendAndReceive(request);
FYI: I always see this list of users in SpringWS with security, but what if I have a lot of users trying to access.
WS - [servlet-name]-servlet.xml
<bean id="callbackHandler" class="org.springframework.ws.soap.security.wss4j.callback.SimplePasswordValidationCallbackHandler">
<property name="users">
<props>
<prop key="Bert">Ernie</prop>
<prop key="Mickey">Mouse</prop>
</props>
</property>
</bean>
How can I resolve this UnsupportedCallbackException Exception?
You must specify SecurementUsername and SecurementPassword at call time. This is a programmatically example:
WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
webServiceTemplate.setDefaultUri(uri);
Wss4jSecurityInterceptor interceptor = new Wss4jSecurityInterceptor();
interceptor.setSecurementActions(securementActions);
interceptor.setSecurementMustUnderstand(true);
interceptor.setSecurementUsername(usuario);
interceptor.setSecurementPassword(contrasena);
webServiceTemplate.setInterceptors(new ClientInterceptor[] {interceptor});
I was getting this error when I upgraded from cfx 2.2.X to 2.7.X. Due to feature upgrades, the server side code was not able to read the password as a result the password was received as null by the server. Make sure the server received the correct username and password, which would fix this issue.

Remember-me- spring security

I am currently trying to implement remember me functionality in my website. Following is part of my configuration
<security:remember-me services-ref="rememberMeServices" />
<bean id="rememberMeServices" class="com.entertainment.ecom.web.auth.EcomRemembe rMeServices">
<property name="userDetailsService" ref="ecomUserDetailsService"/>
<property name="key" value="a23eef6dfd1514cb885f47070380ff18"/>
<property name="cookieName" value="ENTC"/>
<property name="tokenValiditySeconds" value="80000"/>
</bean>
My EcomRememberMeServices extends AbstractRememberMeServices & I have overridden onLoginFail & onLoginSuccess methods. My question is, from where my onLoginSuccess() method will be called?
I have tried to run above configuration & it was seen that onLoginFail gets called through RememberMeAuthenticationFilter(rememberMeServices.loginFail(request, response)) but when I checked source code for this filter, I could not find any call for onLoginSuccess() or loginSuccess() method. So do I need to call this explicitly?
In BasicAuthenticationFilter, there is a call for this method. So I tried to use it but still i does not work.(<http-basic/>). So can anyone please help me in this?
There is one more method logout(), which is called by logout filter. I guess you have to inject rememberMeServices into Login and Logout Filter as well (I am not sure if it can be done within http element in xml):
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg index="0" type="org.springframework.security.web.authentication.logout.LogoutSuccessHandler" ref="logoutSuccessHandler" />
<constructor-arg index="1">
<list value-type="org.springframework.security.web.authentication.logout.LogoutHandler">
<ref local="rememberMeServices"/>
</list>
</constructor-arg>
</bean>
and
<bean id="formLoginFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
...
<property name="rememberMeServices">
<ref local="rememberMeServices" />
</property>
</bean>

Resources