JavaRush /Java блогу /Random-KY /Келгиле, электрондук почта жана OAuth2 аркылуу жазгы кооп...

Келгиле, электрондук почта жана OAuth2 аркылуу жазгы коопсуздукка үзгүлтүксүз логинди киргизели, ноталар кызматынын мисалында

Группада жарыяланган
Арызымды жазып жатып, колдонуучуну электрондук почта аркылуу да, социалдык тармактарда да каттоодон өткөрүү боюнча так макалалардын жоктугуна туш болдум. Классикалык кирүү формасын орнотуу боюнча жакшы окуу куралдары бар болчу. OAuth2 боюнча жакшы окуу куралдары бар болчу . Бул эки ыкманы кантип айкалыштыруу боюнча кылмыштуу аз маалымат болгон. Издөө процессинде биз иштиктүү чечимге келе алдык. Ал акыркы чындык деп ырастаbyte, бирок ал өз милдетин аткарат. Бул макалада мен нөлдөн окшош Spring Security конфигурациясы менен ноталарды сактоо кызматын кантип ишке ашырууну көрсөтөм. Келгиле, электрондук почта жана OAuth2 аркылуу жазгы коопсуздукка үзгүлтүксүз логинди киргизели, ноталар кызматынын мисалында - 1Эскертүү: Окурман жаз боюнча жок дегенде бир нече окуу куралдарынан өтүп кетсе жакшы болот, анткени көңүл жазгы коопсуздукка гана бурулат, репозиторийлер, контроллерлор ж.б.у.с. деталдуу түшүндүрмөлөр жок. Болбосо, ансыз деле чоң макала чыгып калмак. гигант болуу. Мазмун
  1. Долбоорду түзүү
  2. Объекттерди жана Колдонмо логикасын түзүү
    1. Объекттер
    2. Репозиторийлер
    3. Контроллерлор
    4. Барактар
  3. Классикалык кирүү үчүн жазгы коопсуздукту конфигурациялоо
    1. Негизги конфигурация SecurityConfig
    2. Ыңгайлаштырылган колдонуучу кирүү
    3. Контроллорду жакшырталы
    4. Ишке киргизүү
  4. Жазгы коопсуздукта мисал катары Google аркылуу OAuth2 орнотуу
    1. Чыпка конфигурациясын жана application.properties
    2. Google Cloud Platform менен тиркемени каттоонун негизги учурлары
    3. CustomUserInfoTokenServices
  5. Долбоордун акыркы башталышы

Долбоорду түзүү

Биз start.spring.io сайтына кирип , долбоордун негизин түзөбүз:
  • Web - камтылган Tomcat, url карталары жана башка ушул сыяктуу тиркемелерди ишке киргизүү;
  • JPA - маалымат базасына кошулуу;
  • Мурут - веб-баракчаларды түзүү үчүн колдонулган шаблон кыймылдаткычы;
  • Коопсуздук - тиркемени коргоо. Бул макала эмне үчүн түзүлгөн.
Алынган архивди жүктөп алып, аны керектүү папкага чыгарыңыз. Биз аны IDEде ишке киргизебиз. Сиз өз каалооңуз боюнча маалымат базасын тандай аласыз. Мен MySQLди долбоордун маалымат базасы катары колдоном, ошондуктан <көз карандылык> блогундагы pom.xml файлына төмөнкү көз карандылыкты кошом:
<dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
     <version>5.1.34</version>
</dependency>
application.properties конфигурациясы учурда төмөнкүдөй:
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

Объекттерди жана Колдонмо логикасын түзүү

Объекттер

entitiesКелгиле, маалымат базасы an objectилерин жайгаштырган пакетти түзөлү . Колдонуучу Spring Security конфигурациясына керектелүүчү Userинтерфейсти ишке ашырган класс тарабынан сүрөттөлөт . UserDetailsКолдонуучунун идентификатору, колдонуучу аты (бул электрондук почта), сырсөз, аты, ролу, аракет желеги, Google аккаунтунун аталышы жана электрондук почтасы ( googleNameжана 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
}
Колдонуучунун ролдору Spring Securityде кирүү мүмкүнчүлүгүн жөнгө салуу үчүн колдонулат. Биздин колдонмо бир гана ролду колдонот:
public enum Role implements GrantedAuthority
{
  USER;

  @Override
  public String getAuthority()
  {
     return name();
  }
}
Келгиле, идентификатор, нота аталышы, жазуунун негизги бөлүгү жана ал таандык болгон колдонуучунун идентификатору менен нота классын түзөлү:
@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()
}

