springboot springsecurity 基于html 通过 json 方式登录
数据库表

数据查询基于JPA
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.26</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.26</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private SecurityProvider securityProvider;
@Autowired
MyUserService myUserService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/js/**","/logon","/**/*.html").permitAll()
.anyRequest()
.authenticated()
.and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserService).passwordEncoder(new BCryptPasswordEncoder());
}
@Override
public void configure(WebSecurity web) throws Exception {
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
@Data
@ToString
@Entity
public class User implements UserDetails {
@Id
@GeneratedValue
private Integer id;
@Column(name = "name")
private String username;
private String password;
private String role;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
//注意:这里每个权限前面都要加ROLE_。否在最后验证不会通过
authList.add(new SimpleGrantedAuthority("ROLE_"+ this.getRole()));
return authList;
}
@Override
public boolean isAccountNonExpired() {
return false;
}
@Override
public boolean isAccountNonLocked() {
return false;
}
@Override
public boolean isCredentialsNonExpired() {
return false;
}
@Override
public boolean isEnabled() {
return false;
}
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../js/jquery-3.4.1.min.js"></script>
<script>
$(function(){
$("#sub").click(function(){
var username = $("#username").val();
var password = $("#password").val();
//csrf token
var token = document.cookie.split('; ').reduce(function(result, v, i, a) { var k = v.split('='); result[k[0]] = k[1]; return result; }, {});
$.ajax({
url: '/logon',
type:'post',
data:JSON.stringify({"username": username,"password": password}),
contentType: "application/json",
dataType: "json",
beforeSend: function(request) {
request.setRequestHeader("X-XSRF-TOKEN",token["XSRF-TOKEN"]);
},
success: function(response){
alert(response)
},
error: function(response){
alert(response)
}
})
})
$("#sub2").click(function(){
var token = document.cookie.split('; ').reduce(function(result, v, i, a) { var k = v.split('='); result[k[0]] = k[1]; return result; }, {});
$.ajax({
url: '/logon2',
type:'post',
beforeSend: function(request) {
request.setRequestHeader("X-XSRF-TOKEN",token["XSRF-TOKEN"]);
},
success: function(response){
alert(response)
},
error: function(response){
alert(response)
}
})
})
})
</script>
</head>
<body>
username: <input type="text" name="username" id="username"></br>
password: <input type="text" name="password" id="password"></br>
<button style="width: 50px;height: 25px" id="sub">submit</button>
<button style="width: 50px;height: 25px" id="sub2">submit2</button>
</body>
</html>
@RestController
public class LogonController {
@Autowired
private ValidateUserLoginInfo validateUserLoginInfo;
@PostMapping("logon")
public String logon(@RequestBody Map<String,String> map, HttpServletRequest request){
String username = map.get("username");
String password = map.get("password");
validateUserLoginInfo.validateUserInfo(username,password,request);
JSONObject json = new JSONObject();
try {
json.put("status","success");
} catch (JSONException e) {
e.printStackTrace();
}
return json.toString();
}
@PostMapping("logon2")
@PreAuthorize("hasRole('test')") //需要test 角色才能登录
public String logon2(){
JSONObject json = new JSONObject();
try {
json.put("status","success");
} catch (JSONException e) {
e.printStackTrace();
}
return json.toString();
}
}
@Service
public class MyUserService implements UserDetailsService {
@Autowired
UserDao userDao;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
User user = userDao.queryByUsername(s);
UserDetails userDetails = null;
if (Optional.ofNullable(user).isPresent()) {
Collection<? extends GrantedAuthority> authoritiesList = user.getAuthorities();
return new org.springframework.security.core.userdetails.User(s, user.getPassword(), true, true, true, true, authoritiesList);
}
return userDetails;
}
}
@Service
public class ValidateUserLoginInfo {
@Autowired
private AuthenticationManager authenticationManager;
public boolean validateUserInfo(String username, String password, HttpServletRequest request){
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username,password);
token.setDetails(new WebAuthenticationDetails(request));
try {
Authentication authentication = this.authenticationManager.authenticate(token);
SecurityContext contextAfterChainExecution = SecurityContextHolder.getContext();
contextAfterChainExecution.setAuthentication(authentication);
//加这句的作用是没有走默认的UsernamePasswordAuthenticationFilter 登录成功的信息不会放到session 中去,导致第二个请求会返回403 需要手动将信息放到session
request.getSession(true).setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY,contextAfterChainExecution);
} catch (AuthenticationException e) {
e.printStackTrace();
}
return false;
}
}
application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=update
- compile

浙公网安备 33010602011771号