Project

General

Profile

Revision 9872d2b2

ID9872d2b2e6b79b0567f2e99f97bbacf213605c43
Parent 01fe562b
Child 638f3be5

Added by Andreas Kohlbecker about 5 years ago

ref #6118 working test implementation of OAuth2
- grant types 'implicite', 'authorization_code' tested and working
- /manage/ service protected (OK for production)
- /classification/ endpoint restricted for testing only

View differences:

cdmlib-remote-webapp/src/main/webapp/WEB-INF/applicationContext.xml
56 56
  <!-- CONFIGURE WEB APPLICATION HERE -->
57 57
  <import resource="datasources/configurable.xml" />
58 58
  
59

  
60 59
  <bean class="eu.etaxonomy.cdm.remote.config.LoggingConfigurer">
61 60
  </bean>
62 61

  
63
  <!-- bootstrap the WebSecurityConfiguration -->
62
  <!-- bootstrap the Web Configuration -->
64 63
  <bean class="eu.etaxonomy.cdm.remote.config.MultiWebSecurityConfiguration">
65 64
  </bean>
66
  <bean class="eu.etaxonomy.cdm.remote.config.AuthorizationServerConfiguration">
67
  </bean>
68 65

  
69 66
  <!-- OAI-PMH TODO externalize? -->
70 67
  <bean name="taxonOaiPmhController"
cdmlib-remote/src/main/java/eu/etaxonomy/cdm/remote/config/AuthorizationServerConfiguration.java
1
/**
2
* Copyright (C) 2016 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.remote.config;
10

  
11
import org.springframework.beans.factory.annotation.Autowired;
12
import org.springframework.context.annotation.Bean;
13
import org.springframework.context.annotation.Configuration;
14
import org.springframework.context.annotation.Lazy;
15
import org.springframework.context.annotation.Scope;
16
import org.springframework.context.annotation.ScopedProxyMode;
17
import org.springframework.security.authentication.AuthenticationManager;
18
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
19
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
20
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
21
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
22
import org.springframework.security.oauth2.provider.ClientDetailsService;
23
import org.springframework.security.oauth2.provider.approval.ApprovalStore;
24
import org.springframework.security.oauth2.provider.approval.InMemoryApprovalStore;
25
import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
26
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
27
import org.springframework.security.oauth2.provider.token.TokenStore;
28
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
29

  
30
import eu.etaxonomy.cdm.remote.oauth2.CdmUserApprovalHandler;
31

  
32
/**
33
 * @author a.kohlbecker
34
 * @date Oct 6, 2016
35
 *
36
 */
37
@Configuration
38
@EnableAuthorizationServer
39
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
40

  
41
    /**
42
     *
43
     */
44
    private static final String RESOURCE_ID = "all-services";
45
    /**
46
     *
47
     */
48
    private static final String CLIENT_ID = "any-client";
49

  
50
    @Autowired
51
    private ClientDetailsService clientDetailsService;
52

  
53
    @Autowired
54
    private UserApprovalHandler userApprovalHandler;
55

  
56
    @Autowired
57
    private AuthenticationManager authenticationManager;
58

  
59

  
60
    @Override
61
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
62
        clients.inMemory().withClient(CLIENT_ID)
63
            .resourceIds(RESOURCE_ID)
64
            .authorizedGrantTypes("implicit")
65
            .authorities("ROLE_USER")
66
            .scopes("read", "write")
67
            .autoApprove("read");
68
    }
69

  
70
    @Bean
71
    public ApprovalStore approvalStore() {
72
        return new InMemoryApprovalStore();
73
    }
74

  
75
    @Bean
76
    public TokenStore tokenStore() {
77
        return new InMemoryTokenStore();
78
    }
79

  
80
    @Override
81
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
82
        endpoints.tokenStore(tokenStore()).userApprovalHandler(userApprovalHandler)
83
        .authenticationManager(authenticationManager);
84
    }
85

  
86
    @Bean
87
    @Lazy
88
    @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
89
    public CdmUserApprovalHandler userApprovalHandler() throws Exception {
90
        CdmUserApprovalHandler handler = new CdmUserApprovalHandler();
91
        handler.setApprovalStore(approvalStore());
92
        handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
93
        handler.setClientDetailsService(clientDetailsService);
94
        handler.setUseApprovalStore(false);
95
        return handler;
96
    }
