SpringSecurity(二)自定义处理机制

版权声明:由于本人水平有限,如有错误,不吝赐教。转载请注明出处 https://blog.csdn.net/qq_41001945/article/details/86348886

一、新建类MyAuthenticationProvider继承DaoAuthenticationProvider

package com.springsecurity.handler;

import com.springsecurity.service.MyUserDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
;

import java.util.Collection;


public class MyAuthenticationProvider extends DaoAuthenticationProvider {


    @Qualifier("bCryptPasswordEncoder")
    @Autowired
    private PasswordEncoder passwordEncoder;

    private UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken;


    /**
     * 自定义验证方式
     */
    @Override
    public Authentication authenticate(Authentication authentication) {
        String username = authentication.getName();
        String password = (String) authentication.getCredentials();
        //前端传过来的明文密码password);
        String encode = passwordEncoder.encode(password);
        //加密之后的密码encode
        //调用UserDetailService的loadUserByUsername方法,来获取从数据库得到的对象信息
        UserDetails user = this.getUserDetailsService().loadUserByUsername(username);

        if(user==null){
            System.out.println("用户不存在");
            return authentication;
        }
        //加密过程在这里体现
        System.out.println("结果CustomUserDetailsService后,已经查询出来的数据库存储密码:" + user.getPassword());
        //判断前端传过来的密码与从数据库得到的是否一致。
        if (!passwordEncoder.matches(password,user.getPassword())) {
            System.out.println("密码错误!!!");
            return authentication;
        }
        //封装用户的权限,将其封装成如下类型的集合
        Collection<? extends GrantedAuthority> authorities = user.getAuthorities();
        //重新封装UsernamePasswordAuthenticationToken对象,并将其返回。
        usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(username, authentication.getCredentials(), authorities);

        usernamePasswordAuthenticationToken.setDetails(user);
        return usernamePasswordAuthenticationToken;
    }

    @Override
    public boolean supports(Class<?> arg0) {
        return true;
    }

}

二、将其加入到容器中

以前我用的1.5.18版本的boot直接在MyAuthenticationProvider中注入UserDetailService.来实现自己验证处理
这个项目用的2.1.1.RELEASE这个版本,使用上述方法,则会出异常。提示得使用Setter方法来注入UserDetailService

 @Bean("myAuthenticationProvider")
    public AuthenticationProvider getMyAuthenticationProvider(){
        MyAuthenticationProvider myAuthenticationProvider = new MyAuthenticationProvider();
        myAuthenticationProvider.setUserDetailsService(myUserDetailService);
        return myAuthenticationProvider;
    }

三、重写方法

// 重写方法,自定义用户
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(myAuthenticationProvider);
    }

完整的SpeingSecurityConfig.java代码

package com.springsecurity.config;

import com.springsecurity.handler.MyAuthenticationFailHandler;
import com.springsecurity.handler.MyAuthenticationProvider;
import com.springsecurity.handler.MyAuthenticationSuccessHandler;
import com.springsecurity.service.MyUserDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyUserDetailService myUserDetailService;

    @Qualifier("myAuthenticationProvider")
    @Autowired
    private AuthenticationProvider myAuthenticationProvider;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/","/login.html","/testlogin","/mylogin") // 不需要登录就可以访问
                .permitAll()
                .antMatchers("/user/**").hasAnyRole("USER") // 需要具有ROLE_USER角色才能访问
                .antMatchers("/admin/**").hasAnyRole("ADMIN") // 需要具有ROLE_ADMIN角色才能访问
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/testlogin") // 设置登录页面
                .loginProcessingUrl("/mylogin")
                .defaultSuccessUrl("/index") // 设置默认登录成功后跳转的页面
                .and()
                .csrf().disable()// 禁用跨站攻击  关闭csrf 防止循环定向
        ;
    }

    // 密码加密方式
    @Bean("bCryptPasswordEncoder")
    public PasswordEncoder bCryptPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }
    // 重写方法,自定义用户
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(myAuthenticationProvider);
    }

    @Bean("myAuthenticationProvider")
    public AuthenticationProvider getMyAuthenticationProvider(){
        MyAuthenticationProvider myAuthenticationProvider = new MyAuthenticationProvider();
        myAuthenticationProvider.setUserDetailsService(myUserDetailService);
        return myAuthenticationProvider;
    }

}

测试方法如上个项目。

猜你喜欢

转载自blog.csdn.net/qq_41001945/article/details/86348886
今日推荐