JavaRush /جاوا بلاگ /Random-SD /اچو ته متعارف ڪرايون باقاعده لاگ ان اي ميل ذريعي ۽ OAuth2...

اچو ته متعارف ڪرايون باقاعده لاگ ان اي ميل ذريعي ۽ OAuth2 ذريعي اسپرنگ سيڪيورٽي ڏانهن نوٽس سروس جو مثال استعمال ڪندي

گروپ ۾ شايع ٿيل
منهنجي ايپليڪيشن لکڻ دوران، مون کي واضح مضمونن جي کوٽ جو سامنا ٿيو ته ڪيئن حاصل ڪجي صارف کي اي ميل ۽ سماجي نيٽ ورڪن ذريعي رجسٽر ڪرڻ لاءِ. کلاسک لاگ ان فارم قائم ڪرڻ تي سٺا سبق هئا. OAuth2 تي سٺا سبق هئا . ٻن طريقن کي ڪيئن گڏ ڪرڻ تي مجرمانه طور تي ٿوري معلومات هئي. ڳولا جي عمل دوران، اسان هڪ قابل عمل حل سان گڏ اچڻ جي قابل هئا. اهو حتمي سچ هجڻ جي دعويٰ نٿو ڪري، پر اهو پنهنجو ڪم پورو ڪري ٿو. هن آرٽيڪل ۾ آئون ڏيکاريندس ته هڪ نوٽ اسٽوريج سروس کي ڪيئن لاڳو ڪجي ساڳئي اسپرنگ سيڪيورٽي ترتيب سان شروع کان. اچو ته نوٽس سروس جو مثال استعمال ڪندي اي ميل ۽ OAuth2 ذريعي اسپرنگ سيڪيورٽي ۾ باقاعده لاگ ان متعارف ڪرايون - 1نوٽ: اهو سٺو آهي ته پڙهندڙ گهٽ ۾ گهٽ بهار جي باري ۾ ڪجهه سبقن مان گذري چڪو آهي، ڇو ته ذخيرن، ڪنٽرولرز وغيره جي تفصيلي وضاحتن کان سواء، صرف اسپرنگ سيڪيورٽي تي ڌيان ڏنو ويندو. ٻي صورت ۾، اڳ ۾ ئي هڪ وڏو مضمون نڪري ويندو. وڏو ٿيڻ. مواد
  1. پروجيڪٽ ٺاهڻ
  2. ايجاد ۽ ايپليڪيشن منطق
    1. ادارا
    2. مخزن
    3. ڪنٽرولرز
    4. صفحا
  3. ڪلاسيڪل لاگ ان لاءِ اسپرنگ سيڪيورٽي کي ترتيب ڏيڻ
    1. بنيادي ٺاھ جوڙ SecurityConfig
    2. ڪسٽم استعمال ڪندڙ لاگ ان
    3. اچو ته ڪنٽرولر کي بهتر بڻايون
    4. لانچ
  4. OAuth2 ترتيب ڏيڻ گوگل کي استعمال ڪندي مثال طور اسپرنگ سيڪيورٽي ۾
    1. فلٽر ٺاھ جوڙ ۽ application.properties
    2. گوگل ڪلائوڊ پليٽ فارم سان ايپليڪيشن رجسٽر ڪرڻ جا نمايان
    3. CustomUserInfoTokenServices
  5. منصوبي جي آخري لانچ

پروجيڪٽ ٺاهڻ

اسان وڃو start.spring.io ۽ پروجيڪٽ جو بنياد ٺاهيو:
  • ويب - بلٽ ان ٽامڪٽ تي هڪ ايپليڪيشن لانچ ڪرڻ، يو آر ايل ميپنگ ۽ ان وانگر؛
  • JPA - ڊيٽابيس ڪنيڪشن؛
  • Mustache هڪ ٽيمپليٽ انجڻ آهي جيڪو ويب صفحا ٺاهڻ لاءِ استعمال ٿيندو آهي.
  • سيڪيورٽي - ايپليڪيشن تحفظ. اھو اھو آھي جنھن لاء ھي مضمون ٺاھيو ويو آھي.
نتيجو آرڪائيو ڊائون لوڊ ڪريو ۽ ان کي فولڊر ۾ ان کي پيڪ ڪريو جيڪو توهان کي گهربل آهي. اسان ان کي IDE ۾ لانچ ڪيو. توھان پنھنجي صوابديد تي ڊيٽابيس چونڊي سگھو ٿا. مان MySQL کي پراجيڪٽ لاءِ ڊيٽابيس طور استعمال ڪريان ٿو، ان ڪري مان هيٺ ڏنل انحصار شامل ڪريان ٿو pom.xml فائل ۾ <dependencies> block:
<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جنھن ۾ اسين ڊيٽابيس جي ادارن کي رکون ٿا. استعمال ڪندڙ کي هڪ طبقي طرفان بيان ڪيو ويندو Userجيڪو انٽرفيس کي لاڳو ڪري ٿو UserDetails، جيڪو بهار جي حفاظت جي ترتيب لاءِ گهربل هوندو. استعمال ڪندڙ وٽ هڪ id، يوزرنيم (هي اي ميل آهي)، پاسورڊ، نالو، ڪردار، سرگرمي پرچم، گوگل کاتي جو نالو ۽ اي ميل هوندو ( 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
}
استعمال ڪندڙ ڪردار اسپرنگ سيڪيورٽي ۾ رسائي کي منظم ڪرڻ لاءِ استعمال ڪيا ويندا آهن. اسان جي ايپليڪيشن صرف هڪ ڪردار استعمال ڪندي:
public enum Role implements GrantedAuthority
{
  USER;

  @Override
  public String getAuthority()
  {
     return name();
  }
}
اچو ته id، نوٽ عنوان، نوٽ باڊي ۽ صارف جي سڃاڻپ سان هڪ نوٽ ڪلاس ٺاهيون جنهن سان اهو تعلق رکي ٿو:
@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";
  }
نوٽس لسٽ واري صفحي لاءِ ذميوار ڪنٽرولر هن وقت آسان ڪارڪردگيءَ تي مشتمل آهي، جيڪا اسپرنگ سيڪيورٽي جي لاڳو ٿيڻ کان پوءِ وڌيڪ پيچيده ٿي ويندي.
@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";
  }
}
اسان لاگ ان صفحي لاءِ ڪنٽرولر نه لکنداسين ڇاڪاڻ ته اهو اسپرنگ سيڪيورٽي پاران استعمال ڪيو ويندو آهي. ان جي بدران، اسان کي هڪ خاص ترتيب جي ضرورت پوندي. هميشه وانگر، اچو ته هڪ ٻيو پيڪيج ٺاهيو، ان کي ڪال ڪريو config، ۽ ڪلاس کي اتي رکو MvcConfig. جڏهن اسان اسپرنگ سيڪيورٽي ڪنفيگريشن لکندا آهيون، اهو معلوم ٿيندو ته اسان ڪهڙي صفحي ڏانهن اشارو ڪري رهيا آهيون جڏهن اسان "/ لاگ ان" استعمال ڪندا آهيون.
@Configuration
public class MvcConfig implements WebMvcConfigurer
{
  public void addViewControllers(ViewControllerRegistry registry)
  {
     registry.addViewController("/login").setViewName("login");
     registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
  }
}

صفحا

مان صفحا ٺاهڻ لاءِ Mustache ٽيمپليٽ انجڻ استعمال ڪريان ٿو . توهان هڪ ٻئي کي لاڳو ڪري سگهو ٿا، اهو مسئلو ناهي. ميٽا معلومات لاءِ هڪ meta.mustache فائل ٺاهي وئي آهي جيڪا سڀني صفحن تي استعمال ٿئي ٿي. ان ۾ اسان جي پروجيڪٽ جي صفحن کي خوبصورت ڏسڻ لاءِ بوٽ اسٽريپ پڻ شامل آهي. صفحا ٺاهيا ويندا آهن "src/main/resources/templates" ڊاريڪٽري ۾. فائلن کي ايڪسٽينشن مُڇن آھي. آرٽيڪل ۾ سڌو HTML ڪوڊ رکڻ سان اهو تمام وڏو ٿيندو، تنهنڪري هتي هڪ لنڪ آهي ٽيمپليٽ فولڊر جي پروجيڪٽ جي GitHub مخزن ۾ .

ڪلاسيڪل لاگ ان لاءِ اسپرنگ سيڪيورٽي کي ترتيب ڏيڻ

اسپرنگ سيڪيورٽي اسان کي ايپليڪيشن ۽ ان جي وسيلن کي غير مجاز رسائي کان بچائڻ ۾ مدد ڪري ٿي. SecurityConfigاسان ورثي ۾ ورثي واري طبقي ۾ هڪ جامع ڪم ڪندڙ ترتيب ٺاهينداسين WebSecurityConfigurerAdapter، جنهن کي اسان پيڪيج ۾ رکنداسين config. اچو ته ان کي @EnableWebSecurity تشريح سان نشان لڳايو، جيڪو بهار جي سيڪيورٽي سپورٽ کي فعال ڪندو، ۽ @Configuration تشريح، جنهن مان ظاهر ٿئي ٿو ته هي ڪلاس ڪجهه ترتيبن تي مشتمل آهي. نوٽ: خود بخود ترتيب ڏنل pom.xml ۾ اسپرنگ بوٽ جي پريننٽ جزو 2.1.4.RELEASE جو ورجن موجود آهي، جنهن سيڪيورٽي کي قائم ڪيل طريقي سان لاڳو ٿيڻ کان روڪيو. پروجيڪٽ ۾ تڪرار کان بچڻ لاء، اهو نسخو 2.0.1.RELEASE ۾ تبديل ڪرڻ جي سفارش ڪئي وئي آهي.

بنيادي ٺاھ جوڙ 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. گمنام صارفين کي هوم پيج، رجسٽريشن ۽ لاگ ان صفحن تائين رسائي جي اجازت ڏيو. ٻين سڀني درخواستن کي لازمي طور تي لاگ ان ٿيل استعمال ڪندڙن طرفان ڪيو وڃي. اچو ته اڳ ۾ بيان ڪيل "/ لاگ ان" کي لاگ ان صفحي جي طور تي تفويض ڪريو. جيڪڏهن لاگ ان ڪامياب آهي، صارف کي نوٽس جي فهرست سان هڪ صفحي تي ورتو ويندو؛ جيڪڏهن ڪو غلطي آهي، صارف لاگ ان صفحي تي رهندو. ڪامياب نڪرڻ تي، صارف کي مکيه صفحي تي ورتو ويندو.

    @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، جهڙوڪ بلٽ ان پليپشن، پر پڻ صارف جو نالو، گوگل کاتي جو نالو ۽ گوگل اڪائونٽ اي ميل. آخري ٻه طريقا اسان لاءِ ڪارآمد هوندا جڏهن لاگ ان کي 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؟ پوءِ صارف جي قسمن جي بي ميلاپ جي ڪري تڪرار ٿيندو جڏهن اسان سوشل نيٽ ورڪ ذريعي لاگ ان لکندا آهيون. اسان اڳ ۾ ضروري لچڪ فراهم ڪندا آهيون. اسان جي نوٽس ڪنٽرولر ڪوڊ هاڻي هن طرح نظر اچي ٿو:
@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
اسان ڏسون ٿا ته پروجيڪٽ ڪاميابيءَ سان شروع ۽ هلندڙ آهي. مڪمل خوشي لاء، اسان کي صرف سماجي نيٽ ورڪ ذريعي لاگ ان ڪرڻ جي صلاحيت جي ضرورت آهي. خير، اچو ته شروع ڪريون!

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 تشريح. اهو خودڪار طريقي سان ڇڪيندو جيڪو توهان کي سماجي نيٽ ورڪن ذريعي لاگ ان ٿيڻ جي ضرورت آهي.

فلٽر ٺاھ جوڙ ۽ application.properties

اچو ته انجيڪٽ ڪريون OAuth2ClientContext اسان جي حفاظتي ترتيب ۾ استعمال ڪرڻ لاءِ.
@Autowired
private OAuth2ClientContext oAuth2ClientContext;
OAuth2ClientContext استعمال ڪيو ويندو آهي جڏهن هڪ فلٽر ٺاهيو جيڪو صارف جي سماجي لاگ ان درخواست جي تصديق ڪري ٿو. فلٽر دستياب آهي مهرباني ڪري @EnableOAuth2Client تشريح. اسان سڀني کي ڪرڻ جي ضرورت آهي ان کي صحيح ترتيب ۾ سڏڻ کان اڳ، مکيه اسپرنگ سيڪيورٽي فلٽر کان اڳ . صرف پوءِ اسان لاگ ان عمل دوران ريڊائريڪٽس کي پڪڙڻ جي قابل ٿي وينداسين 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;
}
توھان کي پڻ ھڪڙو نئون فلٽر شامل ڪرڻ جي ضرورت آھي configure (HttpSecurity http) فنڪشن:
http.addFilterBefore(ssoFilter(), UsernamePasswordAuthenticationFilter.class);
فلٽر کي پڻ ڄاڻڻ جي ضرورت آهي ته ڪلائنٽ گوگل ذريعي رجسٽر ٿيل آهي. @ConfigurationProperties تشريح بيان ڪري ٿي ته ڪھڙي ترتيب واري ملڪيت کي ڏسڻ لاءِ application.properties ۾.
@Bean
@ConfigurationProperties("google.client")
public AuthorizationCodeResourceDetails google()
{
  return new AuthorizationCodeResourceDetails();
}
تصديق مڪمل ڪرڻ لاءِ، توهان کي وضاحت ڪرڻ جي ضرورت آهي گوگل صارف معلومات جي آخري پوائنٽ:
@Bean
@ConfigurationProperties("google.resource")
public ResourceServerProperties googleResource()
{
  return new ResourceServerProperties();
}
گوگل ڪلائوڊ پليٽ فارم ۾ اسان جي ايپليڪيشن کي رجسٽر ڪرڻ کان پوءِ ، اسان 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

گوگل ڪلائوڊ پليٽ فارم سان ايپليڪيشن رجسٽر ڪرڻ جا نمايان

رستو: APIs ۽ خدمتون -> سندون OAuth رسائي جي درخواست ونڊو:
  • ايپليڪيشن جو نالو: اسپرنگ لاگ ان فارم ۽ OAuth2 سبق
  • سپورٽ اي ميل پتو: توهان جو اي ميل
  • گوگل API لاءِ اسڪوپ: اي ميل، پروفائل، اوپن ايڊ
  • بااختيار ڊومينز: me.org
  • ايپليڪيشن جي مکيه صفحي ڏانهن لنڪ: http://me.org:8080
  • ايپ جي رازداري پاليسي سان لنڪ: http://me.org:8080
  • ايپليڪيشن جي استعمال جي شرطن سان لنڪ: http://me.org:8080
سندون:
  • قسم: ويب ايپليڪيشن
  • عنوان: اسپرنگ لاگ ان فارم ۽ OAuth2 سبق
  • اجازت ڏنل جاوا اسڪرپٽ ذريعن: http://me.org، http://me.org:8080
  • اجازت ڏنل URIs: http://me.org:8080/login, http://me.org:8080/login/google
نوٽ: جيئن ته گوگل ايڊريس سان ڪم ڪرڻ نٿو چاهي localhost:8080، ان لائن شامل ڪريو “127.0.0.1 me.org” يا فائل C:\Windows\System32\drivers\etc\hosts آخر ۾. بنيادي شيء اها آهي ته ڊومين هڪ کلاسک شڪل ۾ آهي.

CustomUserInfoTokenServices

