SpringSecurity登录配置-角色权限-403定制

加密案例

PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encode = passwordEncoder.encode("123456");
System.out.println(encode); //$2a$10$svp.cYEelXIMGz/t952otuk2I7COcQLh.ZY3mC4TItFMtaC1Ij17m

sercurity自带的登录校验

在这里插入图片描述
在这里插入图片描述

重写security登录用户和密码

@Configuration
public class SecurityConfig {


	//SpringBoot需要这个Bean,当需要加密时
    @Bean
    public PasswordEncoder getPw(){
        return new BCryptPasswordEncoder();
    }
}

配置

    @Autowired
    UserDetailServiceImpl mUserDetailsService;
    @Autowired
    PasswordEncoder mPasswordEncoder;

    //认证配置
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(mUserDetailsService).passwordEncoder(mPasswordEncoder);
    }
@Service
public class UserDetailServiceImpl implements UserDetailsService {
    

    @Autowired
    PasswordEncoder mPasswordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //根据用户名查数据库,如果不存在就抛出UserNotFoundException
        if(!"admin".equals(username)) throw new UsernameNotFoundException("用户名不存在");
        //数据库中已经进行加密的密码
        String dbpassword = mPasswordEncoder.encode("123456");


        // 用户名 + 密码 + 授权权限
        return new User(username,dbpassword, AuthorityUtils.commaSeparatedStringToAuthorityList("admin,normal"));
    }
}

自定义登录界面配置

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>登录</title>
</head>
<body>
<form method="post" action="/user/login">
  username:  <input type="text" name="username"> <br/>
  password: <input type="text" name="password"> <br/>
  <input type="submit" value="提交"/>
</form>
</body>
</html>

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .loginPage("/login") //跳转至登录页
                .loginProcessingUrl("/user/login") //表单action提交接口,对接loadUserByUsername方法
                .successForwardUrl("/index");
        http.csrf().disable(); //关掉csrf才可以表单接口和UserDetailService方法对接

        //认证拦截配置
        http.authorizeRequests()
                .antMatchers("/login").permitAll() //登录页放行
                .anyRequest().authenticated(); //所有界面都需要认证
    }

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

登录失败页

loginError.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>登录失败</title>
</head>
<body>
登录失败,请 <a href="/login">重新登录</a>
</body>
</html>

配置

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .loginPage("/login") //跳转至登录页
                .loginProcessingUrl("/user/login") //表单action提交接口,对接loadUserByUsername方法
                .successForwardUrl("/index")
                .failureForwardUrl("/loginError");
        http.csrf().disable(); //关掉csrf才可以表单接口和UserDetailService方法对接

        //认证
        http.authorizeRequests()
                .antMatchers("/login").permitAll() //登录页放行
                .antMatchers("/loginError").permitAll() //登录失败页放行
                .anyRequest().authenticated(); //所有界面都需要认证
    }

认证界面和对接接口底层原理是
UsernamePasswordAuthenticationFilter
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

两个接口

当什么也没有配置的时候,账号和密码是由SpringSecurity生成的。而在实际项目中账号和密码都是从数据库中查询出来的。我已我们要通过自定义逻辑控制认证逻辑
UserDetailsService 自定义认证用户
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

自定义表单参数名

  username:  <input type="text" name="username123"> <br/>
  password: <input type="text" name="password123"> <br/>
 http.formLogin()
              .usernameParameter("username123")
              .passwordParameter("password123")
              .loginPage("/login") //跳转至登录页
              .loginProcessingUrl("/user/login") //表单action提交接口,对接loadUserByUsername方法
              .successForwardUrl("/index")
              .failureForwardUrl("/loginError");
      http.csrf().disable(); //关掉csrf才可以表单接口和UserDetailService方法对接

登录成功|失败处理器

/**
 * 项目名: learn_spring_security
 * 包名:    com.kcl.handler
 * 文件名   My
 * 创建者
 * 创建时间: 2021/5/26 4:57 PM
 * 描述  自定义登录成功处理器
 */
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    private String url;

    public MyAuthenticationSuccessHandler(String url) {
        this.url = url;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        httpServletResponse.sendRedirect(url);

        User user = (User) authentication.getPrincipal();
        System.out.println(user.getUsername());
        System.out.println(user.getPassword()); //null
        System.out.println(user.getAuthorities());
    }
}
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {

    private String url;

    public MyAuthenticationFailureHandler(String url) {
        this.url = url;
    }

    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        httpServletResponse.sendRedirect(url);
    }
}

配置
在这里插入图片描述

antMatchers

功能 > 拦截器
** 文件下的所有资源
*当前文件夹下面的资源

.antMatchers("/css/**","/js/**", "/img/**").permitAll() //static目录下放行

其他
在这里插入图片描述

权限控制和角色控制

在这里插入图片描述

权限控制
用户认证分配权限
认证同时授权

@Service
public class UserDetailServiceImpl implements UserDetailsService {

    @Autowired
    PasswordEncoder mPasswordEncoder;
    //自定义登录逻辑
    //security自带登录界面 会 和该方法进行对接
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //根据用户名查数据库,如果不存在就抛出UserNotFoundException
        if(!"admin".equals(username) && !"zhangsan".equals(username)) throw new UsernameNotFoundException("用户名不存在");

        if("admin".equals(username)){
            //数据库中已经进行加密的密码
            String dbpassword = mPasswordEncoder.encode("123456");
            // 用户名 + 密码 + 授权权限
            return new User(username,dbpassword, AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_admin"));
        }
        if("zhangsan".equals(username)){
            //数据库中已经进行加密的密码
            String dbpassword = mPasswordEncoder.encode("123456");
            // 用户名 + 密码 + 授权权限
            return new User(username,dbpassword, AuthorityUtils.commaSeparatedStringToAuthorityList("vip,ROLE_user"));
        }
        return null;
    }
}

权限控制

        //认证
        http.authorizeRequests()
                .antMatchers("/vip").hasAuthority("vip")   //权限控制
                .antMatchers("/admin").hasRole("admin") //角色控制

自定义403处理

@Component
public class MyAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
        httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); //403
        //返回json格式
        httpServletResponse.setHeader("Content-Type","application/json;charset=utf-8");
        PrintWriter writer = httpServletResponse.getWriter();
        writer.write("{\"status\":\"error\",\"msg\":\"权限不足,请联系管理员\"}");
        writer.flush();
        writer.close();
    }
}

SecurityConfig中的configure方法中配置

        //403权限不足,自定义处理
        http.exceptionHandling()
                .accessDeniedHandler(mMyAccessDeniedHandler);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值