Java – upgrade spring security oauth2

I'm trying to change the spring security oauth2 configuration from 2.0 Upgrade from 0.rc1 to 2.0 3.RELEASE. I copied the configuration from the sprklr example and made it work So it is based on the working example of XML based spring security oauth2 configuration

Now I've upgraded to the latest version of spring security (2.0.3 at the time of writing) and tried to convert it to a Java configuration I published the XML configuration and the following Java configuration

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:security="http://www.springframework.org/schema/security"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
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://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd">

<!-- Authentication manager. -->
<security:authentication-manager alias="authenticationManager">
    <security:authentication-provider>
        <security:jdbc-user-service data-source-ref="dataSource"
           users-by-username-query="select a.username,a.password,a.enabled,a.email from account a where a.username = ?" 
           authorities-by-username-query="select a.username,r.role_name from account a,role r,account_role ar where a.id = ar.account_id and r.id = ar.role_id and a.username = ?" />
        <security:password-encoder ref="passwordEncoder"/>
    </security:authentication-provider>
</security:authentication-manager>

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


<security:http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager">
    <security:intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
    <security:anonymous enabled="false" />
    <security:http-basic entry-point-ref="clientAuthenticationEntryPoint" />
    <!-- include this only if you need to authenticate clients via request parameters -->
    <security:custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER" />
    <security:access-denied-handler ref="oauthAccessDeniedHandler" />
</security:http>

<security:http pattern="/api/.*/accounts" request-matcher="regex" create-session="stateless" entry-point-ref="oauthAuthenticationEntryPoint" use-expressions="true">
    <security:intercept-url pattern="/api/.*/accounts" method="POST" requires-channel="https" access="#oauth2.clientHasRole('ROLE_CLIENT') or hasRole('ROLE_ANONYMOUS')"/>
    <security:intercept-url pattern="/.*" access="denyAll()" />
    <security:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
    <security:access-denied-handler ref="oauthAccessDeniedHandler" />
    <security:expression-handler ref="oauthWebExpressionHandler" />
</security:http>

<security:http pattern="/api/**" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint" access-decision-manager-ref="accessDecisionManager">
    <security:anonymous enabled="false" />
    <security:intercept-url pattern="/api/**" access="ROLE_USER,SCOPE_TRUST,SCOPE_PLAY"/>
    <security:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
    <security:access-denied-handler ref="oauthAccessDeniedHandler" />
</security:http>

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

<bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <property name="realmName" value="*****/client" />
    <property name="typeName" value="Basic" />
</bean>

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

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

<bean id="accessDecisionManager" class="org.springframework.security.access.Vote.UnanimousBased">
    <constructor-arg>
        <list>
            <bean class="org.springframework.security.oauth2.provider.Vote.ScopeVoter" />
            <bean class="org.springframework.security.access.Vote.RoleVoter" />
            <bean class="org.springframework.security.access.Vote.AuthenticatedVoter" />
        </list>
    </constructor-arg>
</bean>

<security:authentication-manager id="clientAuthenticationManager">
    <security:authentication-provider user-service-ref="clientDetailsUserService" />
</security:authentication-manager>

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

<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore" />

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

<bean id="tokenEnhancer" class="com.****.*****.config.*****TokenEnhancer" />

<bean id="requestFactory" class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
    <constructor-arg name="clientDetailsService" ref="clientDetails" />
</bean>

<bean id="userApprovalHandler" class="com.****.*****.config.*****UserApprovalHandler">
    <property name="approvalStore" ref="approvalStore" />
    <property name="clientDetailsService" ref="clientDetails" />
    <property name="requestFactory" ref="requestFactory" />
</bean>

<bean id="approvalStore" class="org.springframework.security.oauth2.provider.approval.TokenApprovalStore">
    <property name="tokenStore" ref="tokenStore" />
</bean>

<oauth:authorization-server
    client-details-service-ref="clientDetails" token-services-ref="tokenServices"
    user-approval-handler-ref="userApprovalHandler">
    <oauth:authorization-code />
    <oauth:implicit />
    <oauth:refresh-token />
    <oauth:client-credentials />
    <oauth:password />
</oauth:authorization-server>

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

