JavaRush /Blog Java /Random-MS /Mari perkenalkan log masuk biasa melalui e-mel dan OAuth2...

Mari perkenalkan log masuk biasa melalui e-mel dan OAuth2 kepada Spring Security menggunakan contoh perkhidmatan nota

Diterbitkan dalam kumpulan
Semasa menulis permohonan saya, saya berhadapan dengan kekurangan artikel yang jelas tentang cara membuat pengguna mendaftar melalui e-mel dan rangkaian sosial. Terdapat tutorial yang baik tentang menyediakan borang log masuk klasik. Terdapat tutorial yang bagus tentang OAuth2 . Terdapat sedikit maklumat jenayah tentang cara menggabungkan kedua-dua kaedah. Semasa proses carian, kami dapat menghasilkan penyelesaian yang boleh dilaksanakan. Ia tidak mendakwa sebagai kebenaran muktamad, tetapi ia memenuhi fungsinya. Dalam artikel ini saya akan menunjukkan cara untuk melaksanakan perkhidmatan storan nota dengan konfigurasi Spring Security yang serupa dari awal. Mari perkenalkan log masuk biasa melalui e-mel dan OAuth2 ke Spring Security menggunakan contoh perkhidmatan nota - 1Nota: adalah baik jika pembaca telah melalui sekurang-kurangnya beberapa tutorial tentang Spring, kerana perhatian akan tertumpu hanya pada Spring Security, tanpa penjelasan terperinci tentang repositori, pengawal, dll. Jika tidak, artikel yang sudah agak besar akan bertukar menjadi menjadi raksasa. Kandungan
  1. Mencipta Projek
  2. Mencipta Entiti dan Logik Aplikasi
    1. Entiti
    2. Repositori
    3. Pengawal
    4. muka surat
  3. Mengkonfigurasi Keselamatan Musim Bunga untuk Log Masuk Klasik
    1. Konfigurasi asas SecurityConfig
    2. Log masuk pengguna tersuai
    3. Mari kita perbaiki pengawal
    4. Pelancaran
  4. Menyediakan OAuth2 menggunakan Google sebagai contoh dalam Spring Security
    1. Konfigurasi penapis dan aplikasi.properties
    2. Sorotan pendaftaran aplikasi dengan Google Cloud Platform
    3. CustomUserInfoTokenServices
  5. Pelancaran akhir projek

Mencipta Projek

Kami pergi ke start.spring.io dan membentuk asas projek:
  • Web - melancarkan aplikasi pada Tomcat terbina dalam, pemetaan url dan seumpamanya;
  • JPA - sambungan pangkalan data;
  • Misai ialah enjin templat yang digunakan untuk menjana halaman web;
  • Keselamatan - perlindungan aplikasi. Untuk tujuan inilah artikel ini dicipta.
Muat turun arkib yang terhasil dan buka bungkusannya dalam folder yang anda perlukan. Kami melancarkannya dalam IDE. Anda boleh memilih pangkalan data mengikut budi bicara anda. Saya menggunakan MySQL sebagai pangkalan data untuk projek itu, jadi saya menambah kebergantungan berikut pada fail pom.xml dalam blok <dependencies>:
<dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
     <version>5.1.34</version>
</dependency>
Konfigurasi application.properties pada masa ini adalah seperti berikut:
spring.datasource.url=jdbc:mysql://localhost:3306/springsectut?createDatabaseIfNotExist=true&useSSL=false&autoReconnect=true&useLegacyDatetimeCode=false&serverTimezone=UTC&useUnicode=yes&characterEncoding=UTF-8
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=yourUsername
spring.datasource.password=yourPassword

spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update

spring.jpa.properties.connection.characterEncoding=utf-8
spring.jpa.properties.connection.CharSet=utf-8
spring.jpa.properties.connection.useUnicode=true

spring.mustache.expose-request-attributes=true

Mencipta Entiti dan Logik Aplikasi

Entiti

