1. 程式人生 > 其它 >【ybtoj】銀河英雄傳說

【ybtoj】銀河英雄傳說

認證業務邏輯

  • 建立專案,引入所需依賴,新建實體類,資料庫建立使用者表,yml中配置資料庫連線
  • 編寫mapper
  • 編寫service
@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private UsersMapper usersMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //呼叫usersMapper方法,根據使用者名稱查詢資料庫
        QueryWrapper<Users> wrapper = new QueryWrapper();
        wrapper.eq("username",username);
        Users users = usersMapper.selectOne(wrapper);
        if(users == null) {    // 資料庫沒有使用者名稱,認證失敗
            throw  new UsernameNotFoundException("使用者名稱不存在!");
        }
        // 賦予許可權
        List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_sale");
        // 返回從資料庫查詢到使用者名稱和密碼
        return new User(users.getUsername(), new BCryptPasswordEncoder().encode(users.getPassword()),auths);
    }
}

  • 前端傳送請求到控制器,預設所有的請求訪問時都是需要先認證的,進入認證頁面,輸入使用者名稱和密碼;這時會進入service層,在業務層呼叫持久層的物件查詢使用者的使用者名稱和密碼,二者相比較,相同則認證通過

授權業務邏輯

  • 編寫配置類
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(password());
    }
    @Bean
    PasswordEncoder password() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 退出登入:退出的url、退出後跳轉的url
        http.logout().logoutUrl("/logout").logoutSuccessUrl("/test/hello").permitAll();

        // 配置沒有訪問許可權時跳轉到自定義頁面
        http.exceptionHandling().accessDeniedPage("/unauth.html");

        http.formLogin()   
            .loginPage("/on.html")  // 自定義登入頁面
            .loginProcessingUrl("/user/login")   // 登入的url
            .defaultSuccessUrl("/success.html").permitAll()  //登入成功之後,跳轉路徑
            .failureUrl("/unauth.html") // 登入失敗跳轉的url
            .and().authorizeRequests()
                .antMatchers("/","/test/hello","/user/login").permitAll() // 不需要認證
                // 當前登入使用者,只有具有admins許可權才可以訪問這個路徑
                .antMatchers("/test/index").hasAuthority("admins")
                // 其他需要認證
                .anyRequest().authenticated()
                // 自動登入的有效時間 秒
                .and().rememberMe().tokenRepository(persistentTokenRepository())
                .tokenValiditySeconds(60)
                .userDetailsService(userDetailsService);
    }
}

  • 通常註冊和登入頁面是不需要認證就能訪問的,首先訪問註冊頁面,註冊時將密碼加密、加鹽,之後將使用者名稱、密文密碼、鹽值存入資料庫
  • 訪問登入頁面,輸入使用者名稱和密碼,進入service層,根據使用者名稱查詢到使用者資訊,對剛才輸入的密碼使用註冊時的加密方式,二者再比較,相同則認證成功,將該物件返回給配置類
  • 可以在業務層中查詢出使用者的許可權,再賦予當前使用者;或者在配置類中使用方法賦予使用者許可權;或者使用註解給方法授權,只有擁有許可權的使用者才能訪問
  • 控制層 -> 業務層 -> 配置類