源码见文末,建议使用百度云链接
一、导入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
二、新建一个配置类
package com.security.config; 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.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { //认证用户的来源 @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { super.configure(auth); } //配置SpringSecurity相关信息 @Override protected void configure(HttpSecurity http) throws Exception { super.configure(http); } }
三、基于内存账户认证
package com.security.config; 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.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { //认证用户的来源 @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { //设置认证信息来自内存 {noop}表示明文密码 设置用户 密码 auth.inMemoryAuthentication().withUser("admin").password("{noop}123").roles("USER"); } //配置SpringSecurity相关信息 @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() // test需要USER .antMatchers("/test").hasRole("USER") // 所有资源需要认证 .anyRequest().authenticated() // 指定登录页面 .and().formLogin().permitAll() // 指定退出请求,删除session .and().logout().logoutUrl("/login").invalidateHttpSession(true).permitAll() // 关闭随机token .and().cors().disable(); } }
四、基于数据库认证
4.1导入依赖
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!--mapper--> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>RELEASE</version> </dependency>
4.2配置数据库信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/数据库名?useSSL=false&allowMultiQueries=true&useAffectedRows=true&serverTimezone=GMT%2b8 spring.datasource.username=帐号 spring.datasource.password=密码 spring.datasource.commit-on-return=true #配置别名 mybatis.type-aliases-package=com.security.domin #开启驼峰命名 mybatis.configuration.map-underscore-to-camel-case=true #显示SQL logging.level.com.security=debug
4.3启动类开启MapperScan
@MapperScan("com.security.mapper")
4.4新建用户类实现UserDetails接口
新建用户表
CREATE DATABASE IF NOT EXISTS `test` /*!40100 DEFAULT CHARACTER SET latin1 */; USE `test`; -- 导出 表 test.sys_user 结构 CREATE TABLE IF NOT EXISTS `sys_user` ( `id` int(11) NOT NULL, `username` varchar(32) NOT NULL COMMENT '用户名', `password` varchar(120) NOT NULL COMMENT '密码', `status` int(1) DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
package com.security.domin; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import java.util.Collection; public class SysUser implements UserDetails { private Integer id; private String username; private String password; private Integer status; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; } public Integer getStatus() { return status; } public void setStatus(Integer status) { this.status = status; } //当前用户的角色信息 @Override public Collection<? extends GrantedAuthority> getAuthorities() { return null; } @Override public String getPassword() { return password; } @Override public String getUsername() { return username; } //当前用户是否可用 @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } }
4.5新建角色表及实体类
CREATE DATABASE IF NOT EXISTS `test` /*!40100 DEFAULT CHARACTER SET latin1 */; USE `test`; -- 导出 表 test.sys_role 结构 CREATE TABLE IF NOT EXISTS `sys_role` ( `ID` int(11) DEFAULT NULL COMMENT '编号', `ROLE_NAME` varchar(30) DEFAULT NULL COMMENT '角色名称', `ROLE_DESC` varchar(60) DEFAULT NULL COMMENT '角色描述', KEY `索引 1` (`ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
package com.security.domin; import com.fasterxml.jackson.annotation.JsonIgnore; import org.springframework.security.core.GrantedAuthority; public class SysRole implements GrantedAuthority { private Integer id; private String roleName; private String roleDesc; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getRoleName() { return roleName; } public void setRoleName(String roleName) { this.roleName = roleName; } public String getRoleDesc() { return roleDesc; } public void setRoleDesc(String roleDesc) { this.roleDesc = roleDesc; } //Json转换忽略 @JsonIgnore @Override public String getAuthority() { return roleName; } }
修改用户实体类,增加SysRole字段,@JsonIgnore注解jason转换时忽略
package com.security.domin; import com.fasterxml.jackson.annotation.JsonIgnore; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import java.util.Collection; import java.util.List; public class SysUser implements UserDetails { private Integer id; private String username; private String password; private Integer status; private List<SysRole> roles; public List<SysRole> getRoles() { return roles; } public void setRoles(List<SysRole> roles) { this.roles = roles; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; } public Integer getStatus() { return status; } public void setStatus(Integer status) { this.status = status; } //当前用户的角色信息 @JsonIgnore @Override public Collection<? extends GrantedAuthority> getAuthorities() { return roles; } @Override public String getPassword() { return password; } @Override public String getUsername() { return username; } //当前用户是否可用 @JsonIgnore @Override public boolean isAccountNonExpired() { return true; } @JsonIgnore @Override public boolean isAccountNonLocked() { return true; } @JsonIgnore @Override public boolean isCredentialsNonExpired() { return true; } @JsonIgnore @Override public boolean isEnabled() { return true; } }
CREATE DATABASE IF NOT EXISTS `test` /*!40100 DEFAULT CHARACTER SET latin1 */; USE `test`; -- 导出 表 test.sys_role 结构 CREATE TABLE IF NOT EXISTS `sys_role` ( `ID` int(11) NOT NULL COMMENT '编号', `ROLE_NAME` varchar(30) DEFAULT NULL COMMENT '角色名称', `ROLE_DESC` varchar(60) DEFAULT NULL COMMENT '角色描述', PRIMARY KEY (`ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 正在导出表 test.sys_role 的数据:~0 rows (大约) /*!40000 ALTER TABLE `sys_role` DISABLE KEYS */; INSERT INTO `sys_role` (`ID`, `ROLE_NAME`, `ROLE_DESC`) VALUES (1, 'ROLE_USER', NULL), (2, 'ROLE_ADMIN', NULL); /*!40000 ALTER TABLE `sys_role` ENABLE KEYS */; -- 导出 表 test.sys_user 结构 CREATE TABLE IF NOT EXISTS `sys_user` ( `id` int(11) NOT NULL, `username` varchar(32) NOT NULL COMMENT '用户名', `password` varchar(120) NOT NULL COMMENT '密码', `status` int(1) DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 正在导出表 test.sys_user 的数据:~0 rows (大约) /*!40000 ALTER TABLE `sys_user` DISABLE KEYS */; INSERT INTO `sys_user` (`id`, `username`, `password`, `status`) VALUES (1, 'admin', 'admin', 1); /*!40000 ALTER TABLE `sys_user` ENABLE KEYS */; -- 导出 表 test.sys_user_role 结构 CREATE TABLE IF NOT EXISTS `sys_user_role` ( `id` int(11) NOT NULL, `uid` int(11) NOT NULL, `rid` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `FK_sys_user_role_sys_user` (`uid`), KEY `FK_sys_user_role_sys_role` (`rid`), CONSTRAINT `FK_sys_user_role_sys_role` FOREIGN KEY (`rid`) REFERENCES `sys_role` (`ID`), CONSTRAINT `FK_sys_user_role_sys_user` FOREIGN KEY (`uid`) REFERENCES `sys_user` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 正在导出表 test.sys_user_role 的数据:~0 rows (大约) /*!40000 ALTER TABLE `sys_user_role` DISABLE KEYS */; INSERT INTO `sys_user_role` (`id`, `uid`, `rid`) VALUES (1, 1, 1);
package com.security.mapper; import com.security.domin.SysRole; import org.apache.ibatis.annotations.Select; import tk.mybatis.mapper.common.Mapper; import java.util.List; public interface RoleMapper extends Mapper<SysRole> { @Select("select r.id,r.role_name roleName,r.role_desc roleDesc from sys_role r,sys_user_role ur where r.id=ur.rid and ur.id=#{uid}") public List<SysRole> findByUid(Integer uid); }
package com.security.mapper; import com.security.domin.SysUser; import org.apache.ibatis.annotations.Many; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; import tk.mybatis.mapper.common.Mapper; import java.util.List; public interface UserMapper extends Mapper<SysUser> { // 查询用户 @Select("select * from sys_user where username=#{username}") @Results({ @Result(id = true,property = "id",column = "id"), @Result(property = "roles",column = "id",javaType = List.class,many = @Many(select = "com.security.mapper.RoleMapper.findByUid")) }) public SysUser findByName(String username); }
4.7新建UserService及UserServiceImpl
package com.security.service; import org.springframework.security.core.userdetails.UserDetailsService; public interface UserService extends UserDetailsService { }
package com.security.service.impl; import com.security.mapper.UserMapper; import com.security.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.Transient; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service @Transactional public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { return userMapper.findByName(s); } }
4.8修改SecurityConfig的 configure(AuthenticationManagerBuilder auth)方法
package com.security.config; import com.security.service.UserService; import org.springframework.beans.factory.annotation.Autowired; 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.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.password.PasswordEncoder; @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired UserService userService; //认证用户的来源 @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { //设置认证信息来自内存 {noop}表示明文密码 // auth.inMemoryAuthentication().withUser("admin").password("{noop}123").roles("USER"); //使用数据库认证 auth.userDetailsService(userService).passwordEncoder(new PasswordEncoder() { @Override public String encode(CharSequence rawPassword) { return rawPassword.toString(); } @Override public boolean matches(CharSequence rawPassword, String encodedPassword) { return encodedPassword.equals(rawPassword); } }); } //配置SpringSecurity相关信息 @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() // test需要USER .antMatchers("/test").hasRole("USER") // 所有资源需要认证 .anyRequest().authenticated() // 指定登录页面 .and().formLogin().permitAll(); // 指定退出请求,删除session // .and().logout().logoutUrl("/login").invalidateHttpSession(true).permitAll() 关闭随机token // .and().cors().disable(); } }
4.9方法上动态开启授权
# 在自定义的WebSecurityConfigurerAdapter类上增加注解 @EnableGlobalMethodSecurity(securedEnabled = true) #在自定义的Controller上定义@Secured("ROLE_ADMIN") @Secured("ROLE_ADMIN")
资源包:
https://download.csdn.net/download/qq_29752857/13059289
链接:https://pan.baidu.com/s/1pTbFNbp46erAMRnNFLzZ5Q
提取码:nvof