View Javadoc
1   /*
2    * Copyright 2018-2022 Medical Information Systems Research Group (https://medical.zcu.cz),
3    * Department of Computer Science and Engineering, University of West Bohemia.
4    * Address: Univerzitni 8, 306 14 Plzen, Czech Republic.
5    *
6    * Author Petr Vcelak (vcelak@kiv.zcu.cz).
7    *
8    * This file is part of MRECore project.
9    *
10   * MRECore is free software: you can redistribute it and/or modify
11   * it under the terms of the GNU General Public License as published by
12   * the Free Software Foundation, either version 3 of the License.
13   *
14   * MRECore is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17   * GNU General Public License for more details.
18   *
19   * You should have received a copy of the GNU General Public License
20   * along with MRECore. If not, see <http://www.gnu.org/licenses/>.
21   */
22  package cz.zcu.mre.config;
23  
24  import cz.zcu.mre.service.account.AccountService;
25  import cz.zcu.mre.service.account.AccountServiceImpl;
26  import cz.zcu.mre.service.data.MREDataService;
27  import org.slf4j.Logger;
28  import org.slf4j.LoggerFactory;
29  import org.springframework.beans.factory.annotation.Autowired;
30  import org.springframework.context.annotation.Bean;
31  import org.springframework.context.annotation.Configuration;
32  import org.springframework.core.Ordered;
33  import org.springframework.core.annotation.Order;
34  import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
35  import org.springframework.security.config.annotation.web.builders.HttpSecurity;
36  import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
37  import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
38  import org.springframework.security.crypto.password.PasswordEncoder;
39  import org.springframework.security.web.SecurityFilterChain;
40  import org.springframework.security.web.access.AccessDeniedHandler;
41  import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
42  
43  /**
44   * SecurityConfiguration with Spring Security 5.
45   * 
46   * @author Petr Vcelak (vcelak@kiv.zcu.cz)
47   */
48  @Configuration
49  @EnableWebSecurity
50  //@EnableGlobalMethodSecurity(securedEnabled = true)
51  @Order(value = Ordered.LOWEST_PRECEDENCE)
52  public class SecurityConfiguration  {
53  
54      private static final Logger LOG = LoggerFactory.getLogger(SecurityConfiguration.class);
55  
56      @Autowired
57      private MREDataService dataService;
58  
59      private AccountService accountService;
60  
61      @Bean
62      public AccountService accountService() {
63  
64          if (accountService == null) {
65              LOG.info("Create bean accountService");
66              accountService = new AccountServiceImpl(dataService, passwordEncoder());
67          }
68  
69          return accountService;
70      }
71  
72      @Bean
73      public TokenBasedRememberMeServices rememberMeServices() {
74          return new TokenBasedRememberMeServices("remember-me-key", accountService());
75      }
76  
77      @Bean
78      public PasswordEncoder passwordEncoder() {
79  
80          return new BCryptPasswordEncoder();
81      }
82  
83      @Autowired
84      public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
85          auth
86                  .eraseCredentials(true)
87                  .userDetailsService(accountService())
88                  .passwordEncoder(passwordEncoder());
89      }
90  
91      @Bean
92      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
93          http
94                  .csrf()
95                  .ignoringRequestMatchers("/api/**")
96                  .and()
97                  .exceptionHandling().accessDeniedHandler(accessDeniedHandler())
98                  .and()
99                  .authorizeHttpRequests()
100                 .requestMatchers("/", "/login", "/registration", "/favicon.ico", "/resources/**", "/api/**").permitAll()
101                 .requestMatchers("/api/**").permitAll()
102                 .anyRequest().authenticated()
103                 .and()
104                 .formLogin()
105                 .loginPage("/login").permitAll()
106                 //.failureUrl("/login?error=1")
107                 .failureForwardUrl("/login?error=1")
108                 .loginProcessingUrl("/authenticate")
109                 .and()
110                 .logout()
111                 .logoutUrl("/logout").permitAll()
112                 .logoutSuccessUrl("/login?logout")
113                 .and()
114                 .rememberMe()
115                 .rememberMeServices(rememberMeServices())
116                 .key("remember-me-key")
117                 .and()
118                 .headers().frameOptions().sameOrigin(); // allows iframe content from the same origin
119         return http.build();
120     }
121 
122     @Bean
123     public AccessDeniedHandler accessDeniedHandler() {
124         return new cz.zcu.mre.security.AccessDeniedHandler();
125     }
126 }