97
}
98

  
cdmlib-remote/src/main/java/eu/etaxonomy/cdm/remote/config/DataSourceConfigurer.java
1
// $Id$
2 1
/**
3 2
 * Copyright (C) 2009 EDIT
4 3
 * European Distributed Institute of Taxonomy
cdmlib-remote/src/main/java/eu/etaxonomy/cdm/remote/config/MultiWebSecurityConfiguration.java
9 9
package eu.etaxonomy.cdm.remote.config;
10 10

  
11 11
import org.springframework.context.annotation.Configuration;
12
import org.springframework.context.annotation.Import;
12 13
import org.springframework.core.annotation.Order;
13 14
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
14 15
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
15 16
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
16 17

  
17 18
/**
19
 *
20
 * <b>NOTE</b> on nested @Configuration classes:
21
 *
22
 * When bootstrapping such an arrangement, only the outer class need be registered against the application context.
23
 * By virtue of being a nested @Configuration class, DatabaseConfig will be registered automatically. This avoids
24
 * the need to use an @Import annotation when the relationship between AppConfig DatabaseConfig is already implicitly
25
 * clear.
26
 *
18 27
 * @author a.kohlbecker
19 28
 * @date Oct 6, 2016
20 29
 *
21 30
 */
22 31
@EnableWebSecurity
32
@Import(OAuth2ServerConfiguration.class)
23 33
public class MultiWebSecurityConfiguration {
24 34

  
25 35
    /**
......
29 39
     *
30 40
     */
31 41
    @Configuration
32
    @Order(1)
42
    @Order(2)
33 43
    public static class RemotingWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
34 44
        @Override
35 45
        protected void configure(HttpSecurity http) throws Exception {
......
45 55
        }
46 56
    }
47 57

  
58
    @Configuration
59
    @Order(1)
60
    public static class LoginWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
61
        @Override
62
        protected void configure(HttpSecurity http) throws Exception {
63
              // @formatter:off
64
                 http
65
             .anonymous().disable()
66
             .antMatcher("/oauth/authorize")
67
                 .authorizeRequests().anyRequest().fullyAuthenticated()
68
                 .and()
69
             .csrf().disable()
70
             .httpBasic();
71
             // @formatter:on
72
        }
73
    }
74

  
48 75
    /**
49 76
     * Allow anonymous authentication for all other services
50 77
     * @author a.kohlbecker
51 78
     * @date Oct 6, 2016
52 79
     *
53 80
     */
54
    @Configuration
81
    //@Configuration
55 82
    public static class DefaultWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
56 83
        @Override