Mari kita buat pakej entitiesdi mana kita akan meletakkan entiti pangkalan data. Pengguna akan diterangkan oleh kelas Useryang melaksanakan antara muka UserDetails, yang akan diperlukan untuk konfigurasi Spring Security. Pengguna akan mempunyai id, nama pengguna (ini ialah e-mel), kata laluan, nama, peranan, bendera aktiviti, nama akaun Google dan e-mel ( googleNamedan googleUsername).
@Entity
@Table(name = "user")
public class User implements UserDetails
{
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;

  private String username;
  private String password;
  private String name;
  private boolean active;
  private String googleName;
  private String googleUsername;

  @ElementCollection(targetClass = Role.class, fetch = FetchType.EAGER)
  @CollectionTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"))
  @Enumerated(EnumType.STRING)
  private Set<Role> roles;

    //Геттеры, сеттеры, toString(), equals(), hashcode(), имплементация UserDetails
}
Peranan pengguna digunakan untuk mengawal selia akses dalam Spring Security. Aplikasi kami hanya akan menggunakan satu peranan:
public enum Role implements GrantedAuthority
{
  USER;

  @Override
  public String getAuthority()
  {
     return name();
  }
}
Mari buat kelas nota dengan id, tajuk nota, isi nota dan id pengguna yang menjadi miliknya:
@Entity
@Table(name = "note")
public class Note
{
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;

  private String title;
  private String note;
  private Long userId;

    //Геттеры, сеттеры, toString(), equals(), hashcode()
}

Repositori

Untuk menyimpan entiti ke pangkalan data, kami memerlukan repositori yang akan melakukan semua kerja kotor untuk kami. Mari kita buat pakej repos, di dalamnya kita akan mencipta antara muka UserRepoyang diwarisi NoteRepodaripada antara muka JpaRepository<Entity, Id>.
@Service
@Repository
public interface UserRepo extends JpaRepository<User, Long>
{}

@Service
@Repository
public interface NoteRepo extends JpaRepository<Note, Long>
{
  List<Note> findByUserId(Long userId);
}

Pengawal

Perkhidmatan nota kami akan mempunyai halaman berikut:
  • Rumah;
  • Pendaftaran;
  • Pintu masuk;
  • Senarai nota pengguna.
Hanya pengguna yang diberi kuasa harus mempunyai akses kepada senarai nota. Halaman selebihnya adalah awam. Mari buat pakej controllersyang mengandungi kelas IndexControlleryang mengandungi pemetaan dapatkan biasa halaman utama. Kelas RegistrationControllerbertanggungjawab untuk mendaftarkan pengguna. Pemetaan selepas mengambil data daripada borang, menyimpan pengguna ke pangkalan data dan mengubah hala ke halaman log masuk. PasswordEncoderakan diterangkan kemudian. Ia digunakan untuk menyulitkan kata laluan.
@Controller
public class RegistrationController
{
  @Autowired
  private UserRepo userRepo;

  @Autowired
  private PasswordEncoder passwordEncoder;

  @GetMapping("/registration")
  public String registration()
  {
     return "registration";
  }

  @PostMapping("/registration")
  public String addUser(String name, String username, String password)
  {
     User user = new User();
     user.setName(name);
     user.setUsername(username);
     user.setPassword(passwordEncoder.encode(password));
     user.setActive(true);
     user.setRoles(Collections.singleton(Role.USER));

     userRepo.save(user);

     return "redirect:/login";
  }
Pengawal yang bertanggungjawab untuk halaman senarai nota pada masa ini mengandungi fungsi yang dipermudahkan, yang akan menjadi lebih kompleks selepas pelaksanaan Spring Security.
@Controller
public class NoteController
{
  @Autowired
  private NoteRepo noteRepo;

  @GetMapping("/notes")
  public String notes(Model model)
  {
     List<Note> notes = noteRepo.findAll();
     model.addAttribute("notes", notes);

     return "notes";
  }

