Spring Security 自定義AuthenticationProvider認證類


Spring Security中進行身份驗證的是AuthenticationManager接口,ProviderManager是它的一個默認實現,但它並不用來處理身份認證,而是委托給配置好的AuthenticationProvider,每個AuthenticationProvider會輪流檢查身份認證。

具體流程可參考Spring Security認證流程
此次記錄在Spring Security 連接數據庫實現認證的基礎上增加。

自定義AuthenticationProvider:

package cn.sivan.provider;

import cn.sivan.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;


@Component
public class LoginAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private UserService userService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        //用戶名 密碼
        String username = authentication.getName();
        String password = (String) authentication.getCredentials();

        //通過用戶名獲取用戶信息
        UserDetails userDetails = userService.loadUserByUsername(username);

        if (userDetails == null) {
            throw new UsernameNotFoundException("用戶不存在!");
        }

        if (!passwordEncoder.matches(password, userDetails.getPassword())) {
            throw new BadCredentialsException("密碼不正確!");
        }


        return new UsernamePasswordAuthenticationToken(username, password, userDetails.getAuthorities());
    }

    /**
     * AuthenticationManager 本身不包含認證邏輯,其核心是用來管理所有的 AuthenticationProvider,通過交由合適的 AuthenticationProvider 來實現認證。
     * ProviderManager 是AuthenticationProvider的實現類
     * AuthenticationManager獲取所有AuthenticationProvider的實現
     * 通過該方法判斷是否支持當前方式的認證
     * 這里支持驗證UsernamePasswordAuthenticationToken
     * @param authentication
     * @return
     */
    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}

SpringSecurity配置:

package cn.sivan.config;

import cn.sivan.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationProvider;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@EnableWebSecurity
public class SpringSecurity extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    @Autowired
    private AuthenticationProvider loginValidateAuthenticationProvider;

    @Autowired
    private PasswordEncoder passwordEncoder;


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        //指定userDetailsService
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder);

        //注冊自定義認證
        auth.authenticationProvider(loginValidateAuthenticationProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/favicon.ico").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login/user")
                .loginProcessingUrl("/login")
                .defaultSuccessUrl("/")
                .failureUrl("/login/failure")
                .permitAll()
                .and()
                .logout()
                .logoutSuccessUrl("/login/user")
                .logoutUrl("/logout")
                .invalidateHttpSession(true)
                .permitAll()
                .and()
                .csrf()
                .disable();
    }

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM