Project

General

Profile

Download (7.24 KB) Statistics
| Branch: | Tag: | Revision:
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 java.io.File;
12
import java.io.FileInputStream;
13
import java.io.IOException;
14
import java.util.Properties;
15

    
16
import org.apache.commons.io.FileUtils;
17
import org.springframework.beans.factory.annotation.Autowired;
18
import org.springframework.context.annotation.Configuration;
19
import org.springframework.context.annotation.Import;
20
import org.springframework.core.annotation.Order;
21
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
22
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
23
import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer;
24
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
25
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
26
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
27

    
28
import eu.etaxonomy.cdm.config.ConfigFileUtil;
29

    
30
/**
31
 *
32
 * <b>NOTE</b> on nested @Configuration classes:
33
 *
34
 * When bootstrapping such an arrangement, only the outer class need be registered against the application context.
35
 * By virtue of being a nested @Configuration class, DatabaseConfig will be registered automatically. This avoids
36
 * the need to use an @Import annotation when the relationship between AppConfig DatabaseConfig is already implicitly
37
 * clear.
38
 *
39
 * @author a.kohlbecker
40
 * @since Oct 6, 2016
41
 *
42
 */
43
@EnableWebSecurity
44
@Import(OAuth2ServerConfiguration.class)
45
public class MultiWebSecurityConfiguration {
46

    
47
    public static final String MANAGE_CLIENT = "MANAGE_CLIENT";
48

    
49
    public static final String ROLE_MANAGE_CLIENT = "ROLE_" + MANAGE_CLIENT;
50

    
51
    private static final String MANAGING_USERS_PROPERTIES = "managing-users.properties";
52

    
53
    @Autowired
54
    private ConfigFileUtil configFileUtil;
55

    
56
    /**
57
     * Check for full authentication for remoting services
58
     * @author a.kohlbecker
59
     * @since Oct 6, 2016
60
     *
61
     */
62
    @Configuration
63
    @Order(2)
64
    public static class RemotingWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
65
        @Override
66
        protected void configure(HttpSecurity http) throws Exception {
67
              // @formatter:off
68
                http
69
             .anonymous().disable()
70
             .antMatcher("/remoting/**")
71
                 .authorizeRequests().anyRequest().access("hasAnyRole('ROLE_ADMIN', 'ROLE_PROJECT_MANAGER', 'ROLE_REMOTING')")
72
                 .and()
73
             .csrf().disable()
74
             .httpBasic();
75
             // @formatter:on
76
        }
77
    }
78

    
79
    /**
80
     * Require full authentication on the OAuth2 authorization service
81
     * so that the user is requested to provide his credentials.
82
     *
83
     * @author a.kohlbecker
84
     * @since Jan 16, 2017
85
     *
86
     */
87
    @Configuration
88
    @Order(1)
89
    public static class LoginWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
90
        @Override
91
        protected void configure(HttpSecurity http) throws Exception {
92
              // @formatter:off
93
                http
94
             .anonymous().disable()
95
             .antMatcher("/oauth/authorize")
96
                 .authorizeRequests().anyRequest().fullyAuthenticated()
97
                 .and()
98
             .csrf().disable()
99
             .httpBasic();
100
             // @formatter:on
101
        }
102
    }
103

    
104
    /**
105
     * Allow anonymous authentication for all other services.
106
     *
107
     * <b>NOTE:</b> Further access restrictions are defined
108
     * in the OAuth2ServerConfiguration.
109
     *
110
     * @author a.kohlbecker
111
     * @since Oct 6, 2016
112
     *
113
     */
114
    @Configuration
115
    public static class DefaultWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
116

    
117
        @Override
118
        protected void configure(HttpSecurity http) throws Exception {
119
              // @formatter:off
120
                http
121
             .anonymous().and()
122
             .antMatcher("/**")
123
             .csrf().disable()
124
             .httpBasic();
125
             // @formatter:on
126
        }
127
    }
128

    
129
    @Autowired
130
    public void configureGlobal(AuthenticationManagerBuilder auth, DaoAuthenticationProvider daoAuthenticationProvider) throws Exception {
131

    
132
        // add the DaoAuthenticationProvider which is defined in
133
        // /cdmlib-services/src/main/resources/eu/etaxonomy/cdm/services_security.xml
134
        // if not added here it will not be added to the context as long as we are doing the
135
        // configuration explicitly here.
136
        auth.authenticationProvider(daoAuthenticationProvider);
137

    
138
        // Add an inMemoryUserManager to  enable access to the global ROLE_MANAGE_CLIENTs.
139
        // This is the casue for the need to do the configuration explicitly.
140
        InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> inMemoryAuthConf = auth.inMemoryAuthentication();
141
        File managingUsersFile = new File(configFileUtil.perUserCdmFolder(), MANAGING_USERS_PROPERTIES);
142
        if(!managingUsersFile.exists()){
143
            makeManagingUsersPropertiesFile(managingUsersFile);
144
        }
145
        Properties users = new Properties();
146
        users.load(new FileInputStream(managingUsersFile));
147
        for(Object userName : users.keySet()){
148
            inMemoryAuthConf.withUser(userName.toString()).password(users.get(userName).toString()).roles(MANAGE_CLIENT);
149
        }
150
    }
151

    
152
    /**
153
     * @param globalManagementClients
154
     * @throws IOException
155
     */
156
    private void makeManagingUsersPropertiesFile(File propertiesFile) throws IOException {
157
        propertiesFile.createNewFile();
158
        FileUtils.write(
159
                propertiesFile,
160
                "# Managing users properties file\n"
161
                + "#\n"
162
                + "# This file has been autogenerated by the cdmlib.\n"
163
                + "# In case the file is deleted the cdmlib will re-create it during the next start up.\n"
164
                + "#\n"
165
                + "# This is a java properties file to populate the InMemoryUserDetailsManager in any of \n"
166
                + "# the cdm-remote instances with special global management users which are granted to \n"
167
                + "# access special web services. Among these are the /manage/ web services and those\n"
168
                + "# triggering long running tasks. For more details please refer to\n"
169
                + "# https://dev.e-taxonomy.eu/redmine/projects/edit/wiki/CdmAuthorisationAndAccessControl\n"
170
                + "# \n"
171
                + "# Global management users have the role " + ROLE_MANAGE_CLIENT + ".\n"
172
                + "# and will be available in each of the cdm-remote instances.\n"
173
                + "# Changes made to this file are applied after restarting a cdm instance.\n"
174
                + "#\n"
175
                + "# This properties file should contain entries in the form\n"
176
                + "#    username=password\n"
177
                + "# -------------------------------------------------------------------------------------------\n"
178
                + "#\n"
179
                );
180
        }
181
}
(3-3/5)