  @PostMapping("/addnote")
  public String addNote(String title, String note)
  {
     Note newNote = new Note();
     newNote.setTitle(title);
     newNote.setNote(note);

     noteRepo.save(newNote);

     return "redirect:/notes";
  }
}
Kami tidak akan menulis pengawal untuk halaman log masuk kerana ia digunakan oleh Spring Security. Sebaliknya, kami memerlukan konfigurasi khas. Seperti biasa, mari buat pakej lain, panggilnya configdan letakkan kelas di sana MvcConfig. Apabila kami menulis konfigurasi Spring Security, ia akan mengetahui halaman mana yang kami rujuk apabila kami menggunakan "/log masuk".
@Configuration
public class MvcConfig implements WebMvcConfigurer
{
  public void addViewControllers(ViewControllerRegistry registry)
  {
     registry.addViewController("/login").setViewName("login");
     registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
  }
}

muka surat

Saya menggunakan enjin templat Misai untuk mencipta halaman . Anda boleh melaksanakan satu lagi, tidak mengapa. Fail meta.misai telah dibuat untuk maklumat meta yang digunakan pada semua halaman. Ia juga termasuk Bootstrap untuk menjadikan halaman projek kami kelihatan lebih cantik. Halaman dibuat dalam direktori "src/main/resources/templates". Fail mempunyai misai sambungan. Meletakkan kod html terus dalam artikel akan menjadikannya terlalu besar, jadi berikut ialah pautan ke folder templat dalam repositori GitHub projek .

Mengkonfigurasi Keselamatan Musim Bunga untuk Log Masuk Klasik

Spring Security membantu kami melindungi aplikasi dan sumbernya daripada akses tanpa kebenaran. Kami akan mencipta konfigurasi kerja ringkas dalam kelas SecurityConfigyang diwarisi daripada WebSecurityConfigurerAdapter, yang akan kami letakkan dalam pakej config. Mari tandakannya dengan anotasi @EnableWebSecurity, yang akan mendayakan sokongan Spring Security dan anotasi @Configuration, yang menunjukkan bahawa kelas ini mengandungi beberapa konfigurasi. Nota: pom.xml yang dikonfigurasikan secara automatik mengandungi versi komponen induk Spring Boot 2.1.4.RELEASE, yang menghalang Keselamatan daripada dilaksanakan dengan cara yang ditetapkan. Untuk mengelakkan konflik dalam projek, adalah disyorkan untuk menukar versi kepada 2.0.1.RELEASE.

Konfigurasi asas SecurityConfig

Konfigurasi kami akan dapat:
  1. Sulitkan kata laluan menggunakan BCryptPasswordEncoder:

    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Bean
    PasswordEncoder passwordEncoder()
    {
      PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
      return passwordEncoder;
    }
  2. Log masuk menggunakan pembekal pengesahan bertulis khas:

    @Autowired
    private AuthProvider authProvider;
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth)
    {
      auth.authenticationProvider(authProvider);
    }
  3. Benarkan pengguna tanpa nama mengakses halaman utama, halaman pendaftaran dan log masuk. Semua permintaan lain mesti dilakukan oleh pengguna yang log masuk. Mari kita tetapkan "/log masuk" yang diterangkan sebelum ini sebagai halaman log masuk. Jika log masuk berjaya, pengguna akan dibawa ke halaman dengan senarai nota; jika terdapat ralat, pengguna akan kekal di halaman log masuk. Apabila berjaya keluar, pengguna akan dibawa ke halaman utama.

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
      http
            .authorizeRequests()
            .antMatchers("/resources/**", "/", "/login**", "/registration").permitAll()
            .anyRequest().authenticated()
            .and().formLogin().loginPage("/login")
            .defaultSuccessUrl("/notes").failureUrl("/login?error").permitAll()
            .and().logout().logoutSuccessUrl("/").permitAll();
    }

Log masuk pengguna tersuai

Yang ditulis sendiri AuthProviderakan membolehkan pengguna log masuk bukan sahaja melalui e-mel, tetapi juga dengan nama pengguna.
@Component
public class AuthProvider implements AuthenticationProvider
{
  @Autowired
  private UserService userService;

  @Autowired
  private PasswordEncoder passwordEncoder;

