SWS-350
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>spring-ws-samples</artifactId>
|
||||
<groupId>org.springframework.ws</groupId>
|
||||
@@ -134,7 +135,8 @@
|
||||
<phase>process-classes</phase>
|
||||
<configuration>
|
||||
<tasks>
|
||||
<java classname="org.apache.openjpa.enhance.PCEnhancer" classpathref="maven.runtime.classpath" dir="target/classes" fork="true" />
|
||||
<java classname="org.apache.openjpa.enhance.PCEnhancer"
|
||||
classpathref="maven.runtime.classpath" dir="target/classes" fork="true"/>
|
||||
</tasks>
|
||||
</configuration>
|
||||
<goals>
|
||||
@@ -307,49 +309,12 @@
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-remoting</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-support</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>commons-collections</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security-tiger</artifactId>
|
||||
<version>1.0.5</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core-tiger</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.activemq</groupId>
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package org.springframework.ws.samples.airline.security;
|
||||
|
||||
import org.acegisecurity.GrantedAuthority;
|
||||
import org.acegisecurity.GrantedAuthorityImpl;
|
||||
import org.acegisecurity.userdetails.UserDetails;
|
||||
import org.springframework.security.GrantedAuthority;
|
||||
import org.springframework.security.GrantedAuthorityImpl;
|
||||
import org.springframework.security.userdetails.UserDetails;
|
||||
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ws.samples.airline.security;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.security.Authentication;
|
||||
import org.springframework.security.context.SecurityContext;
|
||||
import org.springframework.security.context.SecurityContextHolder;
|
||||
import org.springframework.security.userdetails.UserDetails;
|
||||
import org.springframework.security.userdetails.UserDetailsService;
|
||||
import org.springframework.security.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.ws.samples.airline.dao.FrequentFlyerDao;
|
||||
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
|
||||
import org.springframework.ws.samples.airline.service.NoSuchFrequentFlyerException;
|
||||
|
||||
/**
|
||||
* Implementation of the <code>FrequentFlyerSecurityService</code> that uses Spring Security.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class SpringFrequentFlyerSecurityService implements FrequentFlyerSecurityService, UserDetailsService {
|
||||
|
||||
private FrequentFlyerDao frequentFlyerDao;
|
||||
|
||||
public SpringFrequentFlyerSecurityService(FrequentFlyerDao frequentFlyerDao) {
|
||||
this.frequentFlyerDao = frequentFlyerDao;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public FrequentFlyer getCurrentlyAuthenticatedFrequentFlyer() {
|
||||
SecurityContext context = SecurityContextHolder.getContext();
|
||||
Authentication authentication = context.getAuthentication();
|
||||
if (authentication != null) {
|
||||
if (authentication.getPrincipal() instanceof FrequentFlyerDetails) {
|
||||
FrequentFlyerDetails details = (FrequentFlyerDetails) authentication.getPrincipal();
|
||||
return details.getFrequentFlyer();
|
||||
}
|
||||
else {
|
||||
return (FrequentFlyer) authentication.getPrincipal();
|
||||
}
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public FrequentFlyer getFrequentFlyer(String username) throws NoSuchFrequentFlyerException {
|
||||
FrequentFlyer frequentFlyer = frequentFlyerDao.get(username);
|
||||
if (frequentFlyer != null) {
|
||||
return frequentFlyer;
|
||||
}
|
||||
else {
|
||||
throw new NoSuchFrequentFlyerException(username);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
|
||||
FrequentFlyer frequentFlyer = frequentFlyerDao.get(username);
|
||||
if (frequentFlyer != null) {
|
||||
return new FrequentFlyerDetails(frequentFlyer);
|
||||
}
|
||||
else {
|
||||
throw new UsernameNotFoundException("Frequent flyer '" + username + "' not found");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import org.springframework.ws.samples.airline.service.NoSuchFrequentFlyerExcepti
|
||||
/**
|
||||
* Stub implementation of <code>FrequentFlyerSecurityService</code>. This implementation is used by default by {@link
|
||||
* org.springframework.ws.samples.airline.service.impl.AirlineServiceImpl}, to allow it to run without depending on
|
||||
* Acegi Security.
|
||||
* Spring Security.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
|
||||
@@ -17,11 +17,9 @@ package org.springframework.ws.samples.airline.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.acegisecurity.annotation.Secured;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.ws.samples.airline.domain.Flight;
|
||||
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
|
||||
import org.springframework.ws.samples.airline.domain.Passenger;
|
||||
@@ -74,8 +72,6 @@ public interface AirlineService {
|
||||
* @see org.springframework.ws.samples.airline.domain.Passenger
|
||||
* @see org.springframework.ws.samples.airline.domain.FrequentFlyer
|
||||
*/
|
||||
@Transactional(readOnly = false,
|
||||
rollbackFor = {NoSuchFlightException.class, NoSeatAvailableException.class, NoSuchFrequentFlyerException.class})
|
||||
Ticket bookFlight(String flightNumber, DateTime departureTime, List<Passenger> passengers)
|
||||
throws NoSuchFlightException, NoSeatAvailableException, NoSuchFrequentFlyerException;
|
||||
|
||||
@@ -84,6 +80,5 @@ public interface AirlineService {
|
||||
*
|
||||
* @return the amount of frequent flyer miles
|
||||
*/
|
||||
@Secured({"ROLE_FREQUENT_FLYER"})
|
||||
int getFrequentFlyerMileage();
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.joda.time.DateTime;
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.annotation.Secured;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -134,6 +135,7 @@ public class AirlineServiceImpl implements AirlineService {
|
||||
return flights;
|
||||
}
|
||||
|
||||
@Secured({"ROLE_FREQUENT_FLYER"})
|
||||
public int getFrequentFlyerMileage() {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Using " + frequentFlyerSecurityService + " for security");
|
||||
|
||||
@@ -1,83 +1,40 @@
|
||||
<?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:aop="http://www.springframework.org/schema/aop"
|
||||
xmlns:security="http://www.springframework.org/schema/security"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
|
||||
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
|
||||
|
||||
<description>
|
||||
This application context contains the WS-Security and Acegi beans.
|
||||
This application context contains the WS-Security and Sprign Security beans.
|
||||
</description>
|
||||
|
||||
<aop:config>
|
||||
<aop:pointcut id="getFrequentFlyerMileage"
|
||||
expression="execution(* org.springframework.ws.samples.airline.service.AirlineService+.*(..))"/>
|
||||
<aop:advisor advice-ref="methodSecurityInterceptor" pointcut-ref="getFrequentFlyerMileage"/>
|
||||
</aop:config>
|
||||
<security:global-method-security secured-annotations="enabled"/>
|
||||
|
||||
<security:authentication-provider user-service-ref="securityService"/>
|
||||
|
||||
<bean id="securityService"
|
||||
class="org.springframework.ws.samples.airline.security.AcegiFrequentFlyerSecurityService">
|
||||
class="org.springframework.ws.samples.airline.security.SpringFrequentFlyerSecurityService">
|
||||
<description>
|
||||
A security service used to obtain Frequent Flyer information.
|
||||
</description>
|
||||
<constructor-arg ref="frequentFlyerDao"/>
|
||||
</bean>
|
||||
|
||||
<!-- ===================== WS-SECURITY ============================== -->
|
||||
|
||||
<bean id="wsSecurityInterceptor" class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor">
|
||||
<description>
|
||||
This interceptor validates incoming messages according to the policy defined in 'securityPolicy.xml'.
|
||||
The policy defines that all incoming requests must have a UsernameToken with a password digest in it.
|
||||
The actual authentication is performed by the Acegi callback handler.
|
||||
The actual authentication is performed by the Spring Security callback handler.
|
||||
</description>
|
||||
<property name="secureResponse" value="false"/>
|
||||
<property name="policyConfiguration"
|
||||
value="classpath:org/springframework/ws/samples/airline/security/securityPolicy.xml"/>
|
||||
<property name="callbackHandler">
|
||||
<bean class="org.springframework.ws.soap.security.xwss.callback.acegi.AcegiDigestPasswordValidationCallbackHandler">
|
||||
<bean class="org.springframework.ws.soap.security.xwss.callback.SpringDigestPasswordValidationCallbackHandler">
|
||||
<property name="userDetailsService" ref="securityService"/>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
|
||||
<!-- ======================== ACEGI AUTHENTICATION ======================= -->
|
||||
|
||||
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
|
||||
<description>
|
||||
A standard Acegi authentication manager.
|
||||
</description>
|
||||
<property name="providers">
|
||||
<bean class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
|
||||
<property name="userDetailsService" ref="securityService"/>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="loggerListener" class="org.acegisecurity.event.authentication.LoggerListener"/>
|
||||
|
||||
<!-- ======================== ACEGI AUTHORIZATION =========================== -->
|
||||
|
||||
<bean id="methodSecurityInterceptor"
|
||||
class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
|
||||
<property name="authenticationManager">
|
||||
<ref local="authenticationManager"/>
|
||||
</property>
|
||||
<property name="accessDecisionManager">
|
||||
<bean class="org.acegisecurity.vote.AffirmativeBased">
|
||||
<property name="decisionVoters">
|
||||
<bean class="org.acegisecurity.vote.RoleVoter"/>
|
||||
</property>
|
||||
</bean>
|
||||
</property>
|
||||
<property name="objectDefinitionSource">
|
||||
<bean class="org.acegisecurity.intercept.method.MethodDefinitionAttributes">
|
||||
<property name="attributes">
|
||||
<bean class="org.acegisecurity.annotation.SecurityAnnotationAttributes"/>
|
||||
</property>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -17,23 +17,24 @@
|
||||
package org.springframework.ws.samples.airline.security;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.acegisecurity.context.SecurityContext;
|
||||
import org.acegisecurity.context.SecurityContextHolder;
|
||||
import org.acegisecurity.context.SecurityContextImpl;
|
||||
import org.acegisecurity.providers.TestingAuthenticationToken;
|
||||
import static org.easymock.EasyMock.*;
|
||||
|
||||
import org.springframework.security.context.SecurityContext;
|
||||
import org.springframework.security.context.SecurityContextHolder;
|
||||
import org.springframework.security.context.SecurityContextImpl;
|
||||
import org.springframework.security.providers.TestingAuthenticationToken;
|
||||
import org.springframework.ws.samples.airline.dao.FrequentFlyerDao;
|
||||
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
|
||||
|
||||
public class AcegiFrequentFlyerSecurityServiceTest extends TestCase {
|
||||
public class SpringFrequentFlyerSecurityServiceTest extends TestCase {
|
||||
|
||||
private AcegiFrequentFlyerSecurityService securityService;
|
||||
private SpringFrequentFlyerSecurityService securityService;
|
||||
|
||||
private FrequentFlyerDao flyerDaoMock;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
flyerDaoMock = createMock(FrequentFlyerDao.class);
|
||||
securityService = new AcegiFrequentFlyerSecurityService(flyerDaoMock);
|
||||
securityService = new SpringFrequentFlyerSecurityService(flyerDaoMock);
|
||||
}
|
||||
|
||||
public void testGetCurrentlyAuthenticatedFrequentFlyer() throws Exception {
|
||||
Reference in New Issue
Block a user