0
点赞
收藏
分享

微信扫一扫

SpringSecurity回顾

晴儿成长记 2022-02-25 阅读 40

目录

用户认证:

用户授权:

特点:

自定义逻辑:

 如何设置登录的用户名密码:

1、通过配置文件,老规矩:一般starterxxx都有对应springboot封装的类(xxxAutoConfiguration,找到对应的Properties就可以知道咋地配置了)

2.基于配置类对用户名密码进行设置:继承WebConfigurerAdapter并重写里面的Configure方法,将用户名密码放在内存中

数据库方式实现登录:用的mybatis



用户认证:

验证用户是否为系统中的合法主体,有没有资格访问;

一般来说,用户认证——>用户提供用户名和密码,系统通过用户名密码进行验证;


用户授权:

用户是否有权限执行某个操作;

特点:

权限可以达到全面控制;

专门为web环境设计;

重量级,依赖多,组件多;——>我们可以用springboot来简化配置

功能相对于shiro更加强大;

默认用户名:user

密码:项目启动时会随机给一个密码
 


SpringSecurity本质上是一个过滤链(有多个过滤器,只有doFilter()方法放行为true就到下一个过滤器) 


自定义逻辑:

需要实现UserDetailService接口——>因为实际开发中账号密码都是从数据库中查询出来的,所以我们需要自定义逻辑控制认证逻辑;

UserDetailService接口:查询数据库用户名和密码过程;

1.创建一个类继承UsernamePasswordAuthenticationnFilter:重写三个方法

2.创建类实现UserDetailService:编写查询数据过程,返回User对象(由安全框架提供)

 protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        SecurityContext context = SecurityContextHolder.createEmptyContext();
        context.setAuthentication(authResult);
        SecurityContextHolder.setContext(context);
        if (this.logger.isDebugEnabled()) {
            this.logger.debug(LogMessage.format("Set SecurityContextHolder to %s", authResult));
        }

        this.rememberMeServices.loginSuccess(request, response, authResult);
        if (this.eventPublisher != null) {
            this.eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
        }

        this.successHandler.onAuthenticationSuccess(request, response, authResult);
    }

    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
        SecurityContextHolder.clearContext();
        this.logger.trace("Failed to process authentication request", failed);
        this.logger.trace("Cleared SecurityContextHolder");
        this.logger.trace("Handling authentication failure");
        this.rememberMeServices.loginFail(request, response);
        this.failureHandler.onAuthenticationFailure(request, response, failed);
    }


 如何设置登录的用户名密码:



/**
 * @author diao 2022/2/23
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        
        //利用BCryptPasswordEncoder进行密码加密
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String password = passwordEncoder.encode("2002514wyh11");

        //将认证信息放到内存中
        auth.inMemoryAuthentication().withUser("Fairy").password(password).roles("admin");
    }

   /*因为我们需要用到BCryptPasswordEncoder
      所以我们需要弄一个BCryptPasswordEncoder接口
      所以这里我们定义一个返回BCryptPasswordEncoder接口的方法
      * */
    @Bean
    PasswordEncoder password(){
        return new BCryptPasswordEncoder();
    }
}
package com.wuyuhang.security.service;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
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.List;

/**
 * @author diao 2022/2/23
 */
//自定义一个名为userDetailsService的组件注入到容器中
@Service("userDetailsService")
public class MyUserDetailService implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //设置权限
        List<GrantedAuthority> authorityList = AuthorityUtils.commaSeparatedStringToAuthorityList("role");
        //返回security中的User,本质上就是自己定义的用户实现(用户名,密码,权限)
        return new User("Fairy",new BCryptPasswordEncoder().encode("2002514wyh11"),authorityList);
    }
}

 实际上就是返回Security中自定义的UserDetails

package com.wuyuhang.security.config;

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.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author diao 2022/2/23
 */
@Configuration
public class UserLoginConfig extends WebSecurityConfigurerAdapter {

    //注入自定义的userDetailService组件
    @Autowired
    private UserDetailsService userDetailsService;
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //设置自己的实现类,并且设置密码加密(密码加密方式:BCryptPasswordEncoder)
        auth.userDetailsService(userDetailsService).passwordEncoder(password());
    }
    
    @Bean
    PasswordEncoder password(){
        return new BCryptPasswordEncoder();
    }
}

package com.wuyuhang.security.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wuyuhang.security.Utils.ToMap;
import com.wuyuhang.security.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
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.List;

/**
 * @author diao 2022/2/23
 */
//自定义一个名为userDetailsService的组件注入到容器中

@Service("userDetailsService")
public class MyUserDetailService implements UserDetailsService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userMapper.selectOne(ToMap.getInstance().addUser(username).getMap());
//判断
        if (user == null) {
            throw new UsernameNotFoundException("用户名不存在!");
        }

        /*当数据库查询用户信息不为null,给user设置权限,并且返回用户信息
        * */
        //授权
        List<GrantedAuthority> authorityList = AuthorityUtils.commaSeparatedStringToAuthorityList("role");
//    返回用户信息,返回后我们就可以正常访问controller了
        return new User(user.getUsername(), new BCryptPasswordEncoder().encode(user.getPassword()), authorityList);
    }
}

 配置类(将UserDetailsService加载):

package com.wuyuhang.security.config;

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.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author diao 2022/2/23
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter{

    @Autowired
    private UserDetailsService userDetailsService;

    //configure方法可以配置用户名和密码,并且利用BCryptPasswordEncoder进行密码加密
    @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 {
        http.formLogin()//自定义自己编写的前端页面
                .loginPage("/login.html")//登录页面设置
                .loginProcessingUrl("/url/login")//登录访问路径
                .defaultSuccessUrl("/test/index").permitAll()//登录成功后跳转路径
                .and().authorizeRequests()
                .antMatchers("/","/test/hello","/user/login").permitAll()//设置哪些路径可以直接访问,不需要认证
                .anyRequest().authenticated()
                .and().csrf().disable();//关闭csrf防护
    }
}

 

举报

相关推荐

0 条评论