  public Authentication authenticate(Authentication authentication) throws AuthenticationException
  {
     String username = authentication.getName();
     String password = (String) authentication.getCredentials();

     User user = (User) userService.loadUserByUsername(username);

     if(user != null && (user.getUsername().equals(username) || user.getName().equals(username)))
     {
        if(!passwordEncoder.matches(password, user.getPassword()))
        {
           throw new BadCredentialsException("Wrong password");
        }

        Collection<? extends GrantedAuthority> authorities = user.getAuthorities();

        return new UsernamePasswordAuthenticationToken(user, password, authorities);
     }
     else
        throw new BadCredentialsException("Username not found");
  }

  public boolean supports(Class<?> arg)
  {
     return true;
  }
}
Seperti yang anda mungkin perasan, kelas UserServiceyang terletak dalam pakej bertanggungjawab untuk memuatkan pengguna services. Dalam kes kami, ia mencari pengguna bukan sahaja mengikut medan username, seperti pelaksanaan terbina dalam, tetapi juga dengan nama pengguna, nama akaun Google dan e-mel akaun Google. Dua kaedah terakhir akan berguna kepada kami apabila melaksanakan log masuk melalui OAuth2. Di sini kelas diberikan dalam versi singkatan.
@Service
public class UserService implements UserDetailsService
{
  @Autowired
  private UserRepo userRepo;

  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
  {
     User userFindByUsername = userRepo.findByUsername(username);
     //Остальные поиски

     if(userFindByUsername != null)
     {
        return userFindByUsername;
     }
     //Остальные проверки
     return null;
  }
}
Nota: jangan lupa tulis kaedah yang diperlukan dalam UserRepo!

Mari kita perbaiki pengawal

Kami telah mengkonfigurasi Spring Security. Sekarang adalah masa untuk memanfaatkan ini dalam pengawal nota anda. Kini setiap pemetaan akan menerima parameter Prinsipal tambahan, yang mana ia akan cuba mencari pengguna. Mengapa saya tidak boleh menyuntik kelas secara langsung User? Kemudian akan berlaku konflik kerana ketidakpadanan jenis pengguna apabila kami menulis log masuk melalui rangkaian sosial. Kami menyediakan fleksibiliti yang diperlukan terlebih dahulu. Kod pengawal nota kami kini kelihatan seperti ini:
@GetMapping("/notes")
public String notes(Principal principal, Model model)
{
  User user = (User) userService.loadUserByUsername(principal.getName());
  List<Note> notes = noteRepo.findByUserId(user.getId());
  model.addAttribute("notes", notes);
  model.addAttribute("user", user);

  return "notes";
}

@PostMapping("/addnote")
public String addNote(Principal principal, String title, String note)
{
  User user = (User) userService.loadUserByUsername(principal.getName());

  Note newNote = new Note();
  newNote.setTitle(title);
  newNote.setNote(note);
  newNote.setUserId(user.getId());

  noteRepo.save(newNote);

  return "redirect:/notes";
}
Nota: projek ini mempunyai perlindungan CSRF yang didayakan secara lalai , jadi sama ada nyahdayakannya untuk diri sendiri (http.csrf().disable()), atau jangan lupa, sebagai pengarang artikel, untuk menambah medan tersembunyi dengan token csrf kepada semua permintaan jawatan.

Pelancaran

