认证过程:
之前的版本都是springboot1.5.3 Spring 4的版本,这次使用最新版本。
首先是依赖的版本,目前为止,我采用了最新的版本,依赖如下;
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.8.RELEASE
com.wx
security-demo1
0.0.1-SNAPSHOT
security-demo1
Demo project for Spring Boot
1.8
org.springframework.boot
spring-boot-starter-security
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.security
spring-security-test
test
org.springframework.boot
spring-boot-maven-plugin
暂时将获取用户信息来源写在内存当中
package com.wx.securitydemo1.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.crypto.bcrypt.BCryptPasswordEncoder;
/**
* Created by IntelliJ IDEA.
* Date: 2019/9/21
*/
@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest()
.authenticated()
.and().formLogin();
http.logout().logoutSuccessUrl("/");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.passwordEncoder(new BCryptPasswordEncoder())
.withUser("admin")
.password(new BCryptPasswordEncoder().encode("admin"))
.roles("USER");
}
}
Api接口:
@RestController
public class HelloController {
@GetMapping("/hello")
@PreAuthorize("hasAuthority('ROLE_USER')")
public String getHello() {
return "hello,I'm Iron Man,Require user privileges";
}
@GetMapping("/hi")
public String getHi() {
return "hi,I'm Iron Man,No privileges";
}
}
测试:
这里使用默认的登陆页面,默认的登陆页面都变好看了
ok 下面我再把信息的获取来源,放到数据库中,整合Mybatis的通用Mapper
依赖:
tk.mybatis
mapper-spring-boot-starter
RELEASE
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.2
mysql
mysql-connector-java
5.1.26
yml:
server:
port: 8080
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/sys-user?characterEncoding=utf8
username: root
password: 133309
#mybatis配置
#mybatis:
##实体类所在包名
# type-aliases-package: com.wx.securitydemo1.domain
mybatis:
mapper-locations: classpath:mapper/*
type-aliases-package: com.wx.securitydemo1.domain.*
# config-location: classpath:mybatis-config.xml
mapper:
mappers: com.wx.securitydemo1.utils.IBaseDao
identity: MYSQL
WebSecurityConfig配置:
package com.wx.securitydemo1.config;
import com.wx.securitydemo1.service.UserService;
import com.wx.securitydemo1.service.impl.CustomUserDetailsService;
import com.wx.securitydemo1.service.impl.UserServiceImpl;
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.method.configuration.EnableGlobalMethodSecurity;
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.crypto.bcrypt.BCryptPasswordEncoder;
/**
* Created by IntelliJ IDEA.
* User: wangxiang
* Date: 2019/9/21
* To change this template use File | Settings | File Templates.
*/
@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.and()
.authorizeRequests()
.antMatchers("/user/register").permitAll()
.antMatchers("/user/test").permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable(); //如果不禁用的话会默认把post请求拦截下来
http.logout().logoutSuccessUrl("/");
}
@Autowired
CustomUserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//用户信息存在内存
// auth.inMemoryAuthentication()
// .passwordEncoder(new BCryptPasswordEncoder())
// .withUser("admin")
// .password(new BCryptPasswordEncoder().encode("admin"))
// .roles("USER");
//用户信息存在数据库
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
}
获取用户信息
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserService userService;
@Override
public User loadUserByUsername(String userName) throws UsernameNotFoundException {
User user = new User();
user.setUserName(userName);
List userList = userService.queryUserByuserName(user);
if (Objects.isNull(userList)) {
throw new CommonException("error.user.not.exist");
}
return userService.queryUserByuserName(user).get(0);
}
}
实体类:
package com.wx.securitydemo1.domain;
import org.jboss.logging.Field;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: wangxiang
* Date: 2019/9/21
* To change this template use File | Settings | File Templates.
*/
public class User implements UserDetails, Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
//如果只是大小写区分,可以不加name属性
@Column(name = "username", nullable = false, unique = true)
private String userName;
@Column(name = "password")
private String passWord;
// @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
// @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
// inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"))
private List authorities;
/**
* authorities为权限点的集合,这个利用了Jpa关联查询了角色表
*/
public User() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
/**
* getAuthorities()方法返回的是该用户设置的权限信息
*
* @return
*/
@Override
public Collection extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
@Override
public String getUsername() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public void setAuthorities(List authorities) {
this.authorities = authorities;
}
/**
* getUsername()方法为UserDetails的方法,这个方法不一定返回username,也可以是其他的用户信息
* 例如手机号码,邮箱地址,
*
* @return
*/
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
package com.wx.securitydemo1.domain;
import org.springframework.security.core.GrantedAuthority;
import javax.persistence.*;
@Entity
public class Role implements GrantedAuthority {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
/** 权限点可以是任何的字符串,不一定是角色的字符串,本例权限点是从数据库中读取的Role表的nama字段*/
@Override
public String getAuthority() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
dao:
@Mapper
public interface UserMapper extends IBaseDao {
List queryUserByuserName(@Param("user") User user);
List list (User user);
}
mapper:
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/register")
public User userRegister(@RequestParam("username") String userName,
@RequestParam("password") String passWord) {
return userService.insert(userName, passWord);
}
@GetMapping("/test")
public List test() {
List list = userService.list(new User());
return list;
}
}
注册用户:
github:https://github.com/WangAlainDelon/security-demo1.git