JavaRush /جاوا بلاگ /Random-UR /آئیے نوٹ سروس کی مثال کا استعمال کرتے ہوئے ای میل اور OAu...

آئیے نوٹ سروس کی مثال کا استعمال کرتے ہوئے ای میل اور 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 - ڈیٹا بیس کنکشن؛
  • مونچھیں ایک ٹیمپلیٹ انجن ہے جو ویب صفحات بنانے کے لیے استعمال ہوتا ہے۔
  • سیکورٹی - درخواست کی حفاظت. یہ مضمون اسی کے لیے بنایا گیا ہے۔
نتیجہ آرکائیو ڈاؤن لوڈ کریں اور اسے اپنے مطلوبہ فولڈر میں کھولیں۔ ہم اسے IDE میں لانچ کرتے ہیں۔ آپ اپنی صوابدید پر ڈیٹا بیس کا انتخاب کر سکتے ہیں۔ میں پروجیکٹ کے لیے MySQL کو ڈیٹا بیس کے طور پر استعمال کرتا ہوں، اس لیے میں <dependencies> بلاک میں 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جس میں ہم ڈیٹابیس اداروں کو رکھیں گے۔ صارف کو ایک کلاس کے ذریعہ بیان کیا جائے گا Userجو انٹرفیس کو لاگو کرتا ہے UserDetails، جس کی بہار سیکورٹی کی ترتیب کے لیے ضرورت ہوگی۔ صارف کے پاس ایک آئی ڈی، صارف نام (یہ ای میل ہے)، پاس ورڈ، نام، کردار، سرگرمی کا جھنڈا، گوگل اکاؤنٹ کا نام اور ای میل ( 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();
  }
}
آئیے آئی ڈی، نوٹ ٹائٹل، نوٹ باڈی اور اس صارف کی شناخت کے ساتھ ایک نوٹ کلاس بنائیں جس سے یہ تعلق رکھتا ہے:
@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۔ جب ہم اسپرنگ سیکیورٹی کنفیگریشن لکھتے ہیں، تو یہ پتہ چل جائے گا کہ جب ہم "/login" استعمال کرتے ہیں تو ہم کس صفحے کا حوالہ دے رہے ہیں۔
@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 میں Spring Boot کے بنیادی جزو 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، جیسے بلٹ ان نفاذ، بلکہ صارف کے نام، 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؟ اس کے بعد جب ہم سوشل نیٹ ورک کے ذریعے لاگ ان لکھیں گے تو صارف کی اقسام میں مماثلت نہ ہونے کی وجہ سے تنازعہ پیدا ہوگا۔ ہم پہلے سے ضروری لچک فراہم کرتے ہیں۔ ہمارے نوٹ کنٹرولر کوڈ اب اس طرح لگتا ہے:
@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 کو لاگو کرتے وقت، میں نے Spring کے اس آفیشل ٹیوٹوریل پر انحصار کیا ۔ 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;
}
آپ کو کنفیگر(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();
}
Google Cloud Platform میں اپنی درخواست رجسٹر کرنے کے بعد ، ہم 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> کو صارف کے بارے میں معلومات کے ساتھ بازیافت کیا جاتا ہے۔ اس پروجیکٹ میں میں نے سوشل نیٹ ورک کے ذریعے ڈیٹا بیس میں لاگ ان ہونے والے صارف کی بچت کو لاگو کیا۔ چونکہ ہم ایک Google اکاؤنٹ بطور 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 دونوں بطور پرنسپل کام کر سکتے ہیں۔ چونکہ ہم نے UserService میں گوگل ڈیٹا کے ذریعے صارف کی لوڈنگ کو پیشگی مدنظر رکھا تھا، اس لیے ایپلیکیشن دونوں قسم کے صارفین کے لیے کام کرے گی۔ ہم پروجیکٹ کے مرکزی صفحہ کنٹرولر میں ترمیم کرتے ہیں تاکہ یہ 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