Kami cuba melancarkan projek itu.
Mari perkenalkan log masuk biasa melalui e-mel dan OAuth2 ke Spring Security menggunakan contoh perkhidmatan nota - 1
Mari perkenalkan log masuk biasa melalui e-mel dan OAuth2 kepada Spring Security menggunakan contoh perkhidmatan nota - 2
Kami melihat bahawa pengguna baharu telah muncul dalam pangkalan data. Kata laluan disulitkan.
Mari perkenalkan log masuk biasa melalui e-mel dan OAuth2 kepada Spring Security menggunakan contoh perkhidmatan nota - 3
Mari perkenalkan log masuk biasa melalui e-mel dan OAuth2 ke Spring Security menggunakan contoh perkhidmatan nota - 4
Mari perkenalkan log masuk biasa melalui e-mel dan OAuth2 ke Spring Security menggunakan contoh perkhidmatan nota - 5
Mari perkenalkan log masuk biasa melalui e-mel dan OAuth2 ke Spring Security menggunakan contoh perkhidmatan nota - 6
Nota disimpan ke pangkalan data.
Mari perkenalkan log masuk biasa melalui e-mel dan OAuth2 kepada Spring Security menggunakan contoh perkhidmatan nota - 7
Kami melihat bahawa projek itu berjaya dilancarkan dan berjalan. Untuk kebahagiaan sepenuhnya, kami hanya memerlukan keupayaan untuk log masuk melalui rangkaian sosial. Baiklah, mari kita mulakan!

Menyediakan OAuth2 menggunakan Google sebagai contoh dalam Spring Security

Apabila melaksanakan OAuth2, saya bergantung pada tutorial rasmi ini daripada Spring . Untuk menyokong OAuth2, tambahkan pustaka berikut pada pom.xml:
<dependency>
  <groupId>org.springframework.security.oauth.boot</groupId>
  <artifactId>spring-security-oauth2-autoconfigure</artifactId>
  <version>2.0.0.RELEASE</version>
</dependency>
Mari ubah suai konfigurasi Spring Security kami dalam SecurityConfig. Mula-mula, mari tambah anotasi @EnableOAuth2Client. Ia secara automatik akan menarik apa yang anda perlukan untuk log masuk melalui rangkaian sosial.

Konfigurasi penapis dan aplikasi.properties

Mari kita menyuntik OAuth2ClientContext untuk digunakan dalam konfigurasi keselamatan kami.
@Autowired
private OAuth2ClientContext oAuth2ClientContext;
OAuth2ClientContext digunakan semasa membuat penapis yang mengesahkan permintaan log masuk sosial pengguna. Penapis tersedia terima kasih kepada anotasi @EnableOAuth2Client. Apa yang perlu kita lakukan ialah memanggilnya dalam susunan yang betul, sebelum penapis Keselamatan Musim Bunga utama. Hanya selepas itu kami akan dapat menangkap ubah hala semasa proses log masuk dengan OAuth2. Untuk melakukan ini, kami menggunakan FilterRegistrationBean, di mana kami menetapkan keutamaan penapis kami kepada -100.
@Bean
public FilterRegistrationBean oAuth2ClientFilterRegistration(OAuth2ClientContextFilter oAuth2ClientContextFilter)
{
  FilterRegistrationBean registration = new FilterRegistrationBean();
  registration.setFilter(oAuth2ClientContextFilter);
  registration.setOrder(-100);
  return registration;
}

private Filter ssoFilter()
{
  OAuth2ClientAuthenticationProcessingFilter googleFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/google");
  OAuth2RestTemplate googleTemplate = new OAuth2RestTemplate(google(), oAuth2ClientContext);
  googleFilter.setRestTemplate(googleTemplate);
  CustomUserInfoTokenServices tokenServices = new CustomUserInfoTokenServices(googleResource().getUserInfoUri(), google().getClientId());
  tokenServices.setRestTemplate(googleTemplate);
  googleFilter.setTokenServices(tokenServices);
  tokenServices.setUserRepo(userRepo);
  tokenServices.setPasswordEncoder(passwordEncoder);
  return googleFilter;
}
Anda juga perlu menambah penapis baharu pada fungsi konfigurasi(HttpSecurity http):
http.addFilterBefore(ssoFilter(), UsernamePasswordAuthenticationFilter.class);
Penapis juga perlu mengetahui bahawa pelanggan telah mendaftar melalui Google. Anotasi @ConfigurationProperties menentukan sifat konfigurasi yang hendak dicari dalam application.properties.
@Bean
@ConfigurationProperties("google.client")
public AuthorizationCodeResourceDetails google()
{
  return new AuthorizationCodeResourceDetails();
}
Untuk melengkapkan pengesahan, anda perlu menentukan titik akhir maklumat pengguna Google:
@Bean
@ConfigurationProperties("google.resource")
public ResourceServerProperties googleResource()
{
  return new ResourceServerProperties();
}
Setelah mendaftarkan aplikasi kami dalam Google Cloud Platform , kami akan menambah sifat dengan awalan yang sesuai pada application.properties:
google.client.clientId=yourClientId
google.client.clientSecret=yourClientSecret
google.client.accessTokenUri=https://www.googleapis.com/oauth2/v4/token
google.client.userAuthorizationUri=https://accounts.google.com/o/oauth2/v2/auth
google.client.clientAuthenticationScheme=form
google.client.scope=openid,email,profile
google.resource.userInfoUri=https://www.googleapis.com/oauth2/v3/userinfo
google.resource.preferTokenInfo=true