<oauth:client-details-service id="clientDetails">
   <oauth:client client-id="*****-PHP-demo" secret="??????????"
        authorized-grant-types="password,authorization_code,refresh_token,client_credentials"
        authorities="ROLE_USER,ROLE_CLIENT"
        scope="play,trust"
        access-token-validity="6000"/>


   <oauth:client client-id="*****-swagger-ui"
        authorized-grant-types="implicit"
        authorities="ROLE_USER,ROLE_CLIENT,ROLE_TRUSTED_CLIENT"
        scope="play,trust"
        redirect-uri="${baseUrl}/o2c.html"
        autoapprove="true"
        access-token-validity="6000"/>

   <oauth:client client-id="*****-runscope" 
        secret="???????????????????????????????"
        authorized-grant-types="password,refresh_token"
        authorities="ROLE_USER,trust"
        redirect-uri="https://www.runscope.com/oauth_tool/callback"
        autoapprove="true"
        access-token-validity="6000"/>     

</oauth:client-details-service>  

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

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

And Java configuration (so far..)

@Configuration
public class SecurityConfig {

@Autowired
private DataSource dataSource;

@Value("${baseUrl}") private String baseUrl;

@Bean
public ClientDetailsService clientDetailsService() throws Exception {
    ClientDetailsServiceConfiguration serviceConfig = new ClientDetailsServiceConfiguration();

    serviceConfig.clientDetailsServiceConfigurer().inMemory()
        .withClient("*****-????????")
        .secret("????????????????????")
        .authorizedGrantTypes("password","authorization_code","refresh_token","client_credentials")
        .authorities("ROLE_CLIENT","ROLE_TRUSTED_CLIENT")
        .scopes("play","trust")
    .and()
        .withClient("*****-????????")
        .authorizedGrantTypes("implicit")
        .authorities("ROLE_USER","ROLE_CLIENT","trust")
        .redirectUris(baseUrl + "/o2c.html")
        .autoApprove(true)
    .and()
        .withClient("*****-???????")
        .secret("????????????????????")
        .authorizedGrantTypes("password","refresh_token")
        .authorities("ROLE_USER","trust")
        .redirectUris("https://www.runscope.com/oauth_tool/callback")
        .autoApprove(true);

    return serviceConfig.clientDetailsService();
}

@Bean
public TokenStore tokenStore() {
    return new InMemoryTokenStore();
}

@Bean
public DefaultTokenServices tokenServices() throws Exception {
    DefaultTokenServices tokenServices = new DefaultTokenServices();
    tokenServices.setAccessTokenValiditySeconds(6000);
    tokenServices.setClientDetailsService(clientDetailsService());
    tokenServices.setTokenEnhancer(new *****TokenEnhancer());
    tokenServices.setSupportRefreshToken(true);
    tokenServices.setTokenStore(tokenStore());
    return tokenServices;
}

@Bean
public UserApprovalHandler userApprovalHandler() throws Exception {
    *****UserApprovalHandler handler = new *****UserApprovalHandler();
    handler.setApprovalStore(approvalStore());
    handler.setClientDetailsService(clientDetailsService());
    handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService()));
    return handler;
}

@Bean
public ApprovalStore approvalStore() {
    TokenApprovalStore store = new TokenApprovalStore();
    store.setTokenStore(tokenStore());
    return store;
}

@Bean
public OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler() {
    return new OAuth2AccessDeniedHandler();
}


@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
@EnableWebSecurity
protected static class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private DataSource dataSource;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Autowired
    private ClientDetailsService clientDetailsService;

    @Autowired
    private OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler;

    @Bean
    protected UserDetailsService clientDetailsUserService() {
        return new ClientDetailsUserDetailsService(clientDetailsService);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.userDetailsService(clientDetailsUserService());

        JdbcUserDetailsManagerConfigurer<AuthenticationManagerBuilder> jdbcUserDetail = new JdbcUserDetailsManagerConfigurer<AuthenticationManagerBuilder>();
        jdbcUserDetail.dataSource(dataSource);
        jdbcUserDetail.passwordEncoder(passwordEncoder);
        jdbcUserDetail.authoritiesByUsernameQuery("select a.username,account_role ar where a.id = ar.account_id and r.id = ar.role_id and a.username = ?");
        jdbcUserDetail.usersByUsernameQuery("select a.username,a.email from account a where a.username = ?");

        auth.apply(jdbcUserDetail);
    }

    @Bean(name="authenticationManager")
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    protected AuthenticationEntryPoint authenticationEntryPoint() {
        OAuth2AuthenticationEntryPoint entryPoint = new OAuth2AuthenticationEntryPoint();
        entryPoint.setTypeName("Basic");
        entryPoint.setRealmName("oauth2/client");
        return entryPoint;
    }

    @Override
    public void configure(WebSecurity webSecurity) throws Exception {
        webSecurity
            .ignoring()
            .antMatchers("/index.html","/resources/**","/swagger/**","/copyright*","/api-docs/**")
        .and()
            .debug(true);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http.anonymous().disable()
            .antMatcher("/oauth/token")
            .authorizeRequests().anyRequest().authenticated()
        .and()
            .httpBasic().authenticationEntryPoint(authenticationEntryPoint())
        .and()
            .csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/token")).disable()
            .exceptionHandling().accessDeniedHandler(oAuth2AccessDeniedHandler)
        .and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        // @formatter:on
    }

}