57 84
        protected void configure(HttpSecurity http) throws Exception {
cdmlib-remote/src/main/java/eu/etaxonomy/cdm/remote/config/OAuth2ServerConfiguration.java
1
/**
2
 * Copyright (C) 2016 EDIT
3
 * European Distributed Institute of Taxonomy
4
 * http://www.e-taxonomy.eu
5
 *
6
 * The contents of this file are subject to the Mozilla Public License Version 1.1
7
 * See LICENSE.TXT at the top of this package for the full license terms.
8
 */
9
package eu.etaxonomy.cdm.remote.config;
10

  
11
import org.springframework.beans.factory.annotation.Autowired;
12
import org.springframework.context.annotation.Bean;
13
import org.springframework.context.annotation.Configuration;
14
import org.springframework.context.annotation.Lazy;
15
import org.springframework.context.annotation.Scope;
16
import org.springframework.context.annotation.ScopedProxyMode;
17
import org.springframework.http.HttpMethod;
18
import org.springframework.security.authentication.AuthenticationManager;
19
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
20
import org.springframework.security.config.http.SessionCreationPolicy;
21
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
22
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
23
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
24
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
25
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
26
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
27
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
28
import org.springframework.security.oauth2.provider.ClientDetailsService;
29
import org.springframework.security.oauth2.provider.approval.ApprovalStore;
30
import org.springframework.security.oauth2.provider.approval.InMemoryApprovalStore;
31
import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
32
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
33
import org.springframework.security.oauth2.provider.token.TokenStore;
34
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
35

  
36
import eu.etaxonomy.cdm.remote.oauth2.CdmUserApprovalHandler;
37

  
38
@Configuration
39
public class OAuth2ServerConfiguration {
40

  
41
    private static final String CDM_RESOURCE_ID = "cdm";
42

  
43
    // @Configuration
44
    @EnableResourceServer
45
    protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
46

  
47
        @Override
48
        public void configure(ResourceServerSecurityConfigurer resources) {
49
            resources.resourceId(CDM_RESOURCE_ID).stateless(false);
50
        }
51

  
52
        @Override
53
        public void configure(HttpSecurity http) throws Exception {
54
            // @formatter:off
55
            http
56
                // Since we want the protected resources to be accessible in the UI as well we need
57
                // session creation to be allowed (it's disabled by default in 2.0.6)
58
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
59
            .and() // TODO do we need this?
60
                .requestMatchers()
61
                    .antMatchers(
62
                        "/manage/**",
63
                        "/oauth/users/**",
64
                        "/oauth/clients/**")
65
                     .regexMatchers("/classification/.*|/classification\\..*")
66
            .and()
67
                .authorizeRequests()
68
                    // see
69
                    // - http://docs.spring.io/spring-security/site/docs/3.0.x/reference/el-access.html
70
                    // - org.springframework.security.oauth2.provider.expression.OAuth2SecurityExpressionMethods
71
                    .antMatchers("/manage/**").access("#oauth2.clientHasRole('ROLE_CLIENT') or (!#oauth2.isOAuth() and hasRole('ROLE_ADMIN'))")
72
                    .regexMatchers("/classification/.*|/classification\\..*")
73
                            //.access("#oauth2.hasScope('trust')")
74
                            .access("hasAnyRole('ROLE_ADMIN', 'ROLE_USER')")
75
                            //.access("#oauth2.clientHasRole('ROLE_CLIENT') or (!#oauth2.isOAuth() and hasAnyRole('ROLE_ADMIN', 'ROLE_USER'))")
76
                    .regexMatchers(HttpMethod.DELETE, "/oauth/users/([^/].*?)/tokens/.*")
77
                        .access("#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient()) and #oauth2.hasScope('write')")
78
                    .regexMatchers(HttpMethod.GET, "/oauth/clients/([^/].*?)/users/.*")
79
                        .access("#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient()) and #oauth2.hasScope('read')")
80
                    .regexMatchers(HttpMethod.GET, "/oauth/clients/.*")
81
                        .access("#oauth2.clientHasRole('ROLE_CLIENT') and #oauth2.isClient() and #oauth2.hasScope('read')");
82
            // @formatter:on
83
        }
84

  
85
    }
86

  
87
    /**
88
     * @author a.kohlbecker
89
     * @date Oct 6, 2016
90
     *
91
     */
92
    @Configuration
93
    @EnableAuthorizationServer
94
    protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
95

  
96
        private static final String CLIENT_ID = "any-client";
97

  
98
        @Autowired
99
        private UserApprovalHandler userApprovalHandler;
100

  
101
        @Autowired
102
        private AuthenticationManager authenticationManager;
103

  
104
        @Bean
105
        public TokenStore tokenStore() {
106
            return new InMemoryTokenStore();
107
        }
108

  
109

  
110
        @Override
111
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
112
            // @formatter:off
113
            clients
114
            .inMemory()
115
            .withClient(CLIENT_ID)
116
            //.resourceIds(RESOURCE_ID)
117
            .authorizedGrantTypes("authorization_code", "refresh_token", "implicit")
118
            .authorities("ROLE_CLIENT")
119
            .scopes("read", "write", "trust")
120
            .secret("secret") // secret for login of the client into /oauth/token
121
            .autoApprove("read");
122
            // @formatter:on
123
        }
124

  
125
        @Override
126
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
127
            endpoints.tokenStore(tokenStore()).userApprovalHandler(userApprovalHandler)
128
                    .authenticationManager(authenticationManager);
129
        }
130

  
131
    }
132

  
133
   protected static class CommonBeans {
134

  
135
        @Autowired
136
        private ClientDetailsService clientDetailsService;
137

  
138

  
139
        @Bean
140
        public ApprovalStore approvalStore() {
141
            return new InMemoryApprovalStore();
142
        }
143

  
144
        @Bean
145
        @Lazy
146
        @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
147
        public CdmUserApprovalHandler userApprovalHandler() throws Exception {
148
            CdmUserApprovalHandler handler = new CdmUserApprovalHandler();
149
            handler.setApprovalStore(approvalStore());
150
            handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
151
            handler.setClientDetailsService(clientDetailsService);
152
            handler.setUseApprovalStore(false);
153
            return handler;
154
        }
155
    }
156
}

Also available in: Unified diff

Add picture from clipboard (Maximum size: 40 MB)