Sorotan pendaftaran aplikasi dengan Google Cloud Platform

Laluan: API dan Perkhidmatan -> Tetingkap Permintaan Akses OAuth Bukti kelayakan:
  • Nama aplikasi: Borang log masuk musim bunga dan tutorial OAuth2
  • Alamat e-mel sokongan: e-mel anda
  • Skop untuk API Google: e-mel, profil, openid
  • Domain dibenarkan: me.org
  • Pautan ke halaman utama permohonan: http://me.org:8080
  • Pautan ke dasar privasi apl: http://me.org:8080
  • Pautan ke syarat penggunaan aplikasi: http://me.org:8080
Bukti kelayakan:
  • Jenis: Aplikasi Web
  • Tajuk: Borang log masuk musim bunga dan tutorial OAuth2
  • Sumber JavaScript yang dibenarkan: http://me.org, http://me.org:8080
  • URI ubah hala yang dibenarkan: http://me.org:8080/login, http://me.org:8080/login/google
Nota: memandangkan Google tidak mahu bekerja dengan alamat localhost:8080, tambahkan baris "127.0.0.1 me.org" atau sesuatu yang serupa dengan fail C:\Windows\System32\drivers\etc\hosts pada penghujungnya. Perkara utama ialah domain itu dalam bentuk klasik.

CustomUserInfoTokenServices