@Configuration
@EnableResourceServer
protected static class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Autowired
    private ResourceServerTokenServices tokenServices;

    @Autowired
    private OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.tokenServices(tokenServices);
        resources.resourceId("*****");
    }


    @Override
    public void configure(HttpSecurity http) throws Exception {

        // @formatter:off
        http
            .anonymous()
            .disable();

        // API calls
        http
            .authorizeRequests()
            .regexMatchers(HttpMethod.POST,"/api/.*/accounts")
            .access("#oauth2.hasScope('trust') and #oauth2.hasScope('play') and (hasRole('ROLE_USER'))")
        .and()
        //.addFilterBefore(clientCredentialsTokenEndpointFilter(),BasicAuthenticationFilter.class)
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.NEVER)
        .and()
            .exceptionHandling()
            .accessDeniedHandler(oAuth2AccessDeniedHandler);

        // API calls
        http
            .authorizeRequests()
            .antMatchers("/api/**")
            .access("#oauth2.hasScope('trust') and #oauth2.hasScope('play') and (hasRole('ROLE_USER'))")
        .and()
        //.addFilterBefore(clientCredentialsTokenEndpointFilter(),BasicAuthenticationFilter.class)
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.NEVER)
        .and()
            .exceptionHandling()
            .accessDeniedHandler(oAuth2AccessDeniedHandler);
        // @formatter:on
    }


}

@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private DataSource dataSource;

    @Autowired
    private DefaultTokenServices tokenServices;

    @Autowired
    private ClientDetailsService clientDetailsService;

    @Autowired
    private UserApprovalHandler userApprovalHandler;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.clientDetailsService(clientDetailsService)
        .tokenServices(tokenServices)
        .userApprovalHandler(userApprovalHandler);
    }

}
}

