Spring Security 学习笔记(二)

Spring Boot 项目中快速使用(整合mybatis)

      • 1.引入pom.xml文件
      • 2.设置security的配置文件
        • SecurityConfig类 -> 配置类
        • AuthenticationEntry 类 -> 未登录时
        • AuthenticationSuccess类 -> 登录成功时
        • AuthenticationFailure类 -> 登录失败时
        • AccessDenied 类 -> 无权访问时
        • LogoutSuccess 类 ->注销操作时
        • SessionInformationExpiredStrategy类 ->异地登录时
      • 3.项目其他设置
        • UserController
        • UserService
        • UserServiceImpl
        • UserMapper
        • application.yml
        • login.html
        • MVC配置

1.引入pom.xml文件

关键部分

        
        <dependency>
            <groupId>org.springframework.securitygroupId>
            <artifactId>spring-security-webartifactId>
            <version>5.5.1version>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-securityartifactId>
            <version>RELEASEversion>
            <scope>compilescope>
        dependency>

补充部分

        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-thymeleafartifactId>
        dependency>
		
        <dependency>
            <groupId>com.google.code.gsongroupId>
            <artifactId>gsonartifactId>
            <version>2.8.2version>
        dependency>
        
        <dependency>
            <groupId>org.apache.commonsgroupId>
            <artifactId>commons-lang3artifactId>
        dependency>
        
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
        
        <dependency>
            <groupId>org.mybatis.spring.bootgroupId>
            <artifactId>mybatis-spring-boot-starterartifactId>
            <version>2.1.2version>
        dependency>
        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <scope>runtimescope>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.mybatis.spring.bootgroupId>
            <artifactId>mybatis-spring-boot-starterartifactId>
            <version>2.2.0version>
        dependency>

2.设置security的配置文件

SecurityConfig类 -> 配置类

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Resource
    private UserService userService;
    /**
     * 未登录
     */
    @Resource
    private AuthenticationEntry authenticationEntry ;
    /**
     * 登录成功
     */
    @Resource
    private AuthenticationSuccess authenticationSuccess;
    /**
     * 登录失败
     */
    @Resource
    private AuthenticationFailure authenticationFailure;
    /**
     * 无权访问
     */
    @Resource
    private AccessDenied accessDenied ;
    /**
     * 注销操作
     */
    @Resource
    private LogoutSuccess logoutSuccess ;
    /**
     * 异地登录,账号下线时的逻辑处理
     */
    @Resource
    private SessionInformationExpiredStrategy sessionInformationExpiredStrategy;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(userService)
                .passwordEncoder(new BCryptPasswordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //cors()解决跨域问题,csrf()会与restful风格冲突,默认 springsecurity 是开启的,所以要disable()关闭一下
        http.cors().and().csrf().disable();

        http.authorizeRequests()
                .antMatchers("/add").permitAll()
                .antMatchers("/test").hasRole("ADMIN")
                // hasRole会将参数自动加上ROLE_
                .and()
                //开启登录
                .formLogin()
                .usernameParameter("username")
                .passwordParameter("password")
                .loginPage("/toLogin")
                .loginProcessingUrl("/login")
                //允许所有人访问
                .permitAll()
                // 登录成功逻辑处理
                .successHandler(authenticationSuccess)
                // 登录失败逻辑处理
                .failureHandler(authenticationFailure)

                .and()
                //开启注销
                .logout()
                //允许所有人访问
                .permitAll()
                //注销逻辑处理
                .logoutSuccessHandler(logoutSuccess)
                //删除cookie
                .deleteCookies("JSESSIONID")

                .and().exceptionHandling()
                //权限不足的时候的逻辑处理
                .accessDeniedHandler(accessDenied)
                //未登录是的逻辑处理
                .authenticationEntryPoint(authenticationEntry)

                .and()
                .sessionManagement()
                //最多只能一个用户登录一个账号
                .maximumSessions(1)
                //异地登录,账号下线时的逻辑处理
                .expiredSessionStrategy(sessionInformationExpiredStrategy);

    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
    }
}

AuthenticationEntry 类 -> 未登录时

/**
 * 未登录时
 * @author CH
 * @date 2021-08-19 15:23
 */
@Component
public class AuthenticationEntry implements AuthenticationEntryPoint {

    @Autowired
    Gson gson;

    /**
     * 未登录时返回给前端数据
     */
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, IOException {
        Result<Object> result = ResultUtil.error(401,"需要登录!!");
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().write(gson.toJson(result));
    }
}

AuthenticationSuccess类 -> 登录成功时

/**
 * 登录成功后自定义操作
 * @author CH
 * @date 2021-08-19 16:23
 */