Репозиторийлер

Объекттерди маалымат базасына сактоо үчүн, биз үчүн бардык ыплас иштерди жасай турган репозиторийлер керек. Пакет түзөлү , анда интерфейстен мураска калган reposинтерфейстерди түзөбүз . UserRepoNoteRepoJpaRepository<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);
}

Контроллерлор

Биздин эскертүүлөр кызматы төмөнкү барактарды камтыйт:
  • Үй;
  • Каттоо;
  • Кирүү;
  • Колдонуучунун эскертүүлөрүнүн тизмеси.
Эскертүүлөрдүн тизмесине ыйгарым укуктуу колдонуучу гана кире алышы керек. Калган барактар ​​жалпыга ачык. Келгиле, негизги беттин кадимки алуу картасын камтыган controllersклассты камтыган пакетти түзөлү. IndexControllerКласс RegistrationControllerколдонуучуну каттоо үчүн жооптуу. Пост-карталоо формадан маалыматтарды алып, колдонуучуну маалымат базасына сактайт жана кирүү барагына багыттайт. PasswordEncoderкийинчерээк баяндалат. Ал сырсөздөрдү шифрлөө үчүн колдонулат.
@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";
  }
Эскертүүлөр тизмеси бетине жооптуу контроллер учурда жөнөкөйлөштүрүлгөн функцияларды камтыйт, ал 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";
  }
}
Кирүү бетине контроллерди жазбайбыз, анткени ал Spring Security тарабынан колдонулат. Анын ордуна, бизге атайын конфигурация керек болот. Адаттагыдай эле, келгиле, башка пакет түзүп, аны чакырып config, классты ошол жерге жайгаштыралы MvcConfig. Spring Security конфигурациясын жазганда, ал "/login" колдонгондо кайсы бетке кайрылып жатканыбызды билет.
@Configuration
public class MvcConfig implements WebMvcConfigurer
{
  public void addViewControllers(ViewControllerRegistry registry)
  {
     registry.addViewController("/login").setViewName("login");
     registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
  }
}

Барактар

Мен барактарды түзүү үчүн Mostache үлгү кыймылдаткычын колдоном . Башкасын ишке ашыра аласыз, бул маанилүү эмес. Бардык беттерде колдонулган мета маалымат үчүн meta.mustache файлы түзүлдү. Ал ошондой эле биздин долбоордун барактарын сулуураак кылуу үчүн Bootstrapди камтыйт. Барактар ​​"src/main/resources/templates" каталогунда түзүлөт. Файлдарда кеңейтүү муруту бар. HTML codeун түздөн-түз макалага жайгаштыруу аны өтө чоң кылат, андыктан бул жерде долбоордун GitHub репозиторийиндеги калыптар папкасына шилтеме .

Классикалык кирүү үчүн жазгы коопсуздукту конфигурациялоо

Spring Security колдонмону жана анын ресурстарын уруксатсыз кирүүдөн коргоого жардам берет. Биз топтомго жайгаштырган мураска SecurityConfigалынган класста кыскача жумушчу конфигурацияны түзөбүз . Аны Spring Security колдоосун иштете турган @EnableWebSecurity annotationсы жана бул класста кандайдыр бир конфигурация бар экенин көрсөткөн @Configuration annotationсы менен белгилейли. Эскертүү: автоматтык түрдө конфигурацияланган pom.xml Spring Boot негизги компонентинин 2.1.4.RELEASE versionсын камтыган, бул Коопсуздукту белгиленген жол менен ишке ашырууга тоскоол болгон. Долбоордогу чыр-чатактарды болтурбоо үчүн versionны 2.0.1.RELEASEге өзгөртүү сунушталат. WebSecurityConfigurerAdapterconfig

Негизги конфигурация SecurityConfig

Биздин конфигурация төмөнкүлөрдү аткара алат:
  1. Сырсөздөрдү шифрлөө аркылуу BCryptPasswordEncoder:

    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Bean
    PasswordEncoder passwordEncoder()
    {
      PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
      return passwordEncoder;
    }
  2. Атайын жазылган аутентификация провайдери аркылуу кирүү:

    @Autowired
    private AuthProvider authProvider;
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth)
    {
      auth.authenticationProvider(authProvider);
    }
  3. Анонимдүү колдонуучуларга үй баракчасына, каттоо жана кирүү баракчаларына кирүүгө уруксат бериңиз. Бардык башка суроо-талаптар кирген колдонуучулар тарабынан аткарылышы керек. Кирүү баракчасы катары мурда сүрөттөлгөн "/ login" ды дайындайлы. Кирүү ийгorктүү болсо, колдонуучу эскертүүлөрдүн тизмеси бар баракка өтөт, эгер ката болсо, колдонуучу кирүү бетинде кала берет. Ийгorктүү чыккандан кийин, колдонуучу башкы бетке өтөт.

    @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();
    }