Add more information (based on Dave syer's questions)

Do not generate tokens, see more information below

Request:

curl -k -i -H "Accept: application/json" -X POST -d "grant_type=password&client_id=*****-PHP-demo&client_secret=???????&scope=play trust&username=tester&password=121212" https://localhost:8443/*****/oauth/token

Response:

HTTP/1.1 401 Unauthorized
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
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
x-frame-options: DENY
Cache-Control: no-store
Pragma: no-cache
WWW-Authenticate: Basic realm="*****/client",error="unauthorized",error_description="An Authentication object was not found in the SecurityContext"
Content-Type: application/json;charset=UTF-8
@R_542_301@: chunked
Date: Tue,16 Sep 2014 14:05:19 GMT

{"error": "unauthorized", "error_description": "cannot find authentication object in securitycontext"}

Server log:

Request received for POST '/oauth/token':

org.apache.catalina.connector.RequestFacade@344dad0c

servletPath:
pathInfo:/oauth/token
headers: 
user-agent: curl/7.30.0
host: localhost:8443
accept: application/json
content-length: 145
content-type: application/x-www-form-urlencoded


Security filter chain: [
  WebAsyncManagerIntegrationFilter
  SecurityContextPersistenceFilter
  HeaderWriterFilter
  logoutFilter
  BasicAuthenticationFilter
  RequestCacheAwareFilter
  SecurityContextHolderAwareRequestFilter
  SessionManagementFilter
  ExceptionTranslationFilter
  FilterSecurityInterceptor
]

(updated on October 14)

Java security configuration;

@Configuration
public class SecurityConfig {

    @Autowired
    private DataSource dataSource;

    @Value("${baseUrl}") private String baseUrl;

    @Bean
    public ClientDetailsService clientDetailsService() throws Exception {
        ClientDetailsServiceConfiguration serviceConfig = new ClientDetailsServiceConfiguration();

        serviceConfig.clientDetailsServiceConfigurer().inMemory()
            .withClient("abc")
            .secret("?????")
            .authorizedGrantTypes("password","client_credentials")
            .authorities("ROLE_CLIENT","ROLE_TRUSTED_CLIENT")
            .scopes("play","trust")
        .and()
            .withClient("xyz")
            .authorizedGrantTypes("implicit")
            .authorities("ROLE_USER","trust")
            .redirectUris(baseUrl + "/o2c.html")
            .autoApprove(true)
        .and()
            .withClient("zzz")
            .secret("?????????????????")
            .authorizedGrantTypes("password","refresh_token")
            .authorities("ROLE_USER","trust")
            .redirectUris("https://www.runscope.com/oauth_tool/callback")
            .autoApprove(true);

        return serviceConfig.clientDetailsService();
    }

    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }

    @Bean
    public DefaultTokenServices tokenServices() throws Exception {
        DefaultTokenServices tokenServices = new DefaultTokenServices();
        tokenServices.setAccessTokenValiditySeconds(6000);
        tokenServices.setClientDetailsService(clientDetailsService());
        tokenServices.setTokenEnhancer(new MyTokenEnhancer());
        tokenServices.setSupportRefreshToken(true);
        tokenServices.setTokenStore(tokenStore());
        return tokenServices;
    }

    @Bean
    public UserApprovalHandler userApprovalHandler() throws Exception {
        MyUserApprovalHandler handler = new MyUserApprovalHandler();
        handler.setApprovalStore(approvalStore());
        handler.setClientDetailsService(clientDetailsService());
        handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService()));
        return handler;
    }

    @Bean
    public ApprovalStore approvalStore() {
        TokenApprovalStore store = new TokenApprovalStore();
        store.setTokenStore(tokenStore());
        return store;
    }

    @Bean
    public OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler() {
        return new OAuth2AccessDeniedHandler();
    }

    @Configuration
    @Order(Ordered.HIGHEST_PRECEDENCE)
    @EnableWebSecurity
    protected static class WebSecurityConfig extends WebSecurityConfigurerAdapter {

        @Autowired
        private DataSource dataSource;

        @Resource
        private PasswordEncoder passwordEncoder;

        @Autowired
        private ClientDetailsService clientDetailsService;

        @Autowired
        private OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler;

        @Bean
        protected UserDetailsService clientDetailsUserService() {
            return new ClientDetailsUserDetailsService(clientDetailsService);
        }

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {

            JdbcUserDetailsManagerConfigurer<AuthenticationManagerBuilder> jdbcUserDetail = new JdbcUserDetailsManagerConfigurer<AuthenticationManagerBuilder>();
            jdbcUserDetail.dataSource(dataSource);
            jdbcUserDetail.passwordEncoder(passwordEncoder);
            jdbcUserDetail.authoritiesByUsernameQuery("select a.username,account_role ar where a.id = ar.account_id and r.id = ar.role_id and a.username = ?");
            jdbcUserDetail.usersByUsernameQuery("select a.username,a.email from account a where a.username = ?");

            auth.apply(jdbcUserDetail);
        }

        @Bean(name="authenticationManager")
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception {
            AuthenticationManager am = super.authenticationManagerBean();
            return am; 
        }

        @Bean
        protected AuthenticationEntryPoint authenticationEntryPoint() {
            OAuth2AuthenticationEntryPoint entryPoint = new OAuth2AuthenticationEntryPoint();
            entryPoint.setTypeName("Basic");
            entryPoint.setRealmName("redrum/client");
            return entryPoint;
        }

        @Override
        public void configure(WebSecurity webSecurity) throws Exception {
            webSecurity
                .ignoring()
                .antMatchers("/resources/**","/api-docs/**")
            .and()
                .debug(true);
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // @formatter:off
            http.anonymous().disable()
                .antMatcher("/oauth/token")
                .authorizeRequests().anyRequest().authenticated()
            .and()
                .httpBasic().authenticationEntryPoint(authenticationEntryPoint())
            .and()
                .csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/token")).disable()
                .exceptionHandling().accessDeniedHandler(oAuth2AccessDeniedHandler)
            .and()
                .addFilterBefore(clientCredentialsTokenEndpointFilter(),BasicAuthenticationFilter.class)
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
            // @formatter:on
        }

        @Bean
        public ClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilter() throws Exception {
            ClientCredentialsTokenEndpointFilter filter = new ClientCredentialsTokenEndpointFilter();
            filter.setAuthenticationEntryPoint(authenticationEntryPoint());
            filter.setAuthenticationManager(authenticationManagerBean());
            return filter;
        }

    }

    @Configuration
    @EnableResourceServer
    protected static class ResourceServerConfig extends ResourceServerConfigurerAdapter {

        @Autowired
        private ResourceServerTokenServices tokenServices;

        @Autowired
        private OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler;

        @Autowired
        private AuthenticationManager authenticationManager;

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
            resources.tokenServices(tokenServices);
            resources.resourceId("xyz");
        }

        @Override
        public void configure(HttpSecurity http) throws Exception {

            // @formatter:off
            http
                .anonymous()
                .disable();

            // API calls
            http
                .authorizeRequests()
                .regexMatchers(HttpMethod.POST,"/api/.*/accounts")
                .access("#oauth2.hasScope('trust') and #oauth2.hasScope('play') and (hasRole('ROLE_USER'))")
            .and()
                //.addFilterBefore(clientCredentialsTokenEndpointFilter(),BasicAuthenticationFilter.class)
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.NEVER)
            .and()
                .exceptionHandling()
                .accessDeniedHandler(oAuth2AccessDeniedHandler);

            // API calls
            http
                .authorizeRequests()
                .antMatchers("/api/**")
                .access("#oauth2.hasScope('trust') and #oauth2.hasScope('play') and (hasRole('ROLE_USER'))")
            .and()
                //.addFilterBefore(clientCredentialsTokenEndpointFilter(),BasicAuthenticationFilter.class)
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.NEVER)
            .and()
                .exceptionHandling()
                .accessDeniedHandler(oAuth2AccessDeniedHandler);
            // @formatter:on
        }


    }

    @Configuration
    @EnableAuthorizationServer
    protected static class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

        @Autowired
        private DataSource dataSource;

        @Autowired
        private DefaultTokenServices tokenServices;

        @Autowired
        private ClientDetailsService clientDetailsService;

        @Autowired
        private UserApprovalHandler userApprovalHandler;

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints.clientDetailsService(clientDetailsService)
            .tokenServices(tokenServices)
            .userApprovalHandler(userApprovalHandler);
        }

    }
}

