IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Spring Java Discussion :

Authentification avec Spring Security et Angular


Sujet :

Spring Java

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    728
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 728
    Points : 250
    Points
    250
    Par défaut Authentification avec Spring Security et Angular
    Bonjour, j'implémente Spring Security sur une application Springboot-angular. Dans mon UserController, j'ai mappé une méthode avec l'url suivante: /api/user/login pour connecter l'utilisateur et récupérer ses informations. Quand je démarre l'application angular, l'url suivante: http://localhost:8080/api/user/login est déclenchée avec un code d'erreur 405. Je suppose que cela est dû au fait que j'ai ajouté la fonctionnalité Spring security. J'ai plusieurs questions:

    1) est-ce normal que l'url : http://localhost:8080/api/user/login, soit déclenchée au démarage de l'application angular ?. Je ne vois pas pourquoi, car dans mon application, je veux que la connection d'un utilisateur soit uniquement géré par un formulaire dans une pop up dédié.

    2) Si c'est normal, quelle est le but de cette requête ? Et comment dois implémenter la méthode du controlleur dédié à cette url ?

    3) dans mon application angular, j'ai configuré proxy.config.json comme suit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
        {
          "/api/*": {
     
            "target":  {
               "host": "localhost",
               "protocol": "http:",
               "port": 8080
             },
            "secure": false,
             "changeOrigin": true,
             "logLevel": "info"
          }
        }
    pour rediriger chaque requête http://localhost:42OO/api vers http://localhost:8080/api. Pour que ça soit pris en compte, je lance la partie angular avec cette commande: "ng serve --proxy-config proxy.config.json".

    Quand "http://localhost:8080/api/user/login" est déclenché, j'ai le message d'erreur suivant:

    Blocage d’une requête multiorigines (Cross-Origin Request) : la politique « Same Origin » ne permet pas de consulter la ressource distante située sur http://localhost:8080/login. Raison : l’en-tête CORS « Access-Control-Allow-Origin » est manquant.

    Donc, comment gérer ceci ?

    Voici la configuration back pour Spring Security:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
     
    Fichier WebSecurityConfig.java
     
        package com.example.demoImmobilierBack;
     
        import javax.sql.DataSource;
     
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.Configuration;
        import org.springframework.security.core.userdetails.UserDetailsService;
        import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
        import org.springframework.security.crypto.password.PasswordEncoder;
        import org.springframework.security.authentication.AuthenticationManager;
        import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
        import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
        import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
        import org.springframework.security.config.annotation.web.builders.HttpSecurity;
        import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
        import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
        import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
        import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
        import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
     
        import com.example.demoImmobilierBack.service.MyUserDetailsService;
     
        @Configuration
        @EnableWebSecurity
        @EnableGlobalMethodSecurity(prePostEnabled = true)
        public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
     
            @Bean
            public UserDetailsService userDetailsService() {
                return new MyUserDetailsService();
            }
     
            @Autowired
            private DataSource dataSource;
     
            @Bean
            public PasswordEncoder passwordEncoder() {
                return new BCryptPasswordEncoder();
            }
     
            @Bean
            public DaoAuthenticationProvider authenticationProvider() {
                DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
                authProvider.setUserDetailsService(userDetailsService());
                authProvider.setPasswordEncoder(passwordEncoder());
                return authProvider;
            }
     
            @Bean("authenticationManager")
            @Override
            public AuthenticationManager authenticationManagerBean() throws Exception {
                return super.authenticationManagerBean();
        }
     
            @Override
            protected void configure(AuthenticationManagerBuilder auth) {
                auth.authenticationProvider(authenticationProvider());
            }
     
            @Override
            protected void configure(HttpSecurity http) throws Exception {
            	http         
                .headers()
                 .frameOptions().sameOrigin()
                 .and()
                   .authorizeRequests()
                    .antMatchers("/**/*.scss", "/**/*.js","/**/*.html").permitAll()
                       .antMatchers("/").permitAll()
                       .antMatchers("/admin/**").hasRole("ADMIN")
                       .anyRequest().authenticated()
                       .and()
                   .formLogin()
                       .loginPage("/api/user/login")
                       .defaultSuccessUrl("/")
        //               .failureUrl("/login?error")
                       .failureUrl("/")
                       .permitAll()
                       .and()
                   .logout()
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                    .logoutSuccessUrl("/")
        //            .logoutSuccessUrl("/login?logout")
                    .deleteCookies("my-remember-me-cookie")
                       .permitAll()
                       .and()
                    .rememberMe()
                     //.key("my-secure-key")
                     .rememberMeCookieName("my-remember-me-cookie")
                     .tokenRepository(persistentTokenRepository())
                     .tokenValiditySeconds(24 * 60 * 60)
                     .and()
                   .exceptionHandling()
                   .and()
                   .csrf().disable();
            }
     
            PersistentTokenRepository persistentTokenRepository(){
                JdbcTokenRepositoryImpl tokenRepositoryImpl = new JdbcTokenRepositoryImpl();
                tokenRepositoryImpl.setDataSource(dataSource);
                return tokenRepositoryImpl;
            }
     
        }
    Le controlleur utilisateur UserController.java
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
        package com.example.demoImmobilierBack.controller;
     
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.http.MediaType;
        import org.springframework.web.bind.annotation.RequestBody;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RequestMethod;
        import org.springframework.web.bind.annotation.ResponseBody;
        import org.springframework.web.bind.annotation.RestController;
     
        import com.example.demoImmobilierBack.dto.UserDTO;
        import com.example.demoImmobilierBack.service.UserService;
     
        @RestController
        @RequestMapping({"/api/user"})
        public class UserController {
     
            @Autowired
            private UserService userService;
     
            @RequestMapping(value = "/login",
            method = RequestMethod.POST)
            public @ResponseBody UserDTO login(@RequestBody UserDTO userDTO){
            	String message = userService.checkIfUserExistsAndGoodCredential(userDTO);
            	if (message.isEmpty()) {
            		userDTO = userService.findByEmailAndPassword(userDTO.getEmail(), userDTO.getPassword());
            		userDTO.setPassword("");
            	} else {
            		userDTO.setMessage(message);
            	}
                return userDTO;
            }
    Le fichier InitialDataLoader.java
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
     
        package com.example.demoImmobilierBack.service;
     
        import java.util.Arrays;
        import java.util.Collection;
        import java.util.List;
     
        import javax.transaction.Transactional;
     
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.context.ApplicationListener;
        import org.springframework.context.event.ContextRefreshedEvent;
        import org.springframework.security.crypto.password.PasswordEncoder;
        import org.springframework.stereotype.Component;
     
        import com.example.demoImmobilierBack.model.Privilege;
        import com.example.demoImmobilierBack.model.Role;
        import com.example.demoImmobilierBack.model.User;
        import com.example.demoImmobilierBack.repository.PrivilegeRepository;
        import com.example.demoImmobilierBack.repository.RoleRepository;
        import com.example.demoImmobilierBack.repository.UserRepository;
     
        @Component
        public class InitialDataLoader implements
          ApplicationListener<ContextRefreshedEvent> {
     
            boolean alreadySetup = false;
     
            @Autowired
            private UserRepository userRepository;
     
            @Autowired
            private RoleRepository roleRepository;
     
            @Autowired
            private PrivilegeRepository privilegeRepository;
     
            @Autowired
            private PasswordEncoder passwordEncoder;
     
            @Override
            @Transactional
            public void onApplicationEvent(ContextRefreshedEvent event) {
     
                if (alreadySetup)
                    return;
                Privilege readPrivilege
                  = createPrivilegeIfNotFound("READ_PRIVILEGE");
                Privilege writePrivilege
                  = createPrivilegeIfNotFound("WRITE_PRIVILEGE");
     
                List<Privilege> adminPrivileges = Arrays.asList(
                  readPrivilege, writePrivilege);        
                createRoleIfNotFound("ADMIN", adminPrivileges);
                createRoleIfNotFound("LOUEUR", adminPrivileges);
                createRoleIfNotFound("ACHETER", adminPrivileges);
                createRoleIfNotFound("DEPOSE_LOUER", adminPrivileges);
                createRoleIfNotFound("DEPOSE_ACHETER", adminPrivileges);
                createRoleIfNotFound("AGENCE", adminPrivileges);
                createRoleIfNotFound("PROMOTEUR", adminPrivileges);
     
     
     
                Role adminRole = roleRepository.findByName("ADMIN");
     
                User user = userRepository.findByEmail("flamant@club-internet.fr");
                if (user == null) {
        	        user = new User();
        	        user.setGender("M");
        	        user.setFirstName("adminFirstName");
        	        user.setLastName("adminLastName");
        	        user.setRaisonSociale("adminLastName");
        	        user.setName("PARTICULIER");
        	        user.setLastName("adminLastName");
        	        user.setPassword(passwordEncoder.encode("adminPassword"));
        	        user.setEmail("flamant@club-internet.fr");
        	        user.setRoles(Arrays.asList(adminRole));
        	        user.setEnabled(true);
        	        user.setAccountNonExpired(true);
        	        user.setAccountNonLocked(true);
        	        user.setCredentialsNonExpired(true);
        	        userRepository.save(user);
                }
     
                alreadySetup = true;
            }
     
            @Transactional
            private Privilege createPrivilegeIfNotFound(String name) {
     
                Privilege privilege = privilegeRepository.findByName(name);
                if (privilege == null) {
                    privilege = new Privilege(name);
                    privilegeRepository.save(privilege);
                }
                return privilege;
            }
     
            @Transactional
            private Role createRoleIfNotFound(
              String name, Collection<Privilege> privileges) {
     
                Role role = roleRepository.findByName(name);
                if (role == null) {
                    role = new Role(name);
                    role.setPrivileges(privileges);
                    roleRepository.save(role);
                }
                return role;
            }
        }
    L'impémentation UserDetailsService:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
     
        package com.example.demoImmobilierBack.service;
     
        import java.util.ArrayList;
        import java.util.Arrays;
        import java.util.Collection;
        import java.util.List;
     
        import javax.transaction.Transactional;
     
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.context.MessageSource;
        import org.springframework.security.core.GrantedAuthority;
        import org.springframework.security.core.authority.SimpleGrantedAuthority;
        import org.springframework.security.core.userdetails.UserDetails;
        import org.springframework.security.core.userdetails.UserDetailsService;
        import org.springframework.security.core.userdetails.UsernameNotFoundException;
        import org.springframework.stereotype.Service;
     
        import com.example.demoImmobilierBack.model.Privilege;
        import com.example.demoImmobilierBack.model.Role;
        import com.example.demoImmobilierBack.model.User;
        import com.example.demoImmobilierBack.repository.RoleRepository;
        import com.example.demoImmobilierBack.repository.UserRepository;
     
        @Service("userDetailsService")
        @Transactional
        public class MyUserDetailsService implements UserDetailsService {
     
            @Autowired
            private UserRepository userRepository;
     
            //@Autowired
            //private IUserService service;
     
            @Autowired
            private MessageSource messages;
     
            @Autowired
            private RoleRepository roleRepository;
     
            @Override
            public UserDetails loadUserByUsername(String email)
              throws UsernameNotFoundException {
     
                User user = userRepository.findByEmail(email);
                if (user == null) {
                    return new org.springframework.security.core.userdetails.User(
                      " ", " ", true, true, true, true, 
                      (Collection<? extends GrantedAuthority>) getAuthorities(Arrays.asList(roleRepository.findByName("ROLE_USER"))));
                }
     
                return new org.springframework.security.core.userdetails.User(
                  user.getEmail(), user.getPassword(), user.isEnabled(), user.isAccountNonExpired(), user.isCredentialsNonExpired(), 
                  user.isAccountNonLocked(), getRolesAuthorities(user.getRoles()));
            }
     
            private Collection<? extends GrantedAuthority> getRolesAuthorities(
            	      Collection<Role> roles) {
        		List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        		for (Role role :roles) {
        			authorities.add(new SimpleGrantedAuthority(role.getName()));
        		}
     
        		return authorities;
            }
     
            private Collection<? extends GrantedAuthority> getAuthorities(
              Collection<Role> roles) {
     
                return getGrantedAuthorities(getPrivileges(roles));
            }
     
            private List<String> getPrivileges(Collection<Role> roles) {
     
                List<String> privileges = new ArrayList<>();
                List<Privilege> collection = new ArrayList<>();
                for (Role role : roles) {
                    collection.addAll(role.getPrivileges());
                }
                for (Privilege item : collection) {
                    privileges.add(item.getName());
                }
                return privileges;
            }
     
            private List<GrantedAuthority> getGrantedAuthorities(List<String> privileges) {
                List<GrantedAuthority> authorities = new ArrayList<>();
                for (String privilege : privileges) {
                    authorities.add(new SimpleGrantedAuthority(privilege));
                }
                return authorities;
            }
        }

  2. #2
    Membre actif
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    728
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 728
    Points : 250
    Points
    250
    Par défaut
    Bonjour, j'ai tout résolu

    pour le message d'erreur suivant

    Blocage d’une requête multiorigines (Cross-Origin Request) : la politique « Same Origin » ne permet pas de consulter la ressource distante située sur http://localhost:8080/login. Raison : l’en-tête CORS « Access-Control-Allow-Origin » est manquant.
    j'ai permis les requêtes cross origine en rajoutant du coté serveur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    @SpringBootApplication
    public class Application implements WebMvcConfigurer {
        ...
     
        /**
         * CORS configuration
         */
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins(
                            "http://localhost:4200"
                    )
                    .allowedMethods(
                            "GET",
                            "PUT",
                            "POST",
                            "DELETE",
                            "PATCH",
                            "OPTIONS"
                    );
        }
    En ce qui concerne la fait que l'url : http://localhost:8080/api/user/login, soit déclenchée au démarrage de l'application angular, cela est dû au fait que je ne permettais pas l'accès à un utilisateur anonyme pour la requête éxécutée lors de l'affichage de la page principale, du coup le serveur me renvoyait l'url d'accès à la page du formulaire d'authentification et déclanchait cette même requête. Donc, j'ai rajouté la ligne suivante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    .antMatchers("/**/*").permitAll()
    dans le code suivant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http         
        .headers()
         .frameOptions().sameOrigin()
         .and()
           .authorizeRequests()
            .antMatchers("/**/*.scss", "/**/*.js","/**/*.html").permitAll()
               .antMatchers("/**/*").permitAll()
               .antMatchers("/admin/**").hasRole("ADMIN")
               .anyRequest().authenticated()
               .and()
           .formLogin()
               .loginPage("/api/user/login")
               .defaultSuccessUrl("/")
               .failureUrl("/")
               .permitAll()
               .and()
           .logout()

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Security] Simple authentification avec spring security
    Par rachida90 dans le forum Spring
    Réponses: 1
    Dernier message: 21/01/2014, 10h13
  2. [Security] Plusieurs types d'authentification avec spring security
    Par soumayachouchene dans le forum Spring
    Réponses: 0
    Dernier message: 10/04/2013, 18h45
  3. [Security] Authentification avec Spring Security
    Par tiamo dans le forum Spring
    Réponses: 1
    Dernier message: 11/09/2012, 14h01
  4. [Security] Utiliser l'authentification avec Spring Security
    Par wadjaawbk dans le forum Spring
    Réponses: 4
    Dernier message: 21/11/2011, 18h23
  5. Réponses: 1
    Dernier message: 19/12/2010, 12h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo