59_SpringSecurity

1 SpringSecurity

1.2 第一个 SpringSecurity 项目

20201229194217490

1.2.1 导入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

1.2.2 访问页面

导入 spring-boot-starter-security 启动器后,Spring Security 已经生效,默认拦截全部请求,如果用户

没有登录,访问http://localhost:8080,会主动跳转到内置的登录页面。
20201229190037000

在 SecurityProperties 中初始化了用户名和密码

/**
* Default user name.
*/
private String name = "user";

/**
* Password for the default user name.
*/
private String password = UUID.randomUUID().toString();

1.2.3 UserDetailsService

通过自定义 UserDetailsService 接口的实现类控制认证逻辑

package com.cl.mapper;

import com.cl.pojo.User;
import org.apache.ibatis.annotations.Select;

/**
 * @Author chenlan
 * @Description TODO
 * @Date 2020/12/29 11:15
 * @Version 1.0
 */

public interface UserMapper {

    /**
     * 根据用户名查询用户
     *
     * @param username
     * @return
     */
    @Select("select * from sys_user where username = #{username}")
    User selectUserByUsername(String username);
}

package com.cl.service.impl;

import com.cl.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
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.stereotype.Service;

import java.util.ArrayList;

/**
 * @Author chenlan
 * @Description TODO
 * @Date 2020/12/29 10:43
 * @Version 1.0
 */

@Service
public class LoginServiceImpl implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;

    /**
     * @param username 用户提交的用户名
     * @return UserDetails(Interface) 返回其实现类 org.springframework.security.core.userdetails.User
     * @throws UsernameNotFoundException 通过用户名没有查询到相关用户则抛出异常
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 查询当前登录用户是否存在
        com.cl.pojo.User user = userMapper.selectUserByUsername(username);
        if (user != null) {
            /**
             * org.springframework.security.core.userdetails.User
             * 自定义登录逻辑时 SpringSecurity 要求 容器中必须要有 passwordEncoder 实例 用作密码验证
             * User user = new User(username,password,authorities)
             * @username 用户提交的用户名
             * @password 数据库中查询得到的密码
             * @authorities 用户具备的权限 不允许为空
             */
            return new User(username, user.getPassword(), AuthorityUtils.commaSeparatedStringToAuthorityList("没有权限"));
        }
        throw new UsernameNotFoundException("用户不存在");
    }
}

1.2.4 PasswordEncoder

SpringSecurity 要求容器中必须有 PasswordEncoder 实例。所以当自定义登录逻辑时要求必须

给容器注入 PaswordEncoder 的 bean 对象

1.2.4.1 自定义实例
package com.cl.util;

import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

/**
 * @Author chenlan
 * @Description TODO
 * @Date 2020/12/29 10:58
 * @Version 1.0
 *
 * 配置自定义密码编码器
 */

@Component
public class MyPasswordEncoder implements PasswordEncoder{
    /**
     * 设置密码加密
     *
     * @param rawPassword 用户提交的密码
     * @return 返回加密后的密码
     */
    @Override
    public String encode(CharSequence rawPassword) {
        return rawPassword + "cl";
    }

    /**
     * 进行密码验证
     *
     * @param rawPassword 用户提交的密码(未加密)
     * @param encodedPassword 查询得到的数据库密码
     * @return 返回 true 则验证通过 false 则验证失败
     */
    @Override
    public boolean matches(CharSequence rawPassword, String encodedPassword) {
        return encode(rawPassword).equals(encodedPassword);
    }
}

1.2.4.2 使用内置解析器

BCryptPasswordEncoder 是 SpringSecurity 官方推荐的密码解析器。

BCryptPasswordEncoder 是对bcrypt强散列方法的具体实现。是基于Hash算法实现的单向加

密。可以通过 strength 控制加密强度,默认10。

package com.cl.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @Author chenlan
 * @Description TODO
 * @Date 2020/12/29 11:22
 * @Version 1.0
 *
 *
 * SpringSecurity 配置文件
 */

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 配置密码解析器
     *
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder(4);
    }
}

1.2.5 自定义登录页面

1.2.5.1 编写登录页面
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/login" method="post">
    <p><input type="text" name="username"/></p>
    <p><input type="password" name="password"/></p>
    <p><input type="submit" value="登录"/></p>
</form>

</body>
</html>
1.2.5.2 编写配置类
package com.cl.config;

import com.cl.config.handler.MyAuthenticationFailureHandler;
import com.cl.config.handler.MyAuthenticationSuccessHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @Author chenlan
 * @Description TODO
 * @Date 2020/12/29 11:22
 * @Version 1.0
 *
 *
 * SpringSecurity 配置文件
 */

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 登录配置 认证和授权
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 配置认证
        http.formLogin()
                // 配置登录成功后 跳转的 action
                .successForwardUrl("/index"
                // 设置登录的请求路径(登录表单的请求路径)
                .loginProcessingUrl("/login")
                // 配置登录失败跳转路径
                .failureForwardUrl("/fail")
                // 配置登录表单对应的用户名和密码
                .usernameParameter("username")
                .passwordParameter("password")
                // 设置登录页面
                .loginPage("/");


        // 配置授权 (从上到下)
        http.authorizeRequests()
                // 设置 "login.html" 路径可以匿名访问
                .antMatchers("/").anonymous()
                // 配置所有请求都要进行认证
                // anyRequest 等同于 antMatchers("/**")
                .anyRequest().authenticated();

        // 关闭 csrf 保护
        http.csrf().disable();
    }

    /**
     * 配置密码解析器
     *
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder(4);
    }
}
1.2.5.3 编写控制层
package com.cl.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @Author chenlan
 * @Description TODO
 * @Date 2020/12/29 14:30
 * @Version 1.0
 */

@Controller
public class UserController {

    @RequestMapping("/")
    public String login(){
        return "login";
    }

    @RequestMapping("/index")
    public String index(){
        return "index";
    }

    @RequestMapping("/fail")
    public String fail(){
        return "fail";
    }
}

1.2.6 认证其他配置

1.2.6.1 配置请求中的参数名

当进行登录时会执行 UsernamePasswordAuthenticationFilter 过滤器

20201229200450621

在登录配置中进行配置即可

20201229200622530

1.2.6.2 自定义登录成功处理器

在登录配置中使用 successForwardUrl() 配置登录成功时

20201229203217757

20201229203558692

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值