Ыңгайлаштырылган колдонуучу кирүү

Өз алдынча жазылган AuthProviderколдонуучуга электрондук почта аркылуу гана эмес, колдонуучу аты менен да кирүүгө мүмкүнчүлүк берет.
@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;
  }
}
Сиз байкагандай, UserServiceпакетте жайгашкан класс колдонуучуну жүктөө үчүн жооп берет services. Биздин учурда, ал колдонуучуну талаа боюнча гана эмес username, орнотулган ишке ашыруу сыяктуу, ошондой эле колдонуучунун аты, Google аккаунтунун аты жана Google аккаунтунун электрондук почтасы боюнча издейт. Акыркы эки ыкма бизге OAuth2 аркылуу кирүүдө пайдалуу болот. Бул жерде класс кыскартылган вариантта берилет.
@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;
  }
}
Эскертүү: керектүү ыкмаларды жазууну унутпаңыз UserRepo!

Контроллорду жакшырталы

Жазгы коопсуздукту конфигурацияладык. Эми ноталарыңыздын контроллеруңузда мунун пайдасын көрүүгө убакыт келди. Эми ар бир карта кошумча Негизги параметрди кабыл алат, ал аркылуу колдонуучуну табууга аракет кылат. Эмне үчүн мен түздөн-түз классты киргизе албайм User? Анан социалдык тармактар ​​аркылуу логин жазганда колдонуучулардын түрлөрү дал келбегендиктен чыр-чатактар ​​болот. Биз алдын ала керектүү ийкемдүүлүктү камсыздайбыз. Биздин ноталардын контроллерунун codeу азыр мындай көрүнөт:
@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";
}
Эскертүү: долбоордун демейки боюнча CSRF коргоосу иштетилген , андыктан аны өзүңүз үчүн өчүрүңүз (http.csrf().disable()), же макаланын автору катары, csrf белгиси менен жашыруун талааны кошууну унутпаңыз. бардык билдирүүлөр үчүн.

Ишке киргизүү

Долбоорду ишке киргизүүгө аракет кылып жатабыз.
Келгиле, электрондук почта жана OAuth2 аркылуу жазгы коопсуздукка үзгүлтүксүз логинди киргизели, ноталар кызматынын мисалында - 1
Келгиле, электрондук почта жана OAuth2 аркылуу жазгы коопсуздукка үзгүлтүксүз логинди киргизели, ноталар кызматынын мисалында - 2
Базада жаңы колдонуучу пайда болгонун көрүп жатабыз. Сырсөз шифрленген.
Келгиле, электрондук почта жана OAuth2 аркылуу жазгы коопсуздукка үзгүлтүксүз логинди киргизели, ноталар кызматынын мисалында - 3
Келгиле, электрондук почта жана OAuth2 аркылуу жазгы коопсуздукка үзгүлтүксүз логинди киргизели, ноталар кызматынын мисалында - 4
Келгиле, электрондук почта жана OAuth2 аркылуу жазгы коопсуздукка кадимки логинди киргизели, ноталар кызматынын мисалында - 5
Келгиле, электрондук почта жана OAuth2 аркылуу жазгы коопсуздукка кадимки логинди киргизели, ноталар кызматынын мисалында - 6
Эскертүүлөр маалымат базасына сакталат.
Келгиле, электрондук почта жана OAuth2 аркылуу жазгы коопсуздукка үзгүлтүксүз логинди киргизели, ноталар кызматынын мисалында - 7
Долбоор ийгorктүү ишке ашып, иштеп жатканын көрүп жатабыз. Толук бакыт үчүн бизге социалдык тармактар ​​аркылуу кирүү мүмкүнчүлүгү гана керек. Мейли, баштайлы!

Жазгы коопсуздукта мисал катары Google аркылуу OAuth2 орнотуу

OAuth2ди ишке ашырууда мен Жаздын бул расмий окуу куралына таяндым . OAuth2ди колдоо үчүн, pom.xml файлына төмөнкү китепкананы кошуңуз:
<dependency>
  <groupId>org.springframework.security.oauth.boot</groupId>
  <artifactId>spring-security-oauth2-autoconfigure</artifactId>
  <version>2.0.0.RELEASE</version>
</dependency>
Келгиле, жазгы коопсуздук конфигурациябызды өзгөртөлү SecurityConfig. Биринчиден, @EnableOAuth2Client annotationсын кошолу. Ал автоматтык түрдө сиз социалдык тармактар ​​аркылуу кирүү үчүн керектүү нерселерди чыгарат.

Чыпка конфигурациясын жана application.properties

Келгиле, коопсуздук конфигурациябызда колдонуу үчүн OAuth2ClientContext сайып көрөлү.
@Autowired
private OAuth2ClientContext oAuth2ClientContext;
OAuth2ClientContext колдонуучунун социалдык кирүү өтүнүчүн ырастаган чыпка түзүүдө колдонулат. Чыпка @EnableOAuth2Client annotationсынын аркасында жеткorктүү. Биз эмне кылышыбыз керек , негизги Spring Security чыпкасынан мурун , аны туура тартипте чакыруу . Ошондо гана биз OAuth2 менен кирүү процессинде багыттоолорду кармай алабыз. Бул үчүн биз FilterRegistrationBeanфильтрибиздин артыкчылыктуулугун -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;
}
Ошондой эле конфигурациялоо (HttpSecurity http) функциясына жаңы чыпка кошуу керек:
http.addFilterBefore(ssoFilter(), UsernamePasswordAuthenticationFilter.class);
Фильтр, ошондой эле кардар Google аркылуу катталганын бorши керек. @ConfigurationProperties annotationсы application.properties ичинде кайсы конфигурация касиеттерин издөө керектигин аныктайт.
@Bean
@ConfigurationProperties("google.client")
public AuthorizationCodeResourceDetails google()
{
  return new AuthorizationCodeResourceDetails();
}
Аутентификацияны аяктоо үчүн сиз Google колдонуучу маалыматынын акыркы чекитин көрсөтүшүңүз керек:
@Bean
@ConfigurationProperties("google.resource")
public ResourceServerProperties googleResource()
{
  return new ResourceServerProperties();
}
Колдонмобузду Google Булут Платформасында каттагандан кийин , биз 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

Google Cloud Platform менен тиркемени каттоонун негизги учурлары

Жол: API'лер жана Кызматтар -> Каттоо маалыматтары OAuth мүмкүндүк алуу өтүнүчүнүн терезеси:
  • Колдонмонун аталышы: Жазгы кирүү формасы жана OAuth2 окуу куралы
  • Колдоо электрондук почта дареги: сиздин электрондук почта
  • Google API чөйрөсү: электрондук почта, профиль, openid
  • Ыйгарым укуктуу домендер: me.org
  • Тиркеменин негизги бетине шилтеме: http://me.org:8080
  • Колдонмонун купуялык саясатына шилтеме: http://me.org:8080
  • Колдонмо шарттарына шилтеме: http://me.org:8080
Каттоо маалыматтары:
  • Түрү: Веб колдонмо
  • Аталышы: Жазгы кирүү формасы жана OAuth2 окуу куралы
  • Уруксат берилген JavaScript булактары: http://me.org, http://me.org:8080
  • Уруксат берилген багыттоо URI'лери: http://me.org:8080/login, http://me.org:8080/login/google
Эскертүү: Google localhost:8080 дареги менен иштөөнү каалабагандыктан, аягында “127.0.0.1 me.org” сабын же C:\Windows\System32\drivers\etc\hosts файлына окшош нерсени кошуңуз. негизги нерсе домен классикалык түрдө болуп саналат.

CustomUserInfoTokenServices