@Component
public class AuthenticationSuccess implements AuthenticationSuccessHandler {
    @Autowired
    Gson gson;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException, IOException {
        //登录成功时返回给前端的数据
        Result<Object> result = ResultUtil.success("登录成功!!!!!");
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().write(gson.toJson(result));
    }
}

AuthenticationFailure类 -> 登录失败时

/**
 * 登录失败
 * @author CH
 * @date 2021-08-19 16:20
 */
@Component
public class AuthenticationFailure implements AuthenticationFailureHandler {
    @Autowired
    Gson gson;
    
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, IOException {
        Result<Object> result;
        if (e instanceof UsernameNotFoundException) {
            result = ResultUtil.error(-1,e.getMessage());
        } else if (e instanceof BadCredentialsException) {
            result = ResultUtil.error(-1,"密码错误!!");
        } else {
            result = ResultUtil.error(-1,e.getMessage());
        }
        //处理编码方式,防止中文乱码的情况
        response.setContentType("text/json;charset=utf-8");
        //返回给前台
        response.getWriter().write(gson.toJson(result));
    }
}

AccessDenied 类 -> 无权访问时

/**
 * 无权访问
 * @author CH
 * @date 2021-08-19 16:25
 */
@Component
public class AccessDenied implements AccessDeniedHandler {
    @Autowired
    Gson gson;

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException {
        Result<Object> result = ResultUtil.error(-1,"无权访问,need Authorities!!");
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().write(gson.toJson(result));
    }
}

LogoutSuccess 类 ->注销操作时

/**
 * 注销操作
 * @author CH
 * @date 2021-08-19 17:12
 */
@Component
public class LogoutSuccess implements LogoutSuccessHandler {
    @Autowired
    Gson gson;

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        Result<Object> result = ResultUtil.success("注销成功");
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().write(gson.toJson(result));
    }
}

SessionInformationExpiredStrategy类 ->异地登录时

/**
 * 异地登录,账号下线时的逻辑处理
 * @author CH
 * @date 2021-08-19 17:06
 */
@Component
public class SessionInformationExpiredStrategy implements org.springframework.security.web.session.SessionInformationExpiredStrategy {
    @Autowired
    Gson gson;

    @Override
    public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException, ServletException {
        Result<Object> result = ResultUtil.error(-1,"您的账号在异地登录,建议修改密码");
        HttpServletResponse response = event.getResponse();
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().write(gson.toJson(result));
    }
}

3.项目其他设置

UserController

/**
 * @author CH
 * @date 2021-08-19 11:13
 */
@RestController
public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping("/test")
    public String index(){
        return "首页---->"+LocalDateTime.now().toString();
    }

    @RequestMapping("/add")
    public String add() {
        User user = new User();
        user.setUsername("user1");
        user.setPassword("123456");
        user.setState(0);
        user.setRoleId(1);
        userService.add(user);
        return "添加用户---->"+LocalDateTime.now().toString();
    }

    @RequestMapping("ttt")
    public String ttt(){
        return "TTTT";
    }
}

UserService

需要继承UserDetailsService类

public interface UserService extends UserDetailsService {
    @Override
    UserDetails loadUserByUsername(String username);
    int add(User user);
}

UserServiceImpl

/**
 * @author CH
 * @date 2021-08-19 10:48
 */
@Service
public class UserServiceImpl implements UserService, UserDetailsService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) {
    	//自己写的查询
        UserDto userDto = userMapper.queryUserByUserName(username);
        if (username == null) {
            throw new UsernameNotFoundException("用户名不存在");
        }

        List<SimpleGrantedAuthority> authorityList = new ArrayList<>();
        String role = userDto.getCode();
        if (StringUtils.isNotBlank(role)) {
            authorityList.add(new SimpleGrantedAuthority(role.trim()));
        }
        //结尾返回org.springframework.security.core.userdetails.User!!
        return new org.springframework.security.core.userdetails
                .User(userDto.getUsername(), userDto.getPassword(), authorityList);
    }

    @Override
    public int add(User user) {
        user.setPassword(new BCryptPasswordEncoder().encode(user.getPassword()));
        return userMapper.add(user);
    }

}

UserMapper

@Mapper
public interface UserMapper {
	//自己写一下查询
    UserDto queryUserByUserName(String username);
    int add(User user);
}

application.yml

server:
  port: 8000
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/ch_pf?useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver
  thymeleaf:
    prefix: classpath:/templates/
    cache: false
    suffix: .html
    mode: LEGACYHTML5
    template-resolver-order: 0
mybatis:
  mapper-locations: classpath:mapper/*Mapper.xml
  type-aliases-package: com.website.entity

login.html

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

MVC配置

/**
 * MVC配置
 * @author CH
 * @date 2021-08-19 11:45
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/toLogin").setViewName("login");
    }
}

你可能感兴趣的:(Spring,spring,spring,boot,java)