2013-05-01 245 views
0

第一:我的問題看起來像No AuthenticationProvider found for UsernamePasswordAuthenticationToken,但是實現在那裏找到的解決方案並沒有幫助我更進一步。當試圖使用@ PreAuthorize對單元測試進行單元測試時,我得到「沒有爲UsernamePasswordAuthenticationToken找到AuthenticationProvider」

我的應用程序上下文如下:

<?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:jpa="http://www.springframework.org/schema/data/jpa" 
xmlns:security="http://www.springframework.org/schema/security" 
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd 
http://www.springframework.org/schema/data/jpa 
http://www.springframework.org/schema/data/jpa/spring-jpa-1.1.xsd 
http://www.springframework.org/schema/security 
http://www.springframework.org/schema/security/spring-security.xsd"> 

<security:authentication-manager alias="authenticationManager"> 
    <security:authentication-provider ref="userService" /> 
</security:authentication-manager> 

<bean id="userService" class="<util-classpath>.UserServiceMock" > 
    <property name="userDetailsService" ref="crowdUserDetailsService" /> 
    <property name="requestHelper" ref="mockRequestHelper" /> 
</bean> 

<bean id="mockRequestHelper" class="<util-classpath>.RequestHelperMock" /> 

<bean id="crowdUserDetailsService" class="<util-classpath>.UserDetailsServiceMock" /> 

<bean id="RemoteCrowdAuthenticationProvider" class="<util-classpath>.RemoteCrowdAuthenticationProviderMock"> 
    <constructor-arg ref="crowdAuthenticationManager" /> 
    <constructor-arg ref="httpAuthenticator" /> 
    <constructor-arg ref="crowdUserDetailsService" /> 
</bean> 

<bean id="crowdAuthenticationManager" class="<util-classpath>.CrowdAuthenticationManagerMock" > 
    <constructor-arg ref="securityServerClient" /> 
</bean> 

<bean id="securityServerClient" class="<util-classpath>.SecurityServerClientMock" > 
    <constructor-arg ref="clientProperties" /> 
</bean> 

<bean id="clientProperties" class="<util-classpath>.ClientPropertiesMock" > 
    <constructor-arg ref="properties" /> 
</bean> 

<bean id="properties" class="<util-classpath>.PropertiesMock" /> 

<bean id="httpAuthenticator" class="<util-classpath>.HttpAuthenticatorMock" > 
    <constructor-arg ref="clientProperties" /> 
</bean> 

<security:global-method-security pre-post-annotations="enabled" /> 

我的TestController:

@ContextConfiguration("classpath:app-context.xml") 
public abstract class AbstractControllerTest extends AbstractController { 

@Autowired 
private AuthenticationManager am; 
@Mock 
private RemoteCrowdAuthenticationProvider authProvider; 
@Mock 
private AuthenticationProvider customAuthenticationProvider; 

@After 
public void clear() { 
    SecurityContextHolder.clearContext(); 
} 

protected User getJohnDoe() { 
    // role for ordinary user (medewerker) 
    User user = new User("JohnDoe", "John", null, null, "Doe"); 
    Collection<GrantedAuthority> userAuthorities = new ArrayList<GrantedAuthority>(); 
    userAuthorities.add(new SimpleGrantedAuthority("EVERYONE_General")); 
    userAuthorities.add(new SimpleGrantedAuthority("EVERYONE_Profile")); 
    Authentication auth = new UsernamePasswordAuthenticationToken(user.getLoginID(), null, userAuthorities); 
    SecurityContextHolder.getContext().setAuthentication(am.authenticate(auth)); 
    return user; 
} 

我的具體測試類我使用JUnit運行在Eclipse:

@RunWith(SpringJUnit4ClassRunner.class) 
public class AdministrationControllerTest extends AbstractControllerTest { 
@Mock 
private UserService userService; 
@Mock 
private RequestHelper requestHelper; 
@InjectMocks 
private AdministrationController controller = new AdministrationController(); 

private List<User> users; 

@Before 
public void init() { 
    MockitoAnnotations.initMocks(this); 

    users = new ArrayList<User>(); 
    User employee = new User("smithb", "Bob", "", "", "Smith", User.SeniorityLevel.MEDIOR, "Medior developer", initProfile()); 
    employee.setId(new Long(123)); 
    users.add(employee); 

    when(userService.findAllUsersIncludingInactive(new Sort(new Sort.Order("firstName")))).thenReturn(users); 
} 


@Test 
public void testShowCompleteEmployeeOverviewNoAccess() { 
    User johnDoe = getJohnDoe(); 
    ModelAndView modelAndView = controller.showCompleteEmployeeOverview(johnDoe, new ModelAndView()); 

    assertEquals(Constants.LOGOUT_URL, modelAndView.getViewName()); 

    verify(userService, never()).findAllUsersIncludingInactive(any(Sort.class)); 
} 

,嘲笑UserService:

public final class UserServiceMock implements UserService, AuthenticationProvider { 

private UserDetailsServiceMock userDetailsService; 

private RequestHelperMock requestHelper; 

@Override 
public List<User> findAllUsers() { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public List<User> findAllUsers(Sort sort) { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public List<User> findAllUsersIncludingInactive(Sort sort) { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public User findUserById(Long id) { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public User findUserByLoginID(String loginId) { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public User createUser() { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public User saveUser(User user) { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public void removeUser(User user) { 
    // TODO Auto-generated method stub 

} 

@Override 
public Team findTeamById(Long id) { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public List<Team> findAllTeams() { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public List<Team> findAllTeams(Sort sort) { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public Team saveTeam(Team team) { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public List<User> searchUsers(String name) { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public Authentication authenticate(Authentication authentication) throws AuthenticationException { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public boolean supports(Class<?> authentication) { 
    return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication)); 
} 

public UserDetailsServiceMock getUserDetailsService() { 
    return userDetailsService; 
} 

public void setUserDetailsService(UserDetailsServiceMock userDetailsService) { 
    this.userDetailsService = userDetailsService; 
} 

public RequestHelperMock getRequestHelper() { 
    return requestHelper; 
} 

public void setRequestHelper(RequestHelperMock requestHelper) { 
    this.requestHelper = requestHelper; 
} 
} 

不幸的是我不斷收到

org.springframework.security.authentication.ProviderNotFoundException: No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken 

,我不明白爲什麼我要告訴他的項目在配置中使用UserServiceMockAuthenticationProvider

+0

爲什麼需要在getJohnDoe()方法中設置'SecurityContextHolder'? – 2013-05-01 13:16:48

+0

這就是我在這裏找到的:[http://stackoverflow.com/questions/4664893/how-to-manually-set-an-authenticated-user-in-spring-security-springmvc],我需要測試不同的用戶與Spring @PreAuthorize註釋不同的授權級別 – user1829860 2013-05-01 13:46:58

+0

您想要做的是集成和驗證測試之間的事情。絕對不是單元測試。 – 2013-05-01 14:02:51

回答

1

實際上,我所要做的就是在UserServiceMock中實現以下方法:

public Authentication authenticate(Authentication authentication) throws AuthenticationException { 
    return authentication; 
} 

而不是返回null;