Adakah anda perasan perkataan Tersuai dalam perihalan fungsi penapis? Kelas CustomUserInfoTokenServices. Ya, kami akan mencipta kelas kami sendiri dengan blackjack dan keupayaan untuk menyelamatkan pengguna dalam pangkalan data! Menggunakan pintasan papan kekunci Ctrl-N dalam IntelliJ IDEA, anda boleh mencari dan melihat cara UserInfoTokenServiceslalai dilaksanakan. Mari salin kodnya ke dalam kelas yang baru dibuat CustomUserInfoTokenServices. Kebanyakannya boleh dibiarkan tidak berubah. Sebelum menukar logik fungsi, mari tambah UserRepodan sebagai medan peribadi kelas PasswordEncoder. Mari kita buat setter untuk mereka. Mari tambahkan @Autowired UserRepo userRepo ke kelas SecurityConfig. Kami melihat bagaimana penunjuk kepada ralat dalam kaedah penciptaan penapis hilang, dan kami bergembira. Mengapa @Autowired tidak boleh digunakan terus ke CustomUserInfoTokenServices? Kerana kelas ini tidak akan mengambil kebergantungan, kerana ia sendiri tidak ditandakan dengan sebarang anotasi Spring, dan pembinanya dibuat secara eksplisit apabila penapis diisytiharkan. Sehubungan itu, mekanisme DI Spring tidak mengetahui mengenainya. Jika kami memberi anotasi @Autowired pada apa-apa sahaja dalam kelas ini, kami akan mendapat NullPointerException apabila digunakan. Tetapi melalui setter eksplisit semuanya berfungsi dengan baik. Selepas melaksanakan komponen yang diperlukan, objek utama yang diminati menjadi fungsi loadAuthentication, di mana Map<String, Object> dengan maklumat tentang pengguna diambil semula. Dalam projek ini saya melaksanakan penjimatan pengguna yang log masuk melalui rangkaian sosial ke dalam pangkalan data. Memandangkan kami menggunakan akaun Google sebagai penyedia OAuth2, kami menyemak sama ada peta mengandungi medan "sub" yang biasa untuk Google. Jika ia hadir, ini bermakna maklumat tentang pengguna telah diterima dengan betul. Kami mencipta pengguna baharu dan menyimpannya ke pangkalan data.
@Override
public OAuth2Authentication loadAuthentication(String accessToken)
     throws AuthenticationException, InvalidTokenException
{
  Map<String, Object> map = getMap(this.userInfoEndpointUrl, accessToken);

  if(map.containsKey("sub"))
  {
     String googleName = (String) map.get("name");
     String googleUsername = (String) map.get("email");

     User user = userRepo.findByGoogleUsername(googleUsername);

     if(user == null)
     {
        user = new User();
        user.setActive(true);
        user.setRoles(Collections.singleton(Role.USER));
     }

     user.setName(googleName);
     user.setUsername(googleUsername);
     user.setGoogleName(googleName);
     user.setGoogleUsername(googleUsername);
     user.setPassword(passwordEncoder.encode("oauth2user"));

     userRepo.save(user);
  }

  if (map.containsKey("error"))
  {
     this.logger.debug("userinfo returned error: " + map.get("error"));
     throw new InvalidTokenException(accessToken);
  }
  return extractAuthentication(map);
}
Apabila menggunakan beberapa pembekal, anda boleh menentukan pilihan berbeza dalam satu CustomUserInfoTokenServices dan mendaftarkan kelas perkhidmatan serupa yang berbeza dalam kaedah pengisytiharan penapis. Kini kedua-dua Pengguna dan OAuth2Authentication boleh bertindak sebagai Prinsipal. Memandangkan kami mengambil kira dalam UserService terlebih dahulu memuatkan pengguna melalui data Google, aplikasi akan berfungsi untuk kedua-dua jenis pengguna. Kami mengubah suai pengawal halaman utama projek supaya ia mengubah hala pengguna yang log masuk menggunakan OAuth2 ke halaman nota.
@GetMapping("/")
public String index(Principal principal)
{
  if(principal != null)
  {
     return "redirect:/notes";
  }
  return "index";
}

Pelancaran akhir projek

Selepas perubahan kosmetik kecil dan menambah butang keluar, kami melaksanakan pelancaran akhir projek itu.
Mari perkenalkan log masuk biasa melalui e-mel dan OAuth2 kepada Spring Security menggunakan contoh perkhidmatan nota - 8
Mari perkenalkan log masuk biasa melalui e-mel dan OAuth2 ke Spring Security menggunakan contoh perkhidmatan nota - 9
Mari perkenalkan log masuk biasa melalui e-mel dan OAuth2 kepada Spring Security menggunakan contoh perkhidmatan nota - 10
Mari perkenalkan log masuk biasa melalui e-mel dan OAuth2 kepada Spring Security menggunakan contoh perkhidmatan nota - 11
Mari perkenalkan log masuk biasa melalui e-mel dan OAuth2 kepada Spring Security menggunakan contoh perkhidmatan nota - 12
Mari perkenalkan log masuk biasa melalui e-mel dan OAuth2 kepada Spring Security menggunakan contoh perkhidmatan nota - 13
Mari perkenalkan log masuk biasa melalui e-mel dan OAuth2 kepada Spring Security menggunakan contoh perkhidmatan nota - 14
Mari perkenalkan log masuk biasa melalui e-mel dan OAuth2 kepada Spring Security menggunakan contoh perkhidmatan nota - 15
Pengguna berjaya log masuk melalui borang biasa dan melalui akaun Google. Inilah yang kami mahukan! Saya harap artikel ini telah menjelaskan beberapa perkara tentang membuat aplikasi web, mengamankannya dengan Spring Security, dan menggabungkan kaedah log masuk yang berbeza. Dengan kod projek penuh anda boleh
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION