SpringBoot中使用Security(二)

前面一篇文章說到

實現一個配置類繼承WebSecurityConfigurerAdapter,並且重寫configure(HttpSecurity http)方法。同樣可以取消掉Security登錄驗證。

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/**").permitAll();
    }

    /**
     * 配置一個userDetailsService Bean
     * 不再生成默認security.user用戶
     */
    @Bean
    @Override
    protected UserDetailsService userDetailsService() {
        return super.userDetailsService();
    }
}
這種方式取消了Security的驗證。關於登錄的一些操作就是在這做,例如用戶防重複登錄等。上面的方法是取消了Security的登錄驗證,在這可以像配置文件中配置用戶名和密碼一樣,把用戶名和密寫在這。

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

//    @Override
//    protected void configure(HttpSecurity http) throws Exception {
//        http.authorizeRequests().antMatchers("/**").permitAll();
//    }

    /**
     * 將配置中的用戶名和密碼寫在這裏。
     * 這裏可以對用戶密碼進行加密
     * 這個configure和上面的configure只存在一個更加合理,因爲上面的configure是取消驗證,這個是給驗證加規則
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .passwordEncoder(new BCryptPasswordEncoder())
                .withUser("admin")
                .password(new BCryptPasswordEncoder().encode("admin"))
                .roles("ADMIN");
    }

    /**
     * 配置一個userDerailsService Bean
     * 不再生成默認security.user用戶
     */
    protected UserDetailsService userDetailsService(){
        return super.userDetailsService();
    }
}

這樣書寫就是將用戶名和密碼寫在了後臺代碼中,實現了和配置文件中一樣的功能。但是正常情況下登錄不會是這樣簡單.

 

我們可以這樣做,在WebSecurityConfigureAdapter實現類中實現下面代碼。

將加密類型抽離出來,實現UserDetailsService接口,將兩者注入到AuthenticationManagerBuilder中:

import com.one.smile.service.impl.MyUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    //在MyUserDetailsService中實現用戶名和密碼的操作
    @Autowired
    private MyUserDetailsService userDetailsService;

    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder());
    }
}
Service層類MyUserDeailsService
UserDetaisService接口實現類
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collection;

@Service
public class MyUserDetailsService implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Collection<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority("ADMIN"));
        return new User("root", new BCryptPasswordEncoder().encode("root"), authorities);
    }
}

這裏的 User 對象是框架提供的一個用戶對象,注意包名是:org.springframework.security.core.userdetails.User,裏面的屬性中最核心的就是passwordusernameauthorities

這時候去訪問項目,要求輸入的用戶名和密碼就是你抽離出去的UserDetailsService接口的實現類中定義的用戶名和密碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章