我正在将基于xml的配置(从source)转换为java配置。我已将这两个文件放在下面,它正在使用xml配置,但在更改为java配置后无法进行身份验证。任何人都可以提出一些如何解决它的想法吗?
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sec="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/security
http://www.springframework.org/schema/security/spring-security.xsd">
<bean id="passwordEncoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder"/>
<sec:authentication-manager alias="userAuthenticationManager">
<sec:authentication-provider user-service-ref="userService">
<sec:password-encoder ref="passwordEncoder"/>
</sec:authentication-provider>
</sec:authentication-manager>
<sec:authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
<sec:authentication-provider user-service-ref="client-details-user-service"/>
</sec:authentication-manager>
<bean id="client-details-user-service" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="client-details-service" />
</bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<http pattern="/v1.0/users" create-session="stateless" authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/v1.0/users" method="POST" access="IS_AUTHENTICATED_FULLY"/>
<anonymous enabled="false"/>
<http-basic entry-point-ref="clientAuthenticationEntryPoint"/>
<access-denied-handler ref="oauthAccessDeniedHandler"/>
</http>
<!-- REST API Endpoints -->
<http pattern="/v1.0/**" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint"
xmlns="http://www.springframework.org/schema/security">
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER"/>
<access-denied-handler ref="oauthAccessDeniedHandler"/>
</http>
</beans>
<?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:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<context:component-scan base-package="com.porterhead.oauth2.configuration"/>
<!-- Access voters -->
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"
xmlns="http://www.springframework.org/schema/beans">
<property name="decisionVoters">
<list>
<ref bean="roleVoter"/>
</list>
</property>
</bean>
<bean id="roleHierarchy"
class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
<property name="hierarchy">
<value>
ROLE_ADMIN > ROLE_USER
ROLE_USER > ROLE_GUEST
</value>
</property>
</bean>
<bean id="roleVoter" class="com.porterhead.security.HierarchicalJsr250Voter">
<constructor-arg ref="roleHierarchy" />
</bean>
<sec:global-method-security jsr250-annotations="enabled" access-decision-manager-ref="accessDecisionManager"/>
<oauth:expression-handler id="oauthExpressionHandler"/>
<oauth:web-expression-handler id="oauthWebExpressionHandler"/>
</beans>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:sec="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/security/oauth2
http://www.springframework.org/schema/security/spring-security-oauth2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<oauth:authorization-server client-details-service-ref="client-details-service" token-services-ref="tokenServices">
<oauth:refresh-token/>
<oauth:password/>
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter" token-services-ref="tokenServices"/>
<bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager"/>
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="typeName" value="Basic"/>
</bean>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test"/>
</bean>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler"/>
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore"/>
<property name="supportRefreshToken" value="true"/>
<property name="clientDetailsService" ref="client-details-service"/>
</bean>
<bean id="corsFilter" class="com.porterhead.filter.spring.SpringCrossOriginResourceSharingFilter"/>
<bean id="oauthRestEntryPoint" class="com.porterhead.security.OAuthRestEntryPoint"/>
<!-- The token endpoint See org.springframework.security.oauth2.provider.endpoint.TokenEndpoint-->
<http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false"/>
<http-basic entry-point-ref="oauthRestEntryPoint" />
<access-denied-handler ref="oauthAccessDeniedHandler"/>
<custom-filter ref="corsFilter" after="LAST"/>
</http>
</beans>
@Configuration
@ComponentScan
@EnableResourceServer
@Import(SecurityConfig.class)
//@ImportResource({
// "classpath:META-INF/spring/oauth/client-details.xml"
//})
public class OAuth2ServerConfig {
@Configuration
@EnableAuthorizationServer
protected static class OAuth2Config extends
AuthorizationServerConfigurerAdapter {
@Autowired
private ClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilter(){
ClientCredentialsTokenEndpointFilter clientFilter = new ClientCredentialsTokenEndpointFilter();
return clientFilter;
}
@Autowired
private ClientDetailsService clientDetailsService;
@Autowired
public OAuth2AccessTokenRepository oAuth2AccessTokenRepository;
@Autowired
public OAuth2RefreshTokenRepository oAuth2RefreshTokenRepository;
@Bean
public DefaultTokenServices tokenServices(){
final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setReuseRefreshToken(true);
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setClientDetailsService(clientDetailsService);
return defaultTokenServices;
}
@Bean
public OAuth2RepositoryTokenStore tokenStore() {
return new OAuth2RepositoryTokenStore(oAuth2AccessTokenRepository,
oAuth2RefreshTokenRepository);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer)
throws Exception {
oauthServer.tokenKeyAccess(
"isAnonymous || hasAuthority('ROLE_TRUSTED_CLIENT')")
.realm("test");
}
@Override
public void configure(ClientDetailsServiceConfigurer clients)
throws Exception {
clients.withClientDetails(clientDetailsService);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.tokenServices(tokenServices())
.setClientDetailsService(clientDetailsService);
}
}
}
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserRepository userRepository;
@Autowired
private Validator validator;
@Bean
public PasswordEncoder passwordEncoder(){
return new StandardPasswordEncoder();
}
@Bean
public UserDetailsService userDetailsService() {
return new UserServiceImpl(userRepository, validator, passwordEncoder());
}
@Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.userDetailsService(userDetailsService());
}
@Bean
public OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler(){
return new OAuth2AccessDeniedHandler();
}
@Configuration
@Order(1)
public static class OAuthEndPointConfig extends WebSecurityConfigurerAdapter{
@Autowired
private OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler;
@Autowired
private ClientDetailsService clientDetailsService;
@Bean
public OAuthRestEntryPoint oauthRestEntryPoint()
{
return new OAuthRestEntryPoint();
}
@Bean
public ClientDetailsUserDetailsService clientDetailsUserDetailsService(){
return new ClientDetailsUserDetailsService(clientDetailsService);
}
@Bean
protected AuthenticationEntryPoint authenticationEntryPoint(){
OAuth2AuthenticationEntryPoint entryPoint = new OAuth2AuthenticationEntryPoint();
entryPoint.setTypeName("Basic");
entryPoint.setRealmName("test");
return entryPoint;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.anonymous().disable()
.antMatcher("/oauth/token")
.anonymous().disable().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.httpBasic().authenticationEntryPoint(oauthRestEntryPoint())
.and()
.csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/token")).disable()
.exceptionHandling().accessDeniedHandler(oAuth2AccessDeniedHandler)
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
ClientCredentialsTokenEndpointFilter filter = new ClientCredentialsTokenEndpointFilter();
filter.setAuthenticationManager(authenticationManagerBean());
filter.afterPropertiesSet();
}
}
@Configuration
@Order(2)
protected static class ResourceServerEndpointConfig extends WebSecurityConfigurerAdapter{
@Autowired
private OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler;
@Bean
public OAuth2AuthenticationEntryPoint clientAuthenticationEntryPoint(){
OAuth2AuthenticationEntryPoint clientAuthenticationEntrypoint = new OAuth2AuthenticationEntryPoint();
clientAuthenticationEntrypoint.setTypeName("Basic");
return clientAuthenticationEntrypoint;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.anonymous().disable().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling().accessDeniedHandler(oAuth2AccessDeniedHandler)
.authenticationEntryPoint(clientAuthenticationEntryPoint())
.and()
.requestMatchers().antMatchers("/v1.0/users")
.and()
.authorizeRequests().antMatchers(HttpMethod.POST, "/v1.0/users").permitAll()
.and()
.csrf().disable();
}
}
}
curl -v -X POST -H "Content-Type: application/json" -H "Authorization: Basic MzUzYjMwMmM0NDU3NGY1NjUwNDU2ODdlNTM0ZTdkNmE6Mjg2OTI0Njk3ZTYxNWE2NzJhNjQ2YTQ5MzU0NTY0NmM=" -d '{"user":{"emailAddress":"user@example.com"}, "password":"password"}' 'http://localhost:8080/v1.0/users'
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> POST /v1.0/users HTTP/1.1
> User-Agent: curl/7.37.1
> Host: localhost:8080
> Accept: */*
> Content-Type: application/json
> Authorization: Basic MzUzYjMwMmM0NDU3NGY1NjUwNDU2ODdlNTM0ZTdkNmE6Mjg2OTI0Njk3ZTYxNWE2NzJhNjQ2YTQ5MzU0NTY0NmM=
> Content-Length: 67
>
* upload completely sent off: 67 out of 67 bytes
< HTTP/1.1 401 Unauthorized
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Cache-Control: no-store
< Pragma: no-cache
< WWW-Authenticate: Basic realm="oauth", error="unauthorized", error_description="An Authentication object was not found in the SecurityContext"
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Wed, 13 May 2015 16:01:40 GMT
<
* Connection #0 to host localhost left intact
{"error":"unauthorized","error_description":"An Authentication object was not found in the SecurityContext"}Veeras-MacBook-Pro:~ veeramarni$
答案 0 :(得分:2)
我认为authenticationManager
中自动装配的OAuth2ServerConfig
实例会使用默认DaoAuthenticationProvider
进行初始化。要使用已定义的自定义bean,请注入自定义bean,配置AuthenticationManagerBuilder
并在authenticationManager
中将SecurityConfig
公开为bean,如下所示
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
@Qualifier("userDetailsManagerImpl")
private UserDetailsManager userDetailsManager;
....
....
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.parentAuthenticationManager(authenticationManager);
auth.userDetailsService(userDetailsManager);
}
同样在OAuth2ServerConfig
中注入新暴露的bean并按如下所示进行配置
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
...
...
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.authenticationManager(authenticationManager)
.setClientDetailsService(clientDetailsService);
.tokenServices(tokenServices());
}
希望这会有所帮助。