ڇا توھان محسوس ڪيو لفظ ڪسٽم فلٽر فنڪشن جي وضاحت ۾؟ ڪلاس CustomUserInfoTokenServices. ها، اسان بليڪ جيڪ ۽ ڊيٽابيس ۾ صارف کي محفوظ ڪرڻ جي صلاحيت سان اسان جو پنهنجو ڪلاس ٺاهينداسين! IntelliJ IDEA ۾ Ctrl-N ڪيبورڊ شارٽ ڪٽ استعمال ڪندي، توھان ڳولي سگھوٿا ۽ ڏسي سگھوٿا ته UserInfoTokenServicesڊفالٽ ڪيئن لاڳو ٿئي ٿو. اچو ته ان جو ڪوڊ ڪاپي ڪري نئين ٺهيل ڪلاس ۾ CustomUserInfoTokenServices. گهڻو ڪري ان کي بغير تبديل ڪري سگهجي ٿو. افعال جي منطق کي تبديل ڪرڻ کان اڳ، اچو ته شامل ڪريون UserRepo۽ ڪلاس جي خانگي شعبن جي طور تي PasswordEncoder. اچو ته انهن لاء سيٽرز ٺاهي. اچو ته شامل ڪريون @Autowired UserRepo userRepo کي SecurityConfig ڪلاس ۾. اسان ڏسون ٿا ته فلٽر ٺاهڻ واري طريقي ۾ غلطي ڏانهن اشارو ڪيئن غائب ٿي وڃي ٿو، ۽ اسان خوش ٿيو. ڇو نه ٿي سگهيو @Autowired سڌو سنئون CustomUserInfoTokenServices تي لاڳو ڪيو وڃي؟ ڇاڪاڻ ته هي طبقو انحصار نه کڻندو، ڇاڪاڻ ته اهو پاڻ کي ڪنهن به بهار جي تشريح سان نشان نه لڳايو ويو آهي، ۽ ان جو تعمير ڪندڙ واضح طور تي ٺاهيو ويندو آهي جڏهن فلٽر جو اعلان ڪيو ويندو آهي. ان جي مطابق، اسپرنگ جي ڊي آئي ميڪانيزم جي باري ۾ ڄاڻ نه آهي. جيڪڏهن اسان @Autowired هن ڪلاس ۾ ڪنهن به شيءِ تي تشريح ڪريون ٿا، اسان کي استعمال ٿيڻ تي NullPointerException حاصل ڪنداسين. پر واضح سيٽرن ذريعي هر شي تمام سٺو ڪم ڪري ٿو. ضروري جزن کي لاڳو ڪرڻ کان پوءِ، دلچسپي جو مکيه اعتراض loadAuthentication فنڪشن بڻجي ويندو آهي، جنهن ۾ Map<String, Object> استعمال ڪندڙ جي معلومات سان گڏ حاصل ڪيو ويندو آهي. اهو هن پروجيڪٽ ۾ هو ته مون هڪ صارف جي بچت کي لاڳو ڪيو جيڪو سوشل نيٽ ورڪ ذريعي ڊيٽابيس ۾ لاگ ان ٿيو. جيئن ته اسان گوگل کاتو استعمال ڪري رهيا آهيون هڪ OAuth2 فراهم ڪندڙ جي طور تي، اسان چيڪ ڪريون ٿا ته ڇا نقشي ۾ ”ذيلي“ فيلڊ آهي جيڪا گوگل لاءِ عام آهي. جيڪڏهن اهو موجود آهي، ان جو مطلب آهي ته صارف بابت معلومات صحيح طور تي حاصل ڪئي وئي هئي. اسان هڪ نئون صارف ٺاهيو ۽ ان کي ڊيٽابيس ۾ محفوظ ڪيو.
@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 پرنسپل طور ڪم ڪري سگھن ٿا. جيئن ته اسان صارف جي خدمت ۾ گوگل ڊيٽا ذريعي صارف جي لوڊ ٿيڻ کي اڳ ۾ ئي حساب ۾ ورتو، ايپليڪيشن ٻنهي قسمن جي استعمال ڪندڙن لاءِ ڪم ڪندي. اسان پروجيڪٽ جي مکيه صفحي جي ڪنٽرولر کي تبديل ڪريون ٿا ته جيئن اهو 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
صارف ڪاميابيءَ سان لاگ ان ٿئي ٿو باقاعدي فارم ۽ گوگل اڪائونٽ ذريعي. اهو ئي آهي جيڪو اسان چاهيون ٿا! مون کي اميد آهي ته هي آرٽيڪل ويب ايپليڪيشن ٺاهڻ، ان کي اسپرنگ سيڪيورٽي سان محفوظ ڪرڻ، ۽ مختلف لاگ ان طريقن کي گڏ ڪرڻ بابت ڪجهه نقطا صاف ڪري چڪو آهي. مڪمل پروجيڪٽ ڪوڊ سان توهان ڪري سگهو ٿا
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION