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.apache.logging.log4j.LogManager;
|
12
|
import org.apache.logging.log4j.Logger;
|
13
|
import org.springframework.beans.factory.annotation.Autowired;
|
14
|
import org.springframework.context.annotation.Bean;
|
15
|
import org.springframework.context.annotation.Configuration;
|
16
|
import org.springframework.context.annotation.Lazy;
|
17
|
import org.springframework.context.annotation.Scope;
|
18
|
import org.springframework.context.annotation.ScopedProxyMode;
|
19
|
import org.springframework.http.HttpMethod;
|
20
|
import org.springframework.security.authentication.AuthenticationManager;
|
21
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
22
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
23
|
import org.springframework.security.oauth2.config.annotation.builders.InMemoryClientDetailsServiceBuilder;
|
24
|
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
|
25
|
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
|
26
|
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
|
27
|
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
|
28
|
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
|
29
|
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
|
30
|
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
|
31
|
import org.springframework.security.oauth2.provider.ClientDetailsService;
|
32
|
import org.springframework.security.oauth2.provider.approval.ApprovalStore;
|
33
|
import org.springframework.security.oauth2.provider.approval.InMemoryApprovalStore;
|
34
|
import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
|
35
|
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
|
36
|
import org.springframework.security.oauth2.provider.token.TokenStore;
|
37
|
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
|
38
|
|
39
|
import eu.etaxonomy.cdm.remote.oauth2.CdmUserApprovalHandler;
|
40
|
|
41
|
@Configuration
|
42
|
public class OAuth2ServerConfiguration {
|
43
|
|
44
|
private static final String CDM_RESOURCE_ID = "cdm";
|
45
|
|
46
|
private static final String ACCEXPR_MANAGE_CLIENT =
|
47
|
"#oauth2.clientHasRole('ROLE_CLIENT') "
|
48
|
+ "or (!#oauth2.isOAuth() and ( "
|
49
|
+ " hasRole('ROLE_ADMIN') or hasRole('" + MultiWebSecurityConfiguration.ROLE_MANAGE_CLIENT + "')"
|
50
|
+ " )"
|
51
|
+ ")";
|
52
|
|
53
|
@EnableResourceServer
|
54
|
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
|
55
|
|
56
|
@Override
|
57
|
public void configure(ResourceServerSecurityConfigurer resources) {
|
58
|
resources.resourceId(CDM_RESOURCE_ID).stateless(false);
|
59
|
}
|
60
|
|
61
|
@Override
|
62
|
public void configure(HttpSecurity http) throws Exception {
|
63
|
// @formatter:off
|
64
|
http
|
65
|
// Since we want the protected resources to be accessible in the UI as well we need
|
66
|
// session creation to be allowed (it's disabled by default in 2.0.6)
|
67
|
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
|
68
|
.and()
|
69
|
.authorizeRequests()
|
70
|
// see
|
71
|
// - http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#el-access
|
72
|
// or
|
73
|
// org.springframework.security.access.expression.SecurityExpressionRoot
|
74
|
// - org.springframework.security.oauth2.provider.expression.OAuth2SecurityExpressionMethods
|
75
|
.antMatchers(HttpMethod.OPTIONS, "/manage/**").permitAll() // see #6393
|
76
|
.antMatchers("/manage/**").access(ACCEXPR_MANAGE_CLIENT)
|
77
|
.antMatchers("/**description/accumulateDistributions").access(ACCEXPR_MANAGE_CLIENT)
|
78
|
.antMatchers("/user/me").access("isAuthenticated()")
|
79
|
.regexMatchers("/user/.*|/user\\..*").access("hasAnyRole('ROLE_ADMIN', 'ROLE_USER_MANAGER')")
|
80
|
|
81
|
// ------ DELVELOPER SNIPPETS ------
|
82
|
// experiments with classification controller
|
83
|
//.regexMatchers("/classification/.*|/classification\\..*")
|
84
|
//.access("#oauth2.hasScope('trust')")
|
85
|
//.access("hasAnyRole('ROLE_ADMIN', 'ROLE_USER')")
|
86
|
//.access("#oauth2.clientHasRole('ROLE_CLIENT') or (!#oauth2.isOAuth() and hasAnyRole('ROLE_ADMIN', 'ROLE_USER'))")
|
87
|
//
|
88
|
// .regexMatchers(HttpMethod.DELETE, "/oauth/users/([^/].*?)/tokens/.*")
|
89
|
// .access("#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient()) and #oauth2.hasScope('write')")
|
90
|
// .regexMatchers(HttpMethod.GET, "/oauth/clients/([^/].*?)/users/.*")
|
91
|
// .access("#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient()) and #oauth2.hasScope('read')")
|
92
|
// .regexMatchers(HttpMethod.GET, "/oauth/clients/.*")
|
93
|
// .access("#oauth2.clientHasRole('ROLE_CLIENT') and #oauth2.isClient() and #oauth2.hasScope('read')");
|
94
|
// ---------------------------
|
95
|
.and().httpBasic();
|
96
|
// @formatter:on
|
97
|
}
|
98
|
|
99
|
}
|
100
|
|
101
|
/**
|
102
|
* @author a.kohlbecker
|
103
|
* @since Oct 6, 2016
|
104
|
*/
|
105
|
@Configuration
|
106
|
@EnableAuthorizationServer
|
107
|
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
|
108
|
|
109
|
private static final String CLIENT_ID = "any-client";
|
110
|
|
111
|
public static final Logger logger = LogManager.getLogger(AuthorizationServerConfiguration.class);
|
112
|
|
113
|
@Autowired
|
114
|
private UserApprovalHandler userApprovalHandler;
|
115
|
|
116
|
@Autowired
|
117
|
@Lazy // avoid dependency cycle coming from UserService.authenticationManager
|
118
|
private AuthenticationManager authenticationManager;
|
119
|
|
120
|
@Bean
|
121
|
public TokenStore tokenStore() {
|
122
|
return new InMemoryTokenStore();
|
123
|
}
|
124
|
|
125
|
|
126
|
@Override
|
127
|
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
|
128
|
|
129
|
InMemoryClientDetailsServiceBuilder builder = clients.inMemory();
|
130
|
|
131
|
// @formatter:off
|
132
|
/*
|
133
|
* Client for 'implicit grant'
|
134
|
*/
|
135
|
builder.withClient(CLIENT_ID)
|
136
|
//.resourceIds(RESOURCE_ID)
|
137
|
.authorizedGrantTypes("authorization_code", "refresh_token", "implicit")
|
138
|
.authorities("ROLE_CLIENT")
|
139
|
.scopes("read", "write", "trust")
|
140
|
.secret("secret") // secret for login of the client into /oauth/token
|
141
|
.autoApprove("read");
|
142
|
// @formatter:on
|
143
|
|
144
|
}
|
145
|
|
146
|
|
147
|
@Override
|
148
|
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
|
149
|
endpoints.tokenStore(tokenStore()).userApprovalHandler(userApprovalHandler)
|
150
|
.authenticationManager(authenticationManager);
|
151
|
}
|
152
|
|
153
|
}
|
154
|
|
155
|
|
156
|
protected static class CommonBeans {
|
157
|
|
158
|
@Autowired
|
159
|
private ClientDetailsService clientDetailsService;
|
160
|
|
161
|
|
162
|
@Bean
|
163
|
public ApprovalStore approvalStore() {
|
164
|
return new InMemoryApprovalStore();
|
165
|
}
|
166
|
|
167
|
@Bean
|
168
|
@Lazy
|
169
|
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
|
170
|
public CdmUserApprovalHandler userApprovalHandler() throws Exception {
|
171
|
CdmUserApprovalHandler handler = new CdmUserApprovalHandler();
|
172
|
handler.setApprovalStore(approvalStore());
|
173
|
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
|
174
|
handler.setClientDetailsService(clientDetailsService);
|
175
|
handler.setUseApprovalStore(false);
|
176
|
return handler;
|
177
|
}
|
178
|
}
|
179
|
}
|