Solution

This is the solution; I hope it will be useful to sb Using the current state of spring oauth2 documentation and examples to determine this solution is not easy

@Configuration
public class SecurityConfig {

@Autowired
private DataSource dataSource;

@Autowired
private ClientDetailsService clientDetailsService;

@Bean
public TokenStore tokenStore() {
    return new InMemoryTokenStore();
}

@Bean
public DefaultTokenServices tokenServices() throws Exception {
    DefaultTokenServices tokenServices = new DefaultTokenServices();
    tokenServices.setAccessTokenValiditySeconds(6000);
    tokenServices.setClientDetailsService(clientDetailsService);
    tokenServices.setTokenEnhancer(new MyTokenEnhancer());
    tokenServices.setSupportRefreshToken(true);
    tokenServices.setTokenStore(tokenStore());
    return tokenServices;
}

@Bean
public UserApprovalHandler userApprovalHandler() throws Exception {
    MyUserApprovalHandler handler = new MyUserApprovalHandler();
    handler.setApprovalStore(approvalStore());
    handler.setClientDetailsService(clientDetailsService);
    handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
    handler.setUseApprovalStore(true);
    return handler;
}

@Bean
public ApprovalStore approvalStore() {
    TokenApprovalStore store = new TokenApprovalStore();
    store.setTokenStore(tokenStore());
    return store;
}

@Bean
public OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler() {
    return new OAuth2AccessDeniedHandler();
}

@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
@EnableWebSecurity
protected static class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${baseUrl}") 
    private String baseUrl;

    @Autowired
    private DataSource dataSource;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Autowired
    private OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler;