Чыпка функциясынын сүрөттөмөсүндө Custom деген сөздү байкадыңызбы? Класс CustomUserInfoTokenServices. Ооба, биз блэкджек жана колдонуучуну маалымат базасында сактоо мүмкүнчүлүгү менен өзүбүздүн классыбызды түзөбүз! UserInfoTokenServicesIntelliJ IDEAдагы Ctrl-N клавиатура жарлыгын колдонуп, демейки кантип ишке ашырылып жатканын таап, көрө аласыз . Келгиле, анын codeун жаңы түзүлгөн класска көчүрөлү CustomUserInfoTokenServices. Анын көбү өзгөрүүсүз калтырылышы мүмкүн. Функциялардын логикасын өзгөртүүдөн мурун класстын жеке талаалары катары UserRepoкошолу PasswordEncoder. Келгиле, алар үчүн орнотуучуларды түзөлү. SecurityConfig классына @Autowired UserRepo userRepo кошолу. Чыпкаларды түзүү ыкмасындагы катаны көрсөткөн көрсөткүч кантип жоголуп жатканын карап, кубанабыз. Эмне үчүн @Autowired түздөн-түз CustomUserInfoTokenServices кызматына колдонула алган жок? Анткени бул класс көз карандылыкты кабыл алbyte, анткени анын өзү эч кандай Жазгы annotation менен белгиленбейт жана чыпка жарыяланганда анын конструктору ачык түзүлөт. Демек, Жаздын DI механизми бул тууралуу билбейт. Бул класстагы кандайдыр бир нерсеге @Autowired annotationсын жазсак, колдонулганда NullPointerException алабыз. Бирок ачык орнотуучулар аркылуу баары абдан жакшы иштейт. Керектүү компоненттерди ишке ашыргандан кийин, кызыгуунун негизги an objectиси loadAuthentication функциясы болуп калат, мында колдонуучу жөнүндө маалымат менен Map<String, Object> чыгарылат. Дал ушул долбоордо мен социалдык тармак аркылуу кирген колдонуучуну маалымат базасына сактоону ишке ашырдым. Биз Google каттоо эсебин OAuth2 провайдери катары колдонуп жаткандыктан, картада Google үчүн мүнөздүү "кошумча" талаа камтылганын текшеребиз. Эгерде ал бар болсо, бул колдонуучу тууралуу маалымат туура кабыл алынганын билдирет. Биз жаңы колдонуучуну түзүп, аны маалымат базасына сактайбыз.
@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);
}
Бир нече провайдерлерди колдонгондо, сиз бир CustomUserInfoTokenServices ичинде ар кандай опцияларды белгилеп, чыпкалоо декларациясынын методунда окшош кызматтардын ар кандай класстарын каттай аласыз. Эми Колдонуучу жана OAuth2Authentication экөө тең Негизги катары иштей алышат. Биз UserServiceде колдонуучунун Google маалыматтары аркылуу жүктөлүшүн алдын ала эске алгандыктан, тиркеме эки типтеги колдонуучулар үчүн да иштейт. Биз долбоордун башкы бет контроллерин өзгөртүп, ал OAuth2 аркылуу кирген колдонуучуларды эскертүүлөр барагына багыттайбыз.
@GetMapping("/")
public String index(Principal principal)
{
  if(principal != null)
  {
     return "redirect:/notes";
  }
  return "index";
}

Долбоордун акыркы башталышы

Кичинекей косметикалык өзгөрүүлөрдөн жана чыгуу баскычын кошкондон кийин, биз долбоордун акыркы ишке киргизебиз.
Келгиле, электрондук почта жана OAuth2 аркылуу жазгы коопсуздукка кадимки логинди киргизели, ноталар кызматынын мисалында - 8
Келгиле, электрондук почта жана OAuth2 аркылуу жазгы коопсуздукка үзгүлтүксүз логинди киргизели, ноталар кызматынын мисалында - 9
Келгиле, электрондук почта жана OAuth2 аркылуу жазгы коопсуздукка кадимки логинди киргизели, ноталар кызматынын мисалын колдонуу менен - ​​10
Келгиле, электрондук почта жана OAuth2 аркылуу жазгы коопсуздукка үзгүлтүксүз логинди киргизели, ноталар кызматынын мисалында - 11
Келгиле, электрондук почта жана OAuth2 аркылуу жазгы коопсуздукка үзгүлтүксүз логинди киргизели, ноталар кызматынын мисалында - 12
Келгиле, электрондук почта жана OAuth2 аркылуу жазгы коопсуздукка үзгүлтүксүз логинди киргизели, ноталар кызматынын мисалында - 13
Келгиле, электрондук почта жана OAuth2 аркылуу жазгы коопсуздукка үзгүлтүксүз логинди киргизели, ноталар кызматынын мисалында - 14
Келгиле, электрондук почта жана OAuth2 аркылуу жазгы коопсуздукка үзгүлтүксүз логинди киргизели, ноталар кызматынын мисалында - 15
Колдонуучу кадимки форма аркылуу да, Google аккаунту аркылуу да ийгorктүү кирет. Бул биз каалаган нерсе! Бул макалада веб-тиркеме түзүү, аны Spring Security менен камсыздоо жана ар кандай кирүү ыкмаларын айкалыштыруу боюнча айрым ойлорду чечти деп үмүттөнөм. Толук долбоордун codeу менен сиз жасай аласыз
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION