problems injecting custom userDetailsService in Spring Security OAuth2

前端 未结 3 866
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-22 05:33

I am using Spring Security OAuth2 2.0.7.RELEASE. As i am using ORM to connect to my database and default JdbcUserDetailsManager uses jdbc i wanted to implement my own UserDetail

相关标签:
3条回答
  • 2021-01-22 06:00

    The problem is that you are using default JdbcDaoImpl. The query which is causing the problem is

    public static final String DEF_AUTHORITIES_BY_USERNAME_QUERY =
            "select username,authority " +
            "from authorities " +
            "where username = ?";
    

    This is used as a default query to load all authorities for the user by userName inside JdbcDaoImpl. So if you still want to use default JdbcDaoImpl - you can set the custom query, which will do the job with your tables, as the parameter of it.

    I'm not sure what is the schema of you users table, but something like this should be similar(if you are configuring JdbcDaoImpl bean programmatically):

    String query = "select username,authority " +
            "from authorities join users on users.id = authorities.user_id " +
            "where users.username = ?";
    jdbcDaoImpl.setAuthoritiesByUsernameQuery(query);
    

    Or if you create JdbcDaoImpl from XML:

    <bean id="userDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
        <property name="authoritiesByUsernameQuery"
                  value="select username,authority from authorities
                            join users on users.id = authorities.user_id
                            where users.username = ?"/>
    </bean>
    

    There might be some other default queries that you would like to change to fit your schema, take a look at them inside JdbcDaoImpl.

    You might also consider a possibility of writing your own implementation of UserDetailsService if it will start getting too far from default JdbcDaoImpl one.

    0 讨论(0)
  • 2021-01-22 06:02

    You are using auth.jdbcAuthentication().dataSource(this.dataSource).and().userDetailsService(‌​this.userService);// Inject custom and I here it's creating two auth managers - one with default JdbcDaoImpl and dataSource pointing to this.dataSource and another with your custom userService. Try just putting auth.userDetailsService(this.userService) (I hope that userService already have jdbc autowired inside).

    The point here is that .and() is used to add different authentication configurations to the authentication manager, not configuring the jdbcAuthentication() one.

    0 讨论(0)
  • 2021-01-22 06:25

    In 2.0.7 when you do a POST/GET request on /oauth/token with grant type as password, it will actually except a ClientDetailsUserDetailsService but not UserDetailsService.

    I had similar issue and this is how I solved it :

    public class AppClientDetailsUserDetailsService extends ClientDetailsUserDetailsService {
        public AppClientDetailsUserDetailsService(ClientDetailsService clientDetailsService) {
            super(clientDetailsService);
        }
    }
    
    
    public class AppConsumerDetailsService implements ClientDetailsService {
    
         public ClientDetails loadClientByClientId(String clientId)
                throws OAuth2Exception {
               //some logic
         }
    }
    
    <http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="authenticationManager"
              entry-point-ref="entryPoint" xmlns="http://www.springframework.org/schema/security"
                >
            <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
            <anonymous enabled="false" />
            <http-basic entry-point-ref="entryPoint" />
            <custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
    
    </http>
    
    <bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
          <property name="authenticationManager" ref="authenticationManager" />
        </bean>
    

    authenticationManager is the bean for AppClientDetailsUserDetailsService whose constructor argument is AppConsumerDetailsService.

    0 讨论(0)
提交回复
热议问题