德州企业网站建设要素,网站如何做的有特色,外贸建站seo优化,网站怎么做404页面跳转Spring Security是Spring官方推荐的认证、授权框架#xff0c;功能相比Apache Shiro功能更丰富也更强大#xff0c;但是使用起来更麻烦。 如果使用过Apache Shiro#xff0c;学习Spring Security会比较简单一点#xff0c;两种框架有很多相似的地方。 目录
一、准备工作
… Spring Security是Spring官方推荐的认证、授权框架功能相比Apache Shiro功能更丰富也更强大但是使用起来更麻烦。 如果使用过Apache Shiro学习Spring Security会比较简单一点两种框架有很多相似的地方。 目录
一、准备工作
创建springboot项目
pom.xml
application.yml
二、创建相关的类
UserDetailsService
SecurityConfig.java
SystemProperties.java
MybatisPlusConfig.java
三、完成登录接口
创建数据库实体类
创建持久层接口
创建登录DTO对象
创建控制器类
创建业务层类
自定义登录成功处理器 一、准备工作
创建springboot项目 首先通过IntelliJ IDEA创建一个springboot项目项目名为springboot-springsecurity在pom.xml中添加相关依赖。 pom.xml
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.3.4.RELEASE/versionrelativePath //parentgroupIdcom.example/groupIdartifactIdspringboot-springsecurity/artifactIdversion0.0.1-SNAPSHOT/versionpropertiesjava.version1.8/java.versionjjwt.version0.9.1/jjwt.versionmysql.version8.0.28/mysql.versiondruid.version1.1.21/druid.versionlombok.version1.18.22/lombok.versionmybatis.version2.2.2/mybatis.versionmybatis-plus.version3.5.1/mybatis-plus.version/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!--validation--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-validation/artifactId/dependency!--spring security--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactId/dependency!--mysql--dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion${mysql.version}/version/dependency!--druid--dependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion${druid.version}/version/dependency!--lombok--dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion${lombok.version}/version/dependency!--mybatis--dependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion${mybatis.version}/version/dependency!--mybatis-plus--dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion${mybatis-plus.version}/version/dependency!--jjwt--dependencygroupIdio.jsonwebtoken/groupIdartifactIdjjwt/artifactIdversion${jjwt.version}/version/dependency/dependenciesbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/plugin/plugins/build
/project application.yml
server:port: 8080servlet:context-path: /spring:datasource:username: rootpassword: rooturl: jdbc:mysql://localhost:3306/spring_securitydriver-class-name: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSourcemybatis-plus:mapper-locations: classpath:mapper/*Mapper.xmllogging:level:springfox: errorcom.example.security: debugsystem:login-page: /login.htmllogin-url: /user/loginindex-page: /index.htmllogout-url: /user/logoutparameter:username: usernamepassword: passwordwhite-url:- /js/**- /css/**- /images/**- /user/login- /login.html 二、创建相关的类
UserDetailsService
UserDetailsService接口是Spring Security中非常重要的接口在登录认证的时候会通过这个接口的loadUserByUsername()方法获取用户的信息来完成登录的用户名、密码校验完成登录流程。
我们需要创建一个UserDetailsService的实现类并声明为Spring组件。
package com.example.security.security;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.security.entity.User;
import com.example.security.exception.GlobalException;
import com.example.security.mapper.UserMapper;
import com.example.security.restful.ResponseCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
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.Component;import java.util.ArrayList;
import java.util.List;/*** author heyunlin* version 1.0*/
Component
public class UserDetailsServiceImpl implements UserDetailsService {private final UserMapper userMapper;Autowiredpublic UserDetailsServiceImpl(UserMapper userMapper) {this.userMapper userMapper;}Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {// 查询用户信息User user selectByUsername(username);if (user null) {throw new BadCredentialsException(登录失败用户名不存在);} else {ListString permissions selectPermissions(username);return org.springframework.security.core.userdetails.User.builder().username(user.getUsername()).password(user.getPassword()).accountExpired(false).accountLocked(false).disabled(!user.getEnable()).credentialsExpired(false).authorities(permissions.toArray(new String[] {})).build();}}/*** 通过用户名查询用户信息* param username 用户名* return User*/private User selectByUsername(String username) {QueryWrapperUser wrapper new QueryWrapper();wrapper.eq(username, username);ListUser list userMapper.selectList(wrapper);if (list.size() 1) {return list.get(0);}return null;}/*** 通过用户名查询用户权限* param username 用户名* return ListString*/private ListString selectPermissions(String username) {if (username null) {throw new GlobalException(ResponseCode.BAD_REQUEST, 用户名不能为空);}ListString permissions new ArrayList();permissions.add(/user/login);permissions.add(/user/logout);permissions.add(/user/selectById);return permissions;}} SecurityConfig.java
创建security的配置类
package com.example.security.config;import com.example.security.security.LoginFailHandler;
import com.example.security.security.LoginSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.PasswordEncoder;/*** author heyunlin* version 1.0*/
Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {private final SystemProperties systemProperties;Autowiredpublic SecurityConfig(SystemProperties systemProperties) {this.systemProperties systemProperties;}Beanpublic PasswordEncoder passwordEncoder() {return new PasswordEncoder() {Overridepublic String encode(CharSequence charSequence) {return (String) charSequence;}Overridepublic boolean matches(CharSequence charSequence, String s) {return charSequence.equals(s);}};}BeanOverridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}Overrideprotected void configure(HttpSecurity http) throws Exception {// 禁用防跨域攻击http.csrf().disable();// 配置各请求路径的认证与授权http.formLogin().loginPage(systemProperties.getLoginPage()) // 自定义登录页面的地址.loginProcessingUrl(systemProperties.getLoginUrl()) // 处理登录的接口地址.usernameParameter(systemProperties.getParameter().get(username)) // 用户名的参数名.passwordParameter(systemProperties.getParameter().get(password)) // 密码的参数名.successHandler(new LoginSuccessHandler(systemProperties))//.successForwardUrl(/index.html) // 登录成功跳转的地址.failureHandler(new LoginFailHandler()); // 登录失败的处理器// 退出登录相关配置http.logout().logoutUrl(systemProperties.getLogoutUrl()) // 退出登录的接口地址.logoutSuccessUrl(systemProperties.getLoginUrl()); // 退出登录成功跳转的地址// 配置认证规则String[] toArray systemProperties.getWhiteUrl().toArray(new String[]{});http.authorizeRequests().antMatchers(toArray).permitAll() // 白名单也就是不需要登录也能访问的资源.anyRequest().authenticated();}} SystemProperties.java
package com.example.security.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;import java.util.List;
import java.util.Map;/*** author heyunlin* version 1.0*/
Data
Component
ConfigurationProperties(prefix system)
public class SystemProperties {/*** 登录页面*/private String loginPage;/*** 登录的请求地址*/private String loginUrl;/*** 登录成功后跳转的页面*/private String indexPage;/*** 退出登录的请求地址*/private String logoutUrl;/*** 白名单*/private ListString whiteUrl;/*** 登录的参数*/private MapString, String parameter;
} MybatisPlusConfig.java
package com.example.security.config;import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** author heyunlin* version 1.0*/
Configuration
MapperScan(basePackages com.example.security.mapper)
public class MybatisPlusConfig {Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor new MybatisPlusInterceptor();// 防全表更新与删除插件interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());// 分页插件interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}} 三、完成登录接口
创建数据库实体类
User.java
package com.example.security.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;import java.io.Serializable;
import java.time.LocalDateTime;/*** 用户* author heyunlin* version 1.0*/
Data
TableName(user)
public class User implements Serializable {private static final long serialVersionUID 18L;TableId(value id, type IdType.INPUT)private String id;/*** 姓名*/private String name;/*** 性别*/private Integer gender;/*** 用户名*/private String username;/*** 密码*/private String password;/*** 手机号*/private String phone;/*** 是否启用*/private Boolean enable;/*** 最后一次登录时间*/JsonFormat(pattern yyyy-MM-dd HH:mm:ss, timezone GMT8)private LocalDateTime lastLoginTime;
} 创建持久层接口
package com.example.security.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.security.entity.User;
import org.springframework.stereotype.Repository;/*** author heyunlin* version 1.0*/
Repository
public interface UserMapper extends BaseMapperUser {} 创建登录DTO对象
package com.example.security.dto;import lombok.Data;import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;/*** author heyunlin* version 1.0*/
Data
public class UserLoginDTO implements Serializable {private static final long serialVersionUID 18L;/*** 用户名*/NotNull(message 用户名不允许为空)NotEmpty(message 用户名不允许为空)private String username;/*** 密码*/NotNull(message 密码不允许为空)NotEmpty(message 密码不允许为空)private String password;
} 创建控制器类
package com.example.security.controller;import com.example.security.dto.UserLoginDTO;
import com.example.security.entity.User;
import com.example.security.restful.JsonResult;
import com.example.security.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;/*** author heyunlin* version 1.0*/
RestController
RequestMapping(path /user, produces application/json;charsetutf-8)
public class UserController {private final UserService userService;Autowiredpublic UserController(UserService userService) {this.userService userService;}RequestMapping(value /login, method RequestMethod.POST)public JsonResultVoid login(Validated UserLoginDTO userLoginDTO) {userService.login(userLoginDTO);return JsonResult.success(登录成功);}RequestMapping(value /logout, method RequestMethod.POST)public JsonResultVoid logout() {userService.logout();return JsonResult.success(登出成功);}RequestMapping(value /selectById, method RequestMethod.GET)public JsonResultUser selectById(RequestParam(value id, required true) String userId) {User user userService.selectById(userId);return JsonResult.success(null, user);}} 创建业务层类
UserService接口
package com.example.security.service;import com.example.security.dto.UserLoginDTO;
import com.example.security.entity.User;/*** author heyunlin* version 1.0*/
public interface UserService {/*** 登录认证* param userLoginDTO 用户登录信息*/void login(UserLoginDTO userLoginDTO);/*** 退出登录*/void logout();/*** 通过ID查询用户信息* param userId 用户ID* return User 通过ID查询到的用户信息*/User selectById(String userId);
}
UserServiceImpl.java
package com.example.security.service.impl;import com.example.security.dto.UserLoginDTO;
import com.example.security.entity.User;
import com.example.security.mapper.UserMapper;
import com.example.security.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;/*** author heyunlin* version 1.0*/
Service
public class UserServiceImpl implements UserService {private final UserMapper userMapper;private final AuthenticationManager authenticationManager;Autowiredpublic UserServiceImpl(UserMapper userMapper, AuthenticationManager authenticationManager) {this.userMapper userMapper;this.authenticationManager authenticationManager;}Overridepublic void login(UserLoginDTO userLoginDTO) {Authentication authentication new UsernamePasswordAuthenticationToken(userLoginDTO.getUsername(),userLoginDTO.getPassword());authenticationManager.authenticate(authentication);}Overridepublic void logout() {// todo}Overridepublic User selectById(String userId) {return userMapper.selectById(userId);}} 自定义登录成功处理器
登陆成功直接重定向到/index.html
package com.example.security.security;import com.example.security.config.SystemProperties;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** author heyunlin* version 1.0*/
public class LoginSuccessHandler implements AuthenticationSuccessHandler {private final SystemProperties systemProperties;public LoginSuccessHandler(SystemProperties systemProperties) {this.systemProperties systemProperties;}Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {response.sendRedirect(systemProperties.getIndexPage());}} 至此springboot整合Spring Security就完成了项目结构如下。 文章就分享到这里了代码已开源可按需获取~
springboot整合spring securityhttps://gitee.com/he-yunlin/springboot-springsecurity.git