    @Bean
    public ClientDetailsService clientDetailsService() throws Exception {
        ClientDetailsServiceConfiguration serviceConfig = new ClientDetailsServiceConfiguration();

        serviceConfig.clientDetailsServiceConfigurer().inMemory()
            .withClient("***-***-****")
            .secret("???????????????????????????????")
            .authorizedGrantTypes("password","trust")
        .and()
            .withClient("***-******-**")
            .authorizedGrantTypes("implicit")
            .authorities("ROLE_USER","trust")
            .redirectUris(baseUrl + "/o2c.html")
            .autoApprove(true)
        .and()
            .withClient("******-***********")
            .secret("???????????????????????????????????")
            .authorizedGrantTypes("password","trust")
            .redirectUris("https://www.runscope.com/oauth_tool/callback")
            .autoApprove(true);

        return serviceConfig.clientDetailsService();
    }

    @Bean
    UserDetailsService clientDetailsUserDetailsService() throws Exception {
        return new ClientDetailsUserDetailsService(clientDetailsService());
    }



    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        JdbcUserDetailsManagerConfigurer<AuthenticationManagerBuilder> jdbcUserDetail = new JdbcUserDetailsManagerConfigurer<AuthenticationManagerBuilder>();
        jdbcUserDetail.dataSource(dataSource);
        jdbcUserDetail.passwordEncoder(passwordEncoder);
        jdbcUserDetail.authoritiesByUsernameQuery("select a.username,a.email from account a where a.username = ?");
        auth.apply(jdbcUserDetail);

        auth.userDetailsService(clientDetailsUserDetailsService());


    }

    @Bean(name="authenticationManager")
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    protected AuthenticationEntryPoint authenticationEntryPoint() {
        OAuth2AuthenticationEntryPoint entryPoint = new OAuth2AuthenticationEntryPoint();
        entryPoint.setTypeName("Basic");
        entryPoint.setRealmName("app/client");
        return entryPoint;
    }

    @Override
    public void configure(WebSecurity webSecurity) throws Exception {
        webSecurity
            .ignoring()
            .antMatchers("/resources/**","/api-docs/**")
        .and()
            .debug(true);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http.anonymous().disable()
            .antMatcher("/oauth/token")
            .authorizeRequests().anyRequest().authenticated()
        .and()
            .httpBasic().authenticationEntryPoint(authenticationEntryPoint())
        .and()
            .csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/token")).disable()
            .exceptionHandling().accessDeniedHandler(oAuth2AccessDeniedHandler)
        .and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        // @formatter:on

        ClientCredentialsTokenEndpointFilter filter = new ClientCredentialsTokenEndpointFilter();
        filter.setAuthenticationManager(authenticationManagerBean());
        filter.afterPropertiesSet();
        http.addFilterBefore(filter,BasicAuthenticationFilter.class);
    }

}

@Configuration
@EnableResourceServer
protected static class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Autowired
    private ResourceServerTokenServices tokenServices;

    @Autowired
    private OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        //resources.tokenServices(tokenServices);
        resources.resourceId("app");
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {

        // @formatter:off
        http
            .anonymous()
            .disable();

        // API calls
        http
            .authorizeRequests()
            .regexMatchers(HttpMethod.POST,"/api/.*/accounts")
            .access("#oauth2.hasScope('trust') and #oauth2.hasScope('play') and (hasRole('ROLE_USER'))")
        .and()
            //.addFilterBefore(clientCredentialsTokenEndpointFilter(),BasicAuthenticationFilter.class)
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.NEVER)
        .and()
            .exceptionHandling()
            .accessDeniedHandler(oAuth2AccessDeniedHandler);

        // API calls
        http
            .authorizeRequests()
            .antMatchers("/api/**")
            .access("#oauth2.hasScope('trust') and #oauth2.hasScope('play') and (hasRole('ROLE_USER'))")
        .and()
            //.addFilterBefore(clientCredentialsTokenEndpointFilter(),BasicAuthenticationFilter.class)
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.NEVER)
        .and()
            .exceptionHandling()
            .accessDeniedHandler(oAuth2AccessDeniedHandler);
        // @formatter:on
    }

}

@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private DataSource dataSource;

    @Autowired
    private DefaultTokenServices tokenServices;

    @Autowired
    private ClientDetailsService clientDetailsService;

    @Autowired
    private UserApprovalHandler userApprovalHandler;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    AuthenticationEntryPoint authenticationEntryPoint;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
        .tokenServices(tokenServices)
        .userApprovalHandler(userApprovalHandler)
        .authenticationManager(authenticationManager);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients)
            throws Exception {
        clients.withClientDetails(clientDetailsService);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer)
            throws Exception {
        oauthServer.authenticationEntryPoint(authenticationEntryPoint)
                .realm("app/clients");
    }

}

}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>