1

そのため、oauth サーバー (ヘッダーなし) にリクエストを送信しようとしています: grant_type=password&username=blah&password=blah&client_id=blahblah。

2 つの認証マネージャーがあります (1 つはクライアント用、もう 1 つはユーザー検証用です)。問題は、私の認証マネージャーのどれも、検証のためにユーザー名を渡していないことです。どちらの場合も、client_id で呼び出されています。私が欲しいのは、クライアントを検証するものと、ユーザーを検証するものです。

私のBean構成はこれです:

 <http pattern="/oauth/token" create-session="stateless"  authentication-manager-ref="authenticationManager" xmlns="http://www.springframework.org/schema/security">
    <intercept-url pattern="/oauth/token" access="ROLE_USER" />
    <anonymous enabled="false" />
    <http-basic entry-point-ref="clientAuthenticationEntryPoint" />

    <custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER" />  

    <access-denied-handler ref="oauthAccessDeniedHandler" />
</http>


<!-- The OAuth2 protected resources are separated out into their own block so we can deal with authorization and error handling 
    separately. This isn't mandatory, but it makes it easier to control the behaviour. -->
<http pattern="/api/**" create-session="stateless" entry-point-ref="oauthAuthenticationEntryPoint"
    access-decision-manager-ref="accessDecisionManager" xmlns="http://www.springframework.org/schema/security">
    <anonymous enabled="false" />
    <intercept-url pattern="/api" access="ROLE_USER,SCOPE_READ" />

    <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
    <access-denied-handler ref="oauthAccessDeniedHandler" />
</http>


<authentication-manager  alias="authenticationManager"  xmlns="http://www.springframework.org/schema/security">
    <sec:authentication-provider user-service-ref="clientDetailsUserService" />
    <sec:authentication-provider user-service-ref="customUserDetailService">
        <sec:password-encoder ref="passwordEncoder" />
    </sec:authentication-provider>
</authentication-manager>


<beans:bean id="customUserDetailService" class="com.cointraders.api.securities.UserDetailsServiceImpl" />


<beans:bean id="clientDetails" class="org.springframework.security.oauth2.provider.JdbcClientDetailsService">
    <beans:constructor-arg ref="dataSource" />
</beans:bean>

<beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased" xmlns="http://www.springframework.org/schema/beans">
    <beans:constructor-arg>
        <beans:list>
            <beans:bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
            <beans:bean class="org.springframework.security.access.vote.RoleVoter" />
            <beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
        </beans:list>
    </beans:constructor-arg>
</beans:bean>

<oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices">
    <oauth:refresh-token />
    <oauth:password authentication-manager-ref="authenticationManager"  />
</oauth:authorization-server>


<oauth:resource-server id="resourceServerFilter" resource-id="api" token-services-ref="tokenServices" />

<sec:global-method-security pre-post-annotations="enabled" proxy-target-class="true">
    <sec:expression-handler ref="oauthExpressionHandler" />
</sec:global-method-security>

<oauth:expression-handler id="oauthExpressionHandler" />

<oauth:web-expression-handler id="oauthWebExpressionHandler" />

<beans:bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <beans:property name="realmName" value="api/" />
</beans:bean>



<beans:bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
    <beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>


<beans:bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.JdbcTokenStore">
    <beans:constructor-arg ref="dataSource" />
</beans:bean>


<beans:bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
    <beans:property name="tokenStore" ref="tokenStore" />
    <beans:property name="supportRefreshToken" value="true" />
    <beans:property name="clientDetailsService" ref="clientDetails" />
</beans:bean>

<beans:bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
    <beans:constructor-arg ref="clientDetails" />
</beans:bean>

<beans:bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />

<beans:bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <beans:property name="realmName" value="api" />
</beans:bean>

これは私の Web.XML です

    <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
  <filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>contextAttribute</param-name>
        <param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/*.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>/</url-pattern>
 </servlet-mapping>

私のユーザー詳細サービスクラス

 public class UserDetailsServiceImpl extends PersonServiceImpl implements
    UserDetailsService {

@Override
public UserDetails loadUserByUsername(String username)
        throws UsernameNotFoundException {

    UserDetails details = null;
    Specification<Person> specs = Specifications.where(PersonSpecification.equalsUserName(username));
    Person person = this.personRepository.findOne(specs);
    if(person!=null)
    {   
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        authorities.add(new   SimpleGrantedAuthority(person.getRole().getRole().name()));
        details = new User(person.getUserName(), person.getPassword(), person.getActive(), false, false, false, authorities);
    }
    return details;
 }

 }
4

1 に答える 1

3

付与タイプに を設定して<authorization-server/>いません(したがって、クライアント資格情報にマップしたデフォルトの Bean 名「authenticationManager」を使用しています)。AuthenticationManager<password/>

追加の問題は、<authentication-manager/>どちらにも明示的な「id =」を指定せずに2回使用することです。これはAuthenticationManager、2番目のものが最初のものをオーバーライドするため、実際には1つだけを定義する効果があります(両方とも同じidを持っています)。"alias=" の代わりに "id=" を使用してみてください。

可能であれば、クライアント資格情報をヘッダーで送信する必要があります (ただし、おそらくそれはご存知でしょう)。

于 2014-04-18T17